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