📄 facedemodlg.cpp
字号:
int i;
//最多只支持4路人脸检测
memset(fdParam,0,sizeof(FACEDETECTPARAM) * 4);
memset(bpInfo,0,sizeof(BMP) * 12);
//这个Demo版本SDK返回的是2CIF分辨率,因此每路的最大图像是704*288(PAL制式,NTSC时是704*240)
m_pBuff = (char *) malloc(704 * 288 * 3 / 2 * 12/*20*/ + 64);
ASSERT(m_pBuff);
//缓冲对齐
p = (char *)((int)(m_pBuff + 64) & 0xffffffe0);
for(i=0;i<12;i++)
{
bpInfo[i].pBmpBuff.y = (unsigned char *)p;
bpInfo[i].pBmpBuff.u = (unsigned char *)(p + 704 * 288);
bpInfo[i].pBmpBuff.v = (unsigned char *)(p + 704 * 288 * 5 / 4);
p += 704 * 288 * 3 / 2;
}
g_cfHwnd = this->GetSafeHwnd();
m_csTime[0]=&m_csTime0;
m_csTime[1]=&m_csTime1;
m_csTime[2]=&m_csTime2;
m_csTime[3]=&m_csTime3;
m_csTime[4]=&m_csTime4;
m_csTime[5]=&m_csTime5;
m_csTime[6]=&m_csTime6;
m_csTime[7]=&m_csTime7;
m_csTime[8]=&m_csTime8;
m_csTime[9]=&m_csTime9;
m_csTime[10]=&m_csTime10;
m_csTime[11]=&m_csTime11;
m_csChan[0] = &m_csChan1;
m_csChan[1] = &m_csChan2;
m_csChan[2] = &m_csChan3;
m_csChan[3] = &m_csChan4;
m_csChan[4] = &m_csChan5;
m_csChan[5] = &m_csChan6;
m_csChan[6] = &m_csChan7;
m_csChan[7] = &m_csChan8;
m_csChan[8] = &m_csChan9;
m_csChan[9] = &m_csChan10;
m_csChan[10] = &m_csChan11;
m_csChan[11] = &m_csChan12;
m_edChan[0] = &m_edChan1;
m_edChan[1] = &m_edChan2;
m_edChan[2] = &m_edChan3;
m_edChan[3] = &m_edChan4;
m_edChan[4] = &m_edChan5;
m_edChan[5] = &m_edChan6;
m_edChan[6] = &m_edChan7;
m_edChan[7] = &m_edChan8;
m_edChan[8] = &m_edChan9;
m_edChan[9] = &m_edChan10;
m_edChan[10] = &m_edChan11;
m_edChan[11] = &m_edChan12;
m_edTime[0] = &m_edTime0;
m_edTime[1] = &m_edTime1;
m_edTime[2] = &m_edTime2;
m_edTime[3] = &m_edTime3;
m_edTime[4] = &m_edTime4;
m_edTime[5] = &m_edTime5;
m_edTime[6] = &m_edTime6;
m_edTime[7] = &m_edTime7;
m_edTime[8] = &m_edTime8;
m_edTime[9] = &m_edTime9;
m_edTime[10] = &m_edTime10;
m_edTime[11] = &m_edTime11;
CString csTemp;
csTemp.Format("camera%02d",m_nChannel + 1);
///////下面初始化预览功能
if(InitDSPs() <= 0)
{
AfxMessageBox("can not init DSPs\n");
exit(-1);
}
GetDlgItem(IDC_PREV_PIC)->GetClientRect(&rect);
m_cmbType.AddString("YUV图像");
m_cmbType.AddString("JPEG图像");
//创建预览窗口集
for(i=0;i<4;i++)
{
m_cvWindow[i].Create(IDD_DIALOG_PREVIEW,this);
m_cvWindow[i].m_iChannel=i;
m_cvWindow[i].m_hChannelHandle=ChannelOpen(i);
}
m_cmbType.SetCurSel(0);
m_cvWindow[0].MoveWindow(0,0,rect.Width()>>1,rect.Height()>>1,TRUE);
m_cvWindow[1].MoveWindow(rect.Width()>>1,0,rect.Width()>>1,rect.Height()>>1,TRUE);
m_cvWindow[2].MoveWindow(0,rect.Height()>>1,rect.Width()>>1,rect.Height()>>1,TRUE);
m_cvWindow[3].MoveWindow(rect.Width()>>1,rect.Height()>>1,rect.Width()>>1,rect.Height()>>1,TRUE);
//如果创建的窗口比较大,可以覆盖整个屏幕,则应该在此启动预览
// UpdateData(FALSE);
GetDlgItem(IDC_FACECAP_CHANNEL)->SetWindowText("camera01");
m_bInited=TRUE;
m_csPath.Format("%sfacepic",g_csPath);
CreateDirectory(m_csPath,NULL);
m_muShowPic = CreateMutex(NULL,FALSE,NULL);
return TRUE; // return TRUE unless you set the focus to a control
}
void CFaceDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
void CFaceDemoDlg::OnPaint()
{
if (IsIconic())
{
// device context for painting
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
RestoreOverlay();//解决ctrl+alt+del后不显示画面的问题
}
HCURSOR CFaceDemoDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//消息处理函数
int CFaceDemoDlg::OnClientMessage(WPARAM wParam, LPARAM lParam)
{
CClientDC dc(this);
for(int i=0;i<12;i++)
{
WaitForSingleObject(m_muShowPic,INFINITE);
if(bpInfo[i].iPic)
{
TRACE("wParam=%d,lParam=%d,i=%d\n",wParam,lParam,i);
m_csTime[i]->Format("%02d%02d %02d:%02d:%02d",bpInfo[i].time.GetMonth(),bpInfo[i].time.GetDay(),bpInfo[i].time.GetHour(),bpInfo[i].time.GetMinute(),bpInfo[i].time.GetSecond());
m_csChan[i]->Format("camera%02d",bpInfo[i].nChannel + 1);
//最新的人脸用不同的字体颜色突出显示
if(i==lParam)
{
m_edTime[i]->FSetTextColor(RGB(0,0,255));
m_edChan[i]->FSetTextColor(RGB(0,0,255));
}else
{
m_edTime[i]->FSetTextColor(RGB(0,0,0));
m_edChan[i]->FSetTextColor(RGB(0,0,0));
}
ShowPicture(&dc, bpInfo[i].iPic,i);
UpdateData(FALSE);
}
ReleaseMutex(m_muShowPic);
}
return 0;
}
void CFaceDemoDlg::OnMove(int x, int y)
{
if(!m_bInited) return;//如果没有完成初始化则不启动视频预览
GetDlgItem(IDC_PREV_PIC)->GetClientRect(&rect);//获得pic控件的矩形区域
RECT rc;
rc.top=rect.top+2;
rc.left=rect.left+2;
rc.bottom=(rect.bottom>>1)-2;
rc.right=(rect.right>>1)-2;
for(int i=0;i<4;i++)
{
StopVideoPreview(m_cvWindow[i].m_hChannelHandle);
m_cvWindow[i].ShowWindow(TRUE);
StartVideoPreview(m_cvWindow[i].m_hChannelHandle, m_cvWindow[i].m_hWnd, &rc, false, vdfYUV422Planar, 25);
m_cvWindow[i].RefreshBack(m_nChannel);//刷新边框
}
}
int CFaceDemoDlg::SetCurrentChan(int ichannel)
{
int i;
if(ichannel>=0)
{
m_nChannel=ichannel;
}
CString csTemp;
csTemp.Format("camera%02d",m_nChannel + 1);
GetDlgItem(IDC_FACECAP_CHANNEL)->SetWindowText(csTemp);
for(i=0;i<4;i++)
{
if(m_cvWindow[i].IsWindowVisible())
{
m_cvWindow[i].RefreshBack(ichannel);
}else
{
break;
}
}
if(fdParam[m_nChannel].bDetectNow)
{
//显示当前通道检测参数
CString csTemp;
m_nFrameInterval = fdParam[m_nChannel].nFrameInterval;
m_bSaveFile = fdParam[m_nChannel].bSaveFile;
m_nJpegQuality = fdParam[m_nChannel].nJpegQuality;
m_cmbType.SetCurSel(fdParam[m_nChannel].nPicType);
UpdateData(FALSE);
GetDlgItem(IDC_START_CAP)->EnableWindow(FALSE);
}else
{
GetDlgItem(IDC_START_CAP)->EnableWindow(TRUE);
}
return 0;
}
void CFaceDemoDlg::OnStartCap()
{
UpdateData(TRUE);
int nType;
int ret;
CString str;
nType = m_cmbType.GetCurSel();
if(nType == 1)
{
if((m_nJpegQuality < 0) || (m_nJpegQuality > 100))
{
AfxMessageBox("JPEG图像质量范围为0-100");
return;
}
}
fdParam[m_nChannel].bSaveFile = m_bSaveFile;
fdParam[m_nChannel].nFrameInterval = m_nFrameInterval;
fdParam[m_nChannel].nPicType = nType;
fdParam[m_nChannel].nJpegQuality = m_nJpegQuality;
ret = SetFaceDetection(m_cvWindow[m_nChannel].m_hChannelHandle,1,m_nFrameInterval,FaceDetectionCallback,fdParam[m_nChannel].nPicType,fdParam[m_nChannel].nJpegQuality);
if(ret)
{
if(ret==ERR_NOT_SUPPORT)
str.Format("该板卡不支持人脸检测功能!");
else
str.Format("Channel %u start FD error:%x",m_nChannel,ret);
AfxMessageBox(str);
return;
}
fdParam[m_nChannel].bDetectNow = TRUE;
GetDlgItem(IDC_START_CAP)->EnableWindow(FALSE);
}
void CFaceDemoDlg::OnStopCap()
{
SetFaceDetection(m_cvWindow[m_nChannel].m_hChannelHandle,0,0,NULL,0,0);
fdParam[m_nChannel].bDetectNow = FALSE;
GetDlgItem(IDC_START_CAP)->EnableWindow(TRUE);
}
void CFaceDemoDlg::OnExit()
{
OnClose();
}
void CFaceDemoDlg::OnClose()
{
int i;
//停止人脸检测
for(i=0;i<4;i++)
{
SetFaceDetection(m_cvWindow[i].m_hChannelHandle,0,0,NULL,0,0);
}
free(m_pBuff);
for(i=0;i<12;i++)
{
if (bpInfo[i].iPic)
{
bpInfo[i].iPic->Release();
}
}
//停止预览
for(i = 0; i < GetTotalDSPs(); i++)
{
StopVideoPreview(m_cvWindow[i].m_hChannelHandle);
}
//关闭通道
for(i= 0 ;i < GetTotalDSPs(); i++)
{
ChannelClose(m_cvWindow[i].m_hChannelHandle);
}
DeInitDSPs();
TRACE("###");
CDialog::OnOK();
}
int CFaceDemoDlg::PreviewDbclk(int ichannel)
{
//双击放大
if(m_cvWindow[ichannel].m_bDbuttonClick)
{
GetDlgItem(IDC_PREV_PIC)->GetClientRect(&rect);//获得pic控件的矩形区域
RECT rc;
rc.top=rect.top;
rc.left=rect.left;
rc.bottom=rect.bottom;
rc.right=rect.right;
// ScreenToClient(&rc);
for(int i=0;i<4;i++)
{
StopVideoPreview(m_cvWindow[i].m_hChannelHandle);
m_cvWindow[i].ShowWindow(FALSE);
}
m_cvWindow[ichannel].MoveWindow(&rc,TRUE);
m_cvWindow[ichannel].ShowWindow(TRUE);
StartVideoPreview(m_cvWindow[ichannel].m_hChannelHandle, m_cvWindow[ichannel].m_hWnd, &rc, false, vdfYUV422Planar, 25);
}
//双击还原
else{
StopVideoPreview(m_cvWindow[ichannel].m_hChannelHandle);
GetDlgItem(IDC_PREV_PIC)->GetClientRect(&rect);//获得pic控件的矩形区域
RECT rc;
rc.top=rect.top+2;
rc.left=rect.left+2;
rc.bottom=(rect.bottom>>1)-2;
rc.right=(rect.right>>1)-2;
m_cvWindow[0].MoveWindow(0,0,rect.Width()>>1,rect.Height()>>1,TRUE);
m_cvWindow[1].MoveWindow(rect.Width()>>1,0,rect.Width()>>1,rect.Height()>>1,TRUE);
m_cvWindow[2].MoveWindow(0,rect.Height()>>1,rect.Width()>>1,rect.Height()>>1,TRUE);
m_cvWindow[3].MoveWindow(rect.Width()>>1,rect.Height()>>1,rect.Width()>>1,rect.Height()>>1,TRUE);
for(int i=0;i<4;i++)
{
// StopVideoPreview(m_cvWindow[i].m_hChannelHandle);
m_cvWindow[i].ShowWindow(TRUE);
StartVideoPreview(m_cvWindow[i].m_hChannelHandle, m_cvWindow[i].m_hWnd, &rc, false, vdfYUV422Planar, 25);
m_cvWindow[i].RefreshBack(ichannel);//刷新边框
}
}
return 0;
}
BOOL CFaceDemoDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message==WM_KEYDOWN)
{
switch (pMsg->wParam)
{
case VK_ESCAPE:
OnClose();
break;
case 0xD:
return TRUE;
default:
break;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
void CFaceDemoDlg::ShowPicture(CDC* pDC, IPicture *pPic,int index)
{
if (pPic==NULL)
{
return;
}
OLE_XSIZE_HIMETRIC hmWidth;//图片的真实宽度
OLE_YSIZE_HIMETRIC hmHeight;//图片的真实高度
pPic->get_Width(&hmWidth);
pPic->get_Height(&hmHeight);
//将图形输出到屏幕上
CRect rect;
GetDlgItem(IDC_PIC_FACE0+index)->GetWindowRect(&rect);
ScreenToClient(&rect);
long tempLeft=rect.left;
long tempTop=rect.top;
CSize szlt = bpInfo[index].sRect.TopLeft();
CSize szrb = bpInfo[index].sRect.BottomRight();
pDC->DPtoHIMETRIC(&szlt);
pDC->DPtoHIMETRIC(&szrb);
pPic->Render(pDC->m_hDC,tempLeft,tempTop,rect.Width(),rect.Height(),
szlt.cx, hmHeight - szlt.cy,szrb.cx - szlt.cx, szlt.cy - szrb.cy, NULL);
TRACE("x=%d,y=%d,w=%d,h=%d\n",szlt.cx, szrb.cy,szrb.cx - szlt.cx, szlt.cy - szrb.cy);
}
void CFaceDemoDlg::OnChangeFaceType(UINT nID)
{
}
void CFaceDemoDlg::OnCancel()
{
}
void CFaceDemoDlg::OnOK()
{
}
void CFaceDemoDlg::OnCheckFile()
{
UpdateData(TRUE);
}
void CFaceDemoDlg::OnStopall()
{
for(int i=0;i<4;i++)
{
SetFaceDetection(m_cvWindow[i].m_hChannelHandle,0,0,NULL,0,0);
fdParam[i].bDetectNow = FALSE;
}
GetDlgItem(IDC_START_CAP)->EnableWindow(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -