在上一节,我们实现了桌面捕获功能,并成功把桌面图像和麦克风声音发送给对方。在实际应用中,有时候会需要把桌面与摄像头图像叠加在一起发送,这节课我们就来看下如何实现这一功能。
1.备份与修改
备份demo10并修改demo10为demo11.
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.调试运行
效果如下: