第12课 实现桌面与摄像头叠加

在上一节,我们实现了桌面捕获功能,并成功把桌面图像和麦克风声音发送给对方。在实际应用中,有时候会需要把桌面与摄像头图像叠加在一起发送,这节课我们就来看下如何实现这一功能。

1.备份与修改

备份demo11并修改demo11为demo12.

2.用新队列存放叠加前的图像数据

修改原函数capCam和capScr,用新的inCamQue和inScrQue存放摄像头和桌面图像Mat:

cpp 复制代码
int fmle::capCam() {

	videoCap.open(0);
	cv::Mat camMat;
	while (true)
	{

		if (!videoCap.isOpened()){
			Sleep(1);
			continue;
		}

		BOOL ifSuccess = videoCap.read(camMat);

		if (camMat.empty())
		{
			Sleep(1);
			continue;
		}
		if (camMat.cols != backWidth || camMat.rows != backHeight){
			resize(camMat, camMat, cv::Size(backWidth, backHeight));
		}
		if (!camMat.empty()){			
			EnterCriticalSection(&videoQueLock);
			tmpVideoQueObj.type = 1;
			tmpVideoQueObj.tmpMat = camMat;
			tmpVideoQueObj.dataLen = camMat.cols*camMat.rows * 3;
			inCamQue.push(tmpVideoQueObj);
			if (inCamQue.size() >videoDataArrNum){
				inCamQue.front().dataLen = 0;
				inCamQue.front().tmpMat.release();
				inCamQue.front().dataLen = NULL;
				inCamQue.pop();
			}
			LeaveCriticalSection(&videoQueLock);


		}
		Sleep(40);
	}
	camMat.release();

	return 0;
}

int fmle::capScr(){
    
    HWND hwnd = GetDesktopWindow();
    cv::Mat scrMat;
    while (true)
    {
        scrMat = hwndToMat(hwnd);        
        if (scrMat.cols != backWidth || scrMat.rows != backHeight){
            resize(scrMat, scrMat, cv::Size(backWidth, backHeight));
        }

        if (scrMat.data&&!scrMat.empty()){        
            cvtColor(scrMat, scrMat, CV_BGRA2BGR);
            //mainDlg->drawMatOfPub(scrMat);
            EnterCriticalSection(&videoQueLock);
            tmpVideoQueObj.type = 1;
            tmpVideoQueObj.tmpMat = scrMat;
            tmpVideoQueObj.dataLen = scrMat.cols*scrMat.rows * 3;
            inScrQue.push(tmpVideoQueObj);
            if (inScrQue.size() >videoDataArrNum){
                inScrQue.front().dataLen = 0;
                inScrQue.front().tmpMat.release();
                inScrQue.front().dataLen = NULL;
                inScrQue.pop();
            }
            LeaveCriticalSection(&videoQueLock);

        }
        Sleep(40);
    }

    scrMat.release();    
    return 0;
}

3.分别从桌面和摄像头队列取数据并叠加

新建一线程,调用mixVideo实现桌面和摄像头图像的叠加

cpp 复制代码
int fmle::mixVideo(){

    cv::Mat camMat, scrMat, imageROI;
    while (true){
        if (inScrQue.size() > 0 && inCamQue.size() > 0){
            EnterCriticalSection(&videoQueLock);
            camMat = inCamQue.front().tmpMat.clone();
            resize(camMat, camMat, cv::Size(120, 80));
            scrMat = inScrQue.front().tmpMat.clone();
            if (!camMat.empty() && !scrMat.empty()){
                imageROI = scrMat(cv::Rect(0, 0, camMat.cols, camMat.rows));
                addWeighted(imageROI, 0, camMat, 1, 0.0, imageROI);
                mainDlg->drawMatOfPub(scrMat);
            }
            camMat.release();
            scrMat.release();
            imageROI.release();
            LeaveCriticalSection(&videoQueLock);
        }
        Sleep(40);
    }
    return 0;
}

4.调试运行

效果如下:

相关推荐
Liu628881 小时前
C++中的工厂模式高级应用
开发语言·c++·算法
AI科技星2 小时前
全尺度角速度统一:基于 v ≡ c 的纯推导与验证
c语言·开发语言·人工智能·opencv·算法·机器学习·数据挖掘
条tiao条2 小时前
KMP 算法详解:告别暴力匹配,让字符串匹配 “永不回头”
开发语言·算法
干啥啥不行,秃头第一名2 小时前
C++20概念(Concepts)入门指南
开发语言·c++·算法
zzh940773 小时前
Gemini 3.1 Pro 硬核推理优化剖析:思维织锦、动态计算与国内实测
算法
2301_807367193 小时前
C++中的解释器模式变体
开发语言·c++·算法
愣头不青3 小时前
617.合并二叉树
java·算法
MIUMIUKK4 小时前
双指针三大例题
算法
灵感__idea4 小时前
Hello 算法:复杂问题的应对策略
前端·javascript·算法
2301_819414305 小时前
C++与区块链智能合约
开发语言·c++·算法