新建MFC工程项目
设计图形界面
图形界面
打开/关闭摄像头
打开摄像头
void CFaceSigninDlg::OnBnClickedOpenvedio()
{
m_flag = 1;
CRect rect;
CWnd *pWnd = GetDlgItem(LeftPicture); //获取左侧图片控件
pWnd->GetClientRect(&rect);
int x = rect.Width();
int y = rect.Height();
//避免连续打开两次
m_capture.release();
//初始化摄像头
m_capture = VideoCapture(0);
//若无法打开摄像头
if (!m_capture.isOpened()) {
fprintf(stderr, "Can not open camera.\n");
return;
}
while (m_flag) {
Mat frame;
m_capture >> frame; // >>操作符:读取下一帧
resize(frame, m_dst, Size(x, y), 0, 0, 1);
imshow("view", m_dst);
waitKey(25);
}
}
关闭摄像头
void CFaceSigninDlg::OnBnClickedVedioclose()
{
m_flag = 0;
}
获取opencv窗口,并将其父窗口设置为图形控件
//视频预览窗口
namedWindow("view", WINDOW_AUTOSIZE);
HWND hWnd = (HWND)cvGetWindowHandle("view");
HWND hParent = ::GetParent(hWnd);
::SetParent(hWnd, GetDlgItem(LeftPicture)->m_hWnd);
::ShowWindow(hParent, SW_HIDE);
抓拍人脸
void CFaceSigninDlg::OnBnClickedGetimage()
{
//保存某一帧图片
String picpath = "F:\Homeworks\Python_xiaoxueqi\FaceSignin\FaceSignin\FaceSignin\faces";
imwrite(picpath, m_dst);
//读取图片
Mat image = imread(picpath);
Mat imagedst;
CWnd *pWnd = GetDlgItem(RightPicture); //获取右边图片控件
CDC *pDC = NULL;
CString strPath;
//设置静态控件样式,使其可以现实位图,并设置居中
((CStatic*)GetDlgItem(RightPicture)->ModifyStyle(0xF, SS_BITMAP | SS_CENTERIMAGE));
pDC = GetDlgItem(RightPicture)->GetDC();
ShowImage(pDC, picpath, 0, 0);
ReleaseDC(pDC);
}
//显示图片
BOOL CFaceSigninDlg::ShowImage(CDC* pDC, String strPath, int x, int y)
{
IPicture *pPic = NULL;
OleLoadPicturePath(CComBSTR(strPath.c_str()), (LPUNKNOWN)NULL, 0, 0, IID_IPicture, (LPVOID*)&pPic);
if (NULL == pPic)
{
return FALSE;
}
// 宽度+高度
OLE_XSIZE_HIMETRIC hmWidth;
OLE_YSIZE_HIMETRIC hmHeight;
pPic->get_Width(&hmWidth);
pPic->get_Height(&hmHeight);
//宽度和高度
RECT rtWnd;
pDC->GetWindow()->GetWindowRect(&rtWnd);
int iWndWidth = rtWnd.right - rtWnd.left;
int iWndHeight = rtWnd.bottom - rtWnd.top;
if (FAILED(pPic->Render(*pDC, x, y, iWndWidth, iWndHeight, 0, hmHeight, hmWidth, -hmHeight, NULL)))
{
pPic->Release();
return false;
}
//释放资源
pPic->Release();
return true;
}
人脸检测
//人脸检测
std::vector<dlib::rectangle> faces = detector(cimg); //预测人脸
std::vector<full_object_detection> shapes; //此对象表示图像中对象的位置及其每个组成部分的位置。
for (unsigned long i = 0; i < faces.size(); ++i) { //每一个人脸
cv::rectangle(frame, Rect(faces[i].left(), faces[i].top(), faces[i].width(), faces[i].height()), Scalar(0, 0, 255), 1, 1, 0);//绘制方框
shapes.push_back(pose_model(cimg, faces[i]));//将人脸加入shape
}
//特征点标定
if (!shapes.empty()) {
//绘制特征点
for (int i = 0; i < 68; i++) {
cv::circle(frame, cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), 3, cv::Scalar(0, 0, 255), -1);
//显示特征点的数字
putText(frame, to_string(i), cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), CV_FONT_HERSHEY_PLAIN, 1, cv::Scalar(255, 0, 0), 1, 4);
}
//眨眼检测
//左边两点
int y37 = shapes[0].part(37).y();
int y38 = shapes[0].part(38).y();
//右边两点
int y40 = shapes[0].part(40).y();
int y41 = shapes[0].part(41).y();
//中间两点
int x36 = shapes[0].part(36).x();
int x39 = shapes[0].part(39).x();
int y1 = abs(y37 - y41);
int y2 = abs(y38 - y40);
int x1 = abs(x39 - x36);
//长宽比
float flg = (y1 + y2) / (2.0 * x1);
//显示
//CString str;
//str.Format(_T("EAR:%.2s"), flg);
//m_regResult.SetWindowText(str);
//张嘴检测
int y50 = shapes[0].part(50).y();
int y52 = shapes[0].part(52).y();
int y56 = shapes[0].part(56).y();
int y58 = shapes[0].part(58).y();
int x48 = shapes[0].part(48).x();
int x54 = shapes[0].part(54).x();
int my1 = abs(y50 - y58);
int my2 = abs(y52 - y56);
int mx1 = abs(x48 - x54);
//长宽比
float flgMouse = (my1 + my2) / (2.0 * mx1);
}