1 介绍
在过去的几个月里,我主要针对人脸检测进行了研发,尝试的方法包括,adaboost+haar特征,npd人脸检测,和jda人脸检测。这三种方法我都有实现,显然jda人脸检测器效果最佳。
2 方法介绍
jda检测器融合了检测和对齐两种方式,重在检测,通过对齐的方式使检测的效果更好更快。
2.1 样本预处理
样本内容包含:图像、真实人脸、估计人脸、置信度和权值。对于人脸图像来说,首先要将人脸归一到同一尺度,我的做法是:
1)计算真实人脸形状的最小外接矩形;
2)计算正方形,其中心为矩形的中心,边长为矩形最大边长;
3)计算正方形边长与标准大小的比例,根据这一比例缩放图像和人脸形状;
训练样本初始的估计人脸是均值人脸的微小变换(旋转、平移和缩放),权值为1,置信度为0。检测样本的初始人脸为均值人脸。不要用均值人脸直接作为估计人脸。
在实际的训练过程中,负样本会出现严重不够的情况建议用随机变换的方式扩充样本库。
2.2 弱分类器特征
弱分类器所选用的特征是像素差,提取方式如下:
1) 生成弱分类器模板,内容包括两个2D偏移量,N个特征点之二的ID,尺度值(1.0, 0.5, 0.25);
2) 计算当前形状与均值形状之间的尺度和角度关系;
3) 根据角度和尺度映射映射偏移量;
4) 偏移量分别加到两个指定ID的当前标记点,得到两个像素,求其差值作为特征。
参加分类的样本,负样本大于10倍正样本,最好是能达到50倍。
2.3 分类器类型
弱分类器选择为计算最大熵(正负样本都参加)或最小偏移量(仅正样本参加),用概率p来选择,前面的stage,p更大表示选择最大熵方式的概率大些。
强分类器采用树型结构,每个非叶节点是一个弱分类器,叶节点保存一个置信度,到达该叶节点的样本需加上这个值来更新置信度。一棵树还有一个置信度阈值,根据召回率来设定,也就是说样本经过每一个决策树,都会与阈值比较小于阈值认定为负样本并pass掉。
级联强分类器,也就是一棵棵决策树依次分类正样本,但是要分为多级,每一级分类之后要进行回归。
2.4 回归器
回归的目的是预测样本在当前状态下应该发生多少偏移可以到达真实位置。也就是说在单级决策树训练完成后还要训练回归器,回归器的特征是二值特征,提取方式如下:
1) 如果决策树叶节点有8个,样本分到第三个叶节点,则形成0010000;
2) 连接样本经过的所有决策树生成的二值特征;
回归器就是二值特征到偏移量的映射,使用liblinear可以解决,用公式可表示为IW=Y,I表示特征,Y表示偏移量,W表示权值。
github上一些实现,使用liblinear来解线性方程,得到的结果用liblinear自己的接口来保存,然后使用的时候用liblinear的函数预测,这样做会显著减慢速度以及增加模型大小。解决这两个问题的方法是把权值矩阵提取出来。
3 实现结果
个人用C++实现了训练和检测的代码,并做了一些改进,在FDDB上ROC曲线的召回率见下图,在3.3GHz,4核的PC机上,采用单核,10个尺度,0.1 * WINW的滑动窗口,检测范围是图像短边的0.2~0.95,720P图像大概学要17ms。另外模型大小不到2M,检测代码为纯C++,完全不调用第三方库。演示视频见 http://v.youku.com/v_show/id_XMTY0MzcwODg4NA==.html?from=y1.7-2。
参考文献
[1] Robust Real-Time Face Detection
[2] A Fast and Accurate Unconstrained Face Detector.
[3] Joint Cascade Face Detection and Alignment