opencv实现图片与视频中人脸检测功能分享!

本文实例为大家分享了opencv实现人脸检测功能的具体代码,供大家参考,具体内容如下

第一章:反思与总结

上一篇博客我相信自己将人脸检测中的AdaBoost算法解释的非常清晰了,以及如何训练人脸检测的强分类器:人脸检测中AdaBoost算法详解。事后,自我感觉对这个人脸检测还是不够具体,所以自己抽了一下午的时间用opencv实现图片与视频中的人脸检测,下面是我用vs2013加opencv4.9来实现的。做一下声明,我的代码是参考OpenCV实现人脸检测的一个博客写的,非常感谢这位博主,我学到了很多东西,下面是我一下午实践的总结:

第二章:图片中的人脸检测

啥也不说,先上效果图大笑:

opencv实现图片与视频中人脸检测功能

下面是福利图了,图中有志玲姐姐(安静):

opencv实现图片与视频中人脸检测功能

可惜没匹配上,很伤心~~~~

有人可能会问这么漂亮的背景图是这么高的,下面是代码~

  void CmyFaceDetectDlg::OnPaint()   {    if (IsIconic())    {    CPaintDC dc(this); // 用于绘制的设备上下文       SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);       // 使图标在工作区矩形中居中    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;       // 绘制图标    dc.DrawIcon(x, y, m_hIcon);    }    else    {    /*改变对话框背景****若需要默认背景,可以删除*/    CPaintDC dc(this);    CRect rect;    GetClientRect(&rect);    CDC dcBmp;    dcBmp.CreateCompatibleDC(&dc);    CBitmap bmpBackGround;    bmpBackGround.LoadBitmap(<span >IDB_BEIJING</span>);//IDB_BEIJING是背景的图片ID,在资源视图中插入资源,选择BITMAP   
  BITMAP m_bitmap; //上传图片(BMP)格式,将ID设为一致就好了   bmpBackGround.GetBitmap(&m_bitmap);   CBitmap *pbmpOld = dcBmp.SelectObject(&bmpBackGround);   dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcBmp, 0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight, SRCCOPY);   CDialogEx::OnPaint();   }}  

好了,下面进入正题,如何实现图片中的人脸匹配,见代码,后面有详细解释:

  void CmyFaceDetectDlg::OnBnClickedFacedetect()   {    // TODO: 在此添加控件通知处理程序代码    CString filename;    //打开对话框    CFileDialog OpenDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR,    _T("图片 (*.jpg)|*.jpg|(*.*) |*.*|"), NULL);    if (OpenDlg.DoModal() != IDOK)    {    return;    }    filename = OpenDlg.GetPathName();//获得文件路径    /*CString转换*string*/    USES_CONVERSION;//USES_CONVERSION是用来转换类型的    //USES_CONVERSION它是在堆栈上分配空间的,也就是说你在你在函数未结束就不会被释放掉。所有要注意不要在一个函数中用while循环执行它,不然栈空间就马上会分配完(栈空间一般只有2M,很小)    std::string tempName(W2A(filename));//转换过程    image = imread(tempName);//读取图片    const String cascade_name = "./haarcascade_frontalface_alt2.xml";//加载人脸库    if (!cascade.load(cascade_name))    {    MessageBox(_T("ERROR:Could not load cascade!"));    return;    }    if (!image.data)    {    MessageBox(_T("ERROR:Could not load image!"));    return;    }    namedWindow("人脸检测", CV_WINDOW_AUTOSIZE);    detectAndDraw(image, cascade, scale);//调用人脸检测函数    imshow("人脸检测", image);    return;   }      void CmyFaceDetectDlg::detectAndDraw(Mat& img, CascadeClassifier& cascade, double scale)   {    /*程序核心函数,检测标记人脸*/    int i = 0;    vector<Rect>faces;//定义一个容器,保存检测结果    const static Scalar colors[] = {    CV_RGB(0, 0, 255),    CV_RGB(0, 128, 255),    CV_RGB(0, 255, 255),    CV_RGB(0, 255, 0),    CV_RGB(255, 128, 0),    CV_RGB(255, 255, 0),    CV_RGB(255, 0, 0),    CV_RGB(255, 0, 255)    };    Mat gray, smallImage(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);//用cvRound取整    cvtColor(img, gray, CV_BGR2GRAY);//转化灰度图    resize(gray, smallImage, smallImage.size(), 0, 0, INTER_LINEAR);//图片尺度调整,将gray调整为smallImage.size大小,方法为INTER_LINEAR:局部像素的重采样    equalizeHist(smallImage, smallImage);//直方图均衡    cascade.detectMultiScale(smallImage, faces);//核心,检测人脸    //const_iterator迭代器,是不能改变r所指向的元素的值的    for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++)    {    //利用迭代器,标记出人脸位置。    Point center;    Scalar color = colors[i % 8];    int radius;    /*计算出原图像中的圆心和半径。公式很简单,自己写一下,就可以理解了*/    center.x = cvRound((r->x + r->width*0.5)*scale);    center.y = cvRound((r->y + r->height*0.5)*scale);    radius = cvRound((r->width + r->height)*0.25*scale);    circle(img, center, radius, color, 2);    }   } 

注意我是在一个MFC的对话框中,这个界面图中按下“图片”button后的操作。

第三章:视频中的人脸检测

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/482139.html

(0)
上一篇 2020年11月9日
下一篇 2020年11月9日

精彩推荐