人脸识别实战笔记——程序设计

新建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);
        }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 单纯美好的我们 直到悬河千言汇入那句——“遇见你是我的壮举”是否成为“爱你是我的壮举” 01 想必你的青春里也有过...
    安筱淼阅读 322评论 0 1
  • 连续几天,除了疫苗,屏幕被教育界、新闻界、公益圈等各色知名人士性骚扰和强奸女性的新闻报导,搅得社会惶惶不安。 有人...
    高浩容阅读 2,501评论 12 18
  • 记得你开心时 守红 今天的风,吹不去昨夜的霾地球突然变得好沉重太阳想要吸引它,也变得好难,好难 那对在门口恋爱的小...
    孙守红阅读 134评论 0 1
  • 由于空气等环境的污染,小儿哮喘发病越来越多,给许多父母、家庭来烦恼。 孩子一发病,急得家长们团团转,抱...
    中医张阅读 834评论 2 3