最近项目略多,其中一个需要找出一些和脸比较像但是不是脸的负样本,想用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的。

见下图:

我这里只截取了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的框的图:

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

 #include <opencv2\opencv.hpp>
#include <iostream>
#include <vector>
#include <fstream>
#include <math.h>
using namespace std;
using namespace cv;
const string xmlpath = "lbpcascade_frontalface.xml";
CascadeClassifier face_cc; int tic = ; void detect(Mat img){
vector<Rect> faces;
vector<int> rejLevel;
vector<double> levelW;
Mat grayimg;
cvtColor(img, grayimg, CV_RGB2GRAY);
equalizeHist(grayimg, grayimg);
int minl = min(img.rows, img.cols);
face_cc.detectMultiScale(grayimg, faces, rejLevel, levelW, 1.1, , , Size(), Size(), true);
//face_cc.detectMultiScale(grayimg, faces, 1.1);
for ( int i = ; i < faces.size(); i++ )
{
if ( rejLevel[i] < )
{
continue;
}
stringstream text1, text2;
text1 << "rejLevel:" << rejLevel[ i ];
text2 << "levelW:" << levelW[ i ];
string ttt = text1.str();
rectangle(img, faces[ i ], Scalar(, , ), , , );
putText(img, ttt, cvPoint(faces[ i ].x, faces[ i ].y - ), , , Scalar(,,));
ttt = text2.str();
putText(img, ttt, cvPoint(faces[ i ].x, faces[ i ].y + ), , , Scalar(, , ));
}
imshow("IMG", img);
waitKey();
} int main(){
if ( !face_cc.load(xmlpath) )
{
cout << "load error!\n";
return -;
}
ifstream pathin;
pathin.open("imgpath.txt");
string t;
while ( pathin >> t && tic < )
{
Mat img = imread(t);
detect(img);
}
pathin.close();
return ;
}

最新文章

  1. 关于如何显示Jianshu图片的方案
  2. python 优矿自动化交易
  3. 《javascript面向对象精要》读书笔记
  4. Linux LVM学习总结&mdash;&mdash;放大LV容量
  5. ubuntu下crontab编辑方法的设定
  6. [ASE][Daily Scrum]11.24
  7. 用Get-ADComputer取非常用属性的值
  8. 获取图片颜色的rgb,以供css设计背景颜色
  9. Think in java备忘录
  10. 白书P61 - 点集配对问题
  11. Linux系统编程(35)—— socket编程之TCP服务器的并发处理
  12. configure配置脚本的使用
  13. 【BZOJ1212】L语言(AC自动机)
  14. js异步梳理:1.从浏览器的多进程到JS的单线程,理解JS运行机制
  15. Software Testing 2 —— Fault、error and failure小练习
  16. P2704 [NOI2001]炮兵阵地
  17. (原)在firefly_rk3288开发板上解决openGL在设置32位色深以后出现花屏的问题
  18. IE11浏览器,按F12 检查元素,工具会出来,但是没法正常使用?
  19. 【java排序】 归并排序算法、堆排序算法
  20. Linux笔记-Linux命令初解2

热门文章

  1. java基础语法this关键字
  2. SpringMVC—概述
  3. EditPlus 4.3.2477 中文版已经发布(11月3日更新)
  4. Ubuntu16.04安装wireshark
  5. 20145307陈俊达《网络对抗》Exp3 免杀原理与实践
  6. Ubuntu 安装zookeeper
  7. git status出现 fatal: Not a git repository (or any of the parent directories): .git
  8. Linux 实现软件可视化安装(VNC)
  9. linux 系统忘记登录密码
  10. Factory Method(工厂方法)