基于detectMultiScale函数多尺度人脸检测确定目标尺寸

基于detectMultiScale函数多尺度人脸检测确定目标尺寸


功能介绍

由于工作项目需求,需要我结合公司实际项目确定detectMultiScale函数中目标检测对象的最大尺寸和最小尺寸,从而达到加快检测速度、过滤噪点目标的目的。

实现步骤

1.detectMultiScale函数介绍

 打开opencv源码,具体位置在opencv-3.2.0/modules/objdetect/src/cascadedetect.hpp 。 查看源代码可发现detectMultiscale函数有三种:
     void detectMultiScale( InputArray image,
                      CV_OUT std::vector<Rect>& objects,
                      double scaleFactor = 1.1,
                      int minNeighbors = 3, int flags = 0,
                      Size minSize = Size(),
                      Size maxSize = Size() );

void detectMultiScale( InputArray image,
                      CV_OUT std::vector<Rect>& objects,
                      CV_OUT std::vector<int>& numDetections,
                      double scaleFactor=1.1,
                      int minNeighbors=3, int flags=0,
                      Size minSize=Size(),
                      Size maxSize=Size() );

void detectMultiScale( InputArray image,
                      CV_OUT std::vector<Rect>& objects,
                      CV_OUT std::vector<int>& rejectLevels,
                      CV_OUT std::vector<double>& levelWeights,
                      double scaleFactor = 1.1,
                      int minNeighbors = 3, int flags = 0,
                      Size minSize = Size(),
                      Size maxSize = Size(),
                      bool outputRejectLevels = false );

参数介绍:
参数1:image–待检测图片,一般为灰度图像加快检测速度;
参数2:objects–被检测物体的矩形框向量组;为输出量,如人脸检测矩阵Mat
参数3:scaleFactor–表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;一般设置为1.1
参数4:minNeighbors–表示构成检测目标的相邻矩形的最小个数(默认为3个)。
如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。
如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框,
这种设定值一般用在用户自定义对检测结果的组合程序上;
参数5:flags–要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域,因此这些区域通常不会是人脸所在区域;
参数6、7:minSize和maxSize用来限制得到的目标区域的范围。也就是我本次训练得到实际项目尺寸大小
函数介绍:
detectMultiscale函数为多尺度多目标检测:
多尺度:通常搜索目标的模板尺寸大小是固定的,但是不同图片大小不同,所以目标对象的大小也是不定的,所以多尺度即不断缩放图片大小(缩放到与模板匹配),通过模板滑动窗函数搜索匹配;同一副图片可能在不同尺度下都得到匹配值,所以多尺度检测函数detectMultiscale是多尺度合并的结果。
多目标:通过检测符合模板匹配对象,可得到多个目标,均输出到objects向量里面。

2.代码思路

(1)导入opencv自带人脸分类器lbpcascade_frontalface.xml和人眼分类器haarcascade_eye_tree_eyeglasses.xml
(2)读取本地文件夹所有avi视频,参考我的另一篇博客c++读取文件夹文件名
(3)调用detectMultiscale函数,同时检测到人脸和人眼时确定为人脸目标存在,然后输出目标尺寸到vector里,然后排序,输出每个视频中的人脸尺寸最大值和最小值到本地txt文件。
(4)通过得到的尺寸极值确定目标【人脸】的范围

代码块

void detectAndDisplay( Mat frame )
{
    std::vector<Rect> faces;
    Mat frame_gray;
    cvtColor( frame, frame_gray, COLOR_BGR2GRAY );
    equalizeHist( frame_gray, frame_gray );

    //-- Detect faces
    face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0, Size(80, 80) );
    cout << faces.size();
    //if(face.size()=)
    for( size_t i = 0; i < faces.size(); i++ )
    {
        cout << faces[i].size() << endl;
        Mat faceROI = frame_gray( faces[i] );
        std::vector<Rect> eyes;
        eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CASCADE_SCALE_IMAGE, Size(30, 30) );
        if( eyes.size() == 2)
        {
            cout << "faces[i].width: "<< faces[i].width << "  faces[i].height:" <<faces[i].height << "faces[i].size:" << faces[i].size() << " faces[i]:" <<faces[i] << endl;/////////////////////////////////////////////////////////////
            Facesize.push_back(faces[i].width);
            Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
            ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2 ), 0, 0, 360, Scalar( 255, 0, 0 ), 2, 8, 0 );
            for( size_t j = 0; j < eyes.size(); j++ )
            { //-- Draw the eyes
                Point eye_center( faces[i].x + eyes[j].x + eyes[j].width/2, faces[i].y + eyes[j].y + eyes[j].height/2 );
                int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
                circle( frame, eye_center, radius, Scalar( 255, 0, 255 ), 3, 8, 0 );
            }
        }
    }
    imshow( window_name, frame );
}

备注

转载需注明


猜你喜欢

转载自blog.csdn.net/yanrong1095/article/details/78685390
今日推荐