让opencv输出人脸检测的得分(置信率)

系统 1639 0

最近项目略多,其中一个需要找出一些和脸比较像但是不是脸的负样本,想用opencv的人脸检测器检测到的错误脸作为这样的负样本。

但是国内(包括国外)居然几乎没有相关的资料如何输出detectMultiScale()的置信率或者说是人脸得分

所以写一篇小小的总结供有相关需求的人参考。

转载需注明: http://www.cnblogs.com/sciencefans/

看了下人脸识别函数的opencv的源码

      \sources\modules\objdetect\src\cascadedetect.cpp
    

 

中detectMultiScale有两个重载,第二个重载在opencv的开发文档里居然只字未提:

      
        void
      
       CascadeClassifier::detectMultiScale( 
      
        const
      
       Mat& image, vector<Rect>&
      
         objects,

                                          vector
      
      <
      
        int
      
      >&
      
         rejectLevels,

                                          vector
      
      <
      
        double
      
      >&
      
         levelWeights,

                                          
      
      
        double
      
       scaleFactor, 
      
        int
      
      
         minNeighbors,

                                          
      
      
        int
      
      
         flags, Size minObjectSize, Size maxObjectSize,

                                          
      
      
        bool
      
       outputRejectLevels )
    

发现他有个rejectLevels和levelWeight这两个引用参数,看名字感觉是一种得分输出。

google了一下发现国外问的人不少但是基本没啥解释(或者是我没认真找?)

然后看了下它调用的cvHaarDetectObjectsForROC()的源码实现,大概懂了这俩vectors是在干什么的。

先上结论:确实和人脸得分有关。

首先应该明白一点detectMultiScale()这个方法是一个级联分类器,使用了boosting的方法。所以输入图像要经过层层(级级)选拔,留到最后的才是真汉子(正样本)

rejectLevels就是代表在第几层被out的。如果是最后一层(在lbpcascade_frontalface.xml中是20,具体要看xml中的叙述)被out,则说明很可能是正样本。

为啥说很可能呢?

因为还有个参数:levelWeight。即使是在最后一层被out的,levelWeight很小甚至是负数,也可以看成是负样本。

实际上很多负样本正是在最后一层被out的。

见下图:

让opencv输出人脸检测的得分(置信率)

我这里只截取了level在20才out的框。输出了他们的levelWeight。是脸的地方最大是4.23多,其他的就很小。不用过多解释了吧~

所以这个函数的原理是这样的(个人理解,有错误请指教):

首先一个level一个level地测试样本,然后每一个level给一个对应的得分,也就是levelWeight,如果这个weight低于或者高于对应level的threshold,则被抛弃。

坚持到最后一个level并且在最后一个level仍然满足threshold的框就是正确的脸(正样本)。

所以,人脸的分应该是这样:level越大,分数越高,在相同的level,levelWeight越大分数越高。

但是实际上真正的人脸都是能坚持到level20(最后一个level)的,所以只比对最后一个level的所有大于1的框的levelWeight进行比对就可以知道脸的得分啦~

这里给出所有level被gg的框的图:

让opencv输出人脸检测的得分(置信率)

