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

2024-01-08 14:38:17

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

1.备份与修改

备份demo11并修改demo11为demo12.

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

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


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实现桌面和摄像头图像的叠加

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.调试运行

效果如下:

文章来源:https://blog.csdn.net/XiBuQiuChong/article/details/135398226
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。