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