最后给出灰常短小精悍的demo的源代码:

      
         1
      
       #include <opencv2\opencv.hpp>


      
         2
      
       #include <iostream>


      
         3
      
       #include <vector>


      
         4
      
       #include <fstream>


      
         5
      
       #include <math.h>


      
         6
      
      
        using
      
      
        namespace
      
      
         std;


      
      
         7
      
      
        using
      
      
        namespace
      
      
         cv;


      
      
         8
      
      
        const
      
      
        string
      
       xmlpath = 
      
        "
      
      
        lbpcascade_frontalface.xml
      
      
        "
      
      
        ;


      
      
         9
      
      
        CascadeClassifier face_cc;


      
      
        10
      
      
        11
      
      
        int
      
       tic = 
      
        0
      
      
        ;


      
      
        12
      
      
        13
      
      
        void
      
      
         detect(Mat img){


      
      
        14
      
           vector<Rect>
      
         faces;


      
      
        15
      
           vector<
      
        int
      
      >
      
         rejLevel;


      
      
        16
      
           vector<
      
        double
      
      >
      
         levelW;


      
      
        17
      
      
            Mat grayimg;


      
      
        18
      
      
            cvtColor(img, grayimg, CV_RGB2GRAY);


      
      
        19
      
      
            equalizeHist(grayimg, grayimg);


      
      
        20
      
      
        int
      
       minl =
      
         min(img.rows, img.cols);


      
      
        21
      
           face_cc.detectMultiScale(grayimg, faces, rejLevel, levelW, 
      
        1.1
      
      , 
      
        3
      
      , 
      
        0
      
      , Size(), Size(), 
      
        true
      
      
        );


      
      
        22
      
      
        //
      
      
        face_cc.detectMultiScale(grayimg, faces, 1.1);
      
      
        23
      
      
        for
      
       ( 
      
        int
      
       i = 
      
        0
      
      ; i < faces.size(); i++
      
         )


      
      
        24
      
      
            {


      
      
        25
      
      
        if
      
       ( rejLevel[i] < 
      
        00
      
      
         )


      
      
        26
      
      
                {


      
      
        27
      
      
        continue
      
      
        ;


      
      
        28
      
      
                }


      
      
        29
      
      
                stringstream text1, text2;


      
      
        30
      
               text1 << 
      
        "
      
      
        rejLevel:
      
      
        "
      
       <<
      
         rejLevel[ i ];


      
      
        31
      
               text2 << 
      
        "
      
      
        levelW:
      
      
        "
      
       <<
      
         levelW[ i ];


      
      
        32
      
      
        string
      
       ttt =
      
         text1.str();


      
      
        33
      
               rectangle(img, faces[ i ], Scalar(
      
        255
      
      , 
      
        255
      
      , 
      
        0
      
      ), 
      
        2
      
      , 
      
        8
      
      , 
      
        0
      
      
        );


      
      
        34
      
               putText(img, ttt, cvPoint(faces[ i ].x, faces[ i ].y - 
      
        3
      
      ), 
      
        1
      
      , 
      
        1
      
      , Scalar(
      
        0
      
      ,
      
        255
      
      ,
      
        255
      
      
        ));


      
      
        35
      
               ttt =
      
         text2.str();


      
      
        36
      
               putText(img, ttt, cvPoint(faces[ i ].x, faces[ i ].y + 
      
        12
      
      ), 
      
        1
      
      , 
      
        1
      
      , Scalar(
      
        255
      
      , 
      
        0
      
      , 
      
        255
      
      
        ));


      
      
        37
      
      
            }


      
      
        38
      
           imshow(
      
        "
      
      
        IMG
      
      
        "
      
      
        , img);


      
      
        39
      
           waitKey(
      
        0
      
      
        );


      
      
        40
      
      
        }


      
      
        41
      
      
        42
      
      
        int
      
      
         main(){


      
      
        43
      
      
        if
      
       ( !
      
        face_cc.load(xmlpath) )


      
      
        44
      
      
            {


      
      
        45
      
               cout << 
      
        "
      
      
        load error!\n
      
      
        "
      
      
        ;


      
      
        46
      
      
        return
      
       -
      
        1
      
      
        ;


      
      
        47
      
      
            }


      
      
        48
      
      
            ifstream pathin;


      
      
        49
      
           pathin.open(
      
        "
      
      
        imgpath.txt
      
      
        "
      
      
        );


      
      
        50
      
      
        string
      
      
         t;


      
      
        51
      
      
        while
      
       ( pathin >> t && tic < 
      
        10000
      
      
        )


      
      
        52
      
      
            {


      
      
        53
      
               Mat img =
      
         imread(t);


      
      
        54
      
      
                detect(img);


      
      
        55
      
      
            }


      
      
        56
      
      
            pathin.close();


      
      
        57
      
      
        return
      
      
        0
      
      
        ;


      
      
        58
      
       }
    

 

让opencv输出人脸检测的得分(置信率)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论