OpenCV开发笔记(五十四):红胖子8分钟带你深入了解Haar级联分类器进行人脸检测(图文并茂+浅显易懂+程序源码)

若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106057214
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究

红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)

OpenCV开发专栏(点击传送门)

上一篇:《OpenCV开发笔记(五十三):红胖子8分钟带你深入了解模板匹配识别(图文并茂+浅显易懂+程序源码)》

下一篇:《OpenCV开发笔记(五十五):红胖子8分钟带你深入了解Haar、LBP特征以及级联分类器识别过程(图文并茂+浅显易懂+程序源码)》

 

前言

      红胖子来也!!!

      上一篇使用了模板匹配去识别人脸,本篇章使用OpenCV提供的级联分类器进行人脸识别。

 

Demo

 

人脸识别技术

人脸识别技术有两大类:

基于几何特征的人脸检测

使用人脸组合的几何特征的方式识别人脸,人脸的几何特征:眼睛、眉毛、鼻子、脸颊、额头、嘴巴、下巴等等;

基于统计特征的人脸检测

使用模式识别的方法实现特性人脸的训练,在进行相似度判断,如神经网络等分类方法。

 

Haar级联分类器

概述

Haar级联分类器就是基于Haar特征的级联分类器,涉及到两个概念:一个是Haar特征,一个是级联分类器。

Haar特征

本篇章Demo是基于Haar特征的,使用了openCV自带的Haar分类器初始化文件。

(关于具体的将会在后续的文章中解说)

级联分类器

级联分类器类的检测框架简而言之就是一个多尺度缩放+滑动窗口遍历搜索的框架。

    级联分类器试讲若干个分类器进行连接,从而构成一种多项式的强分类方法,单个分类器可以由若干个弱分类器加权组成。

      (关于具体的将会在后续的文章中解说)

 

OpenCV基于级联分类器的人脸识别

级联分类器类CascadeClassifier

OpenCV提供了CascadeClassifier用于检测物体的级联分类器,其使用过程是先需要读取加载一个文件读取分类器。

bool CascadeClassifier::load( const String& filename );
  • 参数一:String类型的filename,读取级联分类器初始化文件;

然后使用人脸检测函数,进行人脸检测。

级联分类器检测人脸函数原型

(注意:有三个重载函数)

void CascadeClassifier::detectMultiScale( InputArray image,
                                          std::vector& objects,
                                          double scaleFactor = 1.1,
                                          int minNeighbors = 3,
                                          int flags = 0,
                                          Size minSize = Size(),
                                          Size maxSize = Size());
  • 参数一:InputArray类型的image,包含检测到对象的图像的CV_8U类型的图像矩阵,即Mat;
  • 参数二:std::vector类型的objects,矩形的对象向量,其中每个矩形包含检测到的对象矩形可能部分位于原始图像之外,即人脸区域矩形;
  • 参数三:double类型的scaleFactor,指定在每个图像比例下图像大小减小的程度;
  • 参数四:int类型的minNeighbors,匹配成功所需要的周围矩形框的数目(由于调整滑动窗口的大小和很多误报),每一个特征匹配到的区域都是一个矩形框,只有多个矩形框同时存在的时候,才认为是匹配成功,比如人脸,这个默认值是3;
  • 参数五:int类型的flags,标记与函数中的旧级联具有相同含义的参cvHaarDetectObjects,它不用于新的级联,类型参照:

OpenCV开发笔记(五十四):红胖子8分钟带你深入了解Haar级联分类器进行人脸检测(图文并茂+浅显易懂+程序源码)_第1张图片

  • 参数六:Size类型的fminSize,最小可能的对象大小。小于该值的对象将被忽略;
  • 参数七:Size类型的maxSize,最大可能对象大小。大于该值的对象将被忽略。如果“maxSize==minSize”模型是按单个比例计算的;

 

openCV级联分类器初始化文件

OpenCV开发笔记(五十四):红胖子8分钟带你深入了解Haar级联分类器进行人脸检测(图文并茂+浅显易懂+程序源码)_第2张图片

 

Demo涉及其他相关技术

OpenCV操作视频,请查看博文:《OpenCV开发笔记(四):OpenCV图片和视频数据的读取与存储》

OpenCV绘制图形,请查看博文:《OpenCV开发笔记(七):OpenCV基础图形绘制》

 

Demo源码

void OpenCVManager::testCascadeClassifier()
{
    cv::String windowName = _windowTitle.toStdString();
    cvui::init(windowName);

    cv::Mat windowMat = cv::Mat(cv::Size(520, 400),
                                CV_8UC3);

    cv::VideoCapture videoCapture;
    videoCapture.open("E:/testFile/4.avi");
//    videoCapture.open("E:/testFile/4.mp4");

    cv::Mat mat;
    cv::Mat dstMat;
    int currentIndex = 0;

    // 级联人脸分类器
    cv::CascadeClassifier cascadeClassifier;
    cascadeClassifier.load("E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/data/haarcascades/haarcascade_frontalface_alt.xml");
    while(true)
    {
        // 刷新全图黑色
        windowMat = cv::Scalar(0, 0, 0);
        currentIndex = videoCapture.get(cv::CAP_PROP_POS_FRAMES);
        videoCapture >> mat;
        if(!mat.empty())
        {
            dstMat = mat.clone();;

            // 灰度变换
            cv::Mat grayMat;
            cv::cvtColor(dstMat, grayMat, CV_BGR2GRAY);
            // 直方图均衡化
            cv::Mat histMat;
            cv::equalizeHist(grayMat, histMat);
            // 多尺度人脸检测
            std::vector faces;
            cascadeClassifier.detectMultiScale(histMat,
                                               faces,
                                               1.1,
                                               3,
                                               0 | cv::CASCADE_SCALE_IMAGE,
                                               cv::Size(10, 10));
            qDebug() << __FILE__ << __LINE__ << "faces number:" << faces.size();
            // 人脸检测结果判定
            for(int index = 0; index < faces.size(); index++)
            {
                // 检测到人脸
                cv::rectangle(dstMat, faces.at(index), cv::Scalar(0, 0, 255));
            }

            // 视频复制
            mat = windowMat(cv::Range(0, 0 + dstMat.rows),
                            cv::Range(0, 0 + dstMat.cols));
            cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat);
        }
        // 更新
        cvui::update();
        // 显示
        cv::imshow(windowName, windowMat);
        // esc键退出
        int key = cv::waitKey(0);
        switch (key) {
        case 97:        // 'a' 往前一帧
            currentIndex--;
            if(currentIndex < 0)
            {
                currentIndex = 0;
            }
            videoCapture.set(cv::CAP_PROP_POS_FRAMES, currentIndex);
            break;
        case 115:       // ‘s’ 往后一帧
            break;
        default:
            break;
        }
        if(key == 27)
        {
            break;
        }
    }
}

 

工程模板:对应版本号v1.49.0

      对应版本号v1.49.0

 

上一篇:《OpenCV开发笔记(五十三):红胖子8分钟带你深入了解模板匹配识别(图文并茂+浅显易懂+程序源码)》

下一篇:《OpenCV开发笔记(五十五):红胖子8分钟带你深入了解Haar、LBP特征以及级联分类器识别过程(图文并茂+浅显易懂+程序源码)》

 

原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106057214

你可能感兴趣的:(#,OpenCV)