天天看点

【dlib代码解读】人脸检测器的训练【转】 1. 综述 2. 代码解读 step by step

版权声明:本文为博主原创文章,转载请注明。

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t0">综述</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t1">代码解读 step by step</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t2">1 预处理阶段</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t3">11 载入训练集测试集</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t4">12 图片上采样</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t5">13 镜像图片</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t6">2 训练阶段</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t7">21 定义scanner用于扫描图片并提取特征</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t8">22 设置scanner扫描窗口大小</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t9">23 定义trainer用于训练人脸检测器</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t10">24 训练生成人脸检测器</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t11">25 测试</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t12">3 tips</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t13">31 模型的存储</a>

<a href="http://blog.csdn.net/elaine_bao/article/details/53046542#t14">32 多个detector联合使用</a>

【dlib代码解读】人脸检测器的训练【转】 1. 综述 2. 代码解读 step by step

以下给出完整的人脸检测器训练代码(详细代码解读请看第2部分):

训练集和测试集图片存储在”faces”文件夹下,另外该文件夹下还需包含training.xml,testing.xml,包含图片中人脸bounding box的位置。组织形式为: 

【dlib代码解读】人脸检测器的训练【转】 1. 综述 2. 代码解读 step by step

即图片放大两倍,这样有助于检测较小的人脸。 

上述函数在对图片进行上采样的同时,也相应地调整了人脸bounding box的位置。

1

对训练所用图片做镜像处理,扩充训练集的训练样本。

class scan_fhog_pyramid定义来自于scan_fhog_pyramid.h,原型如下:

2

类模板中参数1表示图像金字塔的类型,本文使用的是pyramid_down&lt;6&gt;,表示图像金字塔进行下采样的比率为5/6,即对原图像不断缩小5/6,构成多级金字塔。什么时候停止下采样呢?当图像的大小&lt;扫描窗口大小的时候。 

参数2表示特征提取器,默认情况下使用fhog.h中的extract_fhog_feature()提取特征,函数原型为:

此函数提取的HOG特征来自于Felzenszwalb版本的HOG [1] (简称fhog),它是对每个8*8像素大小的cell提取31维的fhog算子,然后保存到上述hog array中供后续计算使用。 

31D fhog=18D+9D+4D。 

(1) 18D来自于对cell做18个bin的梯度方向直方图,即将360°划分为18个bin,然后令cell中的每个像素根据其梯度方向加权投影到直方图相应的bin中,这样就得到了18维有符号的fhog梯度。 

(2) 9D来自于对cell做9个bin的梯度方向直方图,此时是将180°划分为9个bin,则得到无符号的9维fhog梯度。 

(3) 最后的4D是来自于当前cell和其对角线临域的4个领域cell的归一化操作。具体地,取block=2*2 cell,则得到无符号fhog梯度4*9维,将其看成矩阵做按行按列累加可得到1D特征,4个领域则可得到4个block,共4维特征。 

最终,每个cell的31维fhog特征就来自于上述三部分的串联。 

【dlib代码解读】人脸检测器的训练【转】 1. 综述 2. 代码解读 step by step

设置扫描窗口大小为80*80,即扫描窗口是固定大小的,通过放缩图像(图像金字塔)以达到在不同尺度上检测人脸的目的。 

由于在预处理中图像放大了2倍,则图像中最小能检测到的人脸大小为40*40。

structural_object_detection_trainer定义来自于structural_object_detection_trainer.h,通过scanner来初始化trainer。

train()的函数原型在structural_object_detection_trainer.h有4个,这里用的是其中一个,即输入参数为图片和图片中人脸的正确位置,输出一个object_detector。 

注意这种情况下除了已经标出的人脸位置为正样本以外,图片的其他位置随机取负样本,因此在标注训练图片的人脸时,应确保所有人脸都已标注出来。如果出现不太确定是不是人脸的图片,应调用另一个版本的train()函数并设置ignore区域。 

关于train()的内部实现,其实就是训练一个SVM模型,当模型loss&lt;之前所设的epsilon的时候,输出训练好的模型到object_detector。

detector()函数直接返回图片中所有检测到的人脸的bounding box信息。

通过serialize()可以实现对模型的保存,而deserialize()可以将磁盘中保存的模型取出来用。

3

4

5

在文章开篇的时候提到上述人脸检测器比较适用于正脸的检测,对于侧脸的检测效果并不好。那么我们可以单独训练侧脸的人脸检测器,然后多个detector联合使用。

串联所有人脸检测器一起使用的好处是,全图的fhog特征只需要提取一遍即可。 

例如,在dlib自带的人脸检测器中就用了5个HOG-based detector,分别用于检测front looking, left looking, right looking, front looking but rotated left, and a front looking but rotated right one. 下面是这五个detector的训练参数log:

[1] Object Detection with Discriminatively Trained Part Based Models by P. Felzenszwalb, R. Girshick, D. McAllester, D. Ramanan, IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol. 32, No. 9, Sep. 2010。

【新浪微博】 张昺华--sky

【twitter】 @sky2030_

【facebook】 张昺华 zhangbinghua

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.

继续阅读