AdaBoost+LBP人脸检测时间用量分析
人脸检测过程采用多尺度滑窗搜索方式,每个尺度通过一定步长截取大小为20x20的窗口,然后将窗口放到级联分类器中进行是不是人脸的判决,如果是人脸则该窗口通过所有级联分类器;反之,会在某一级分类器被排除。
流程如下:
图中所示为主要的人脸检测步骤,其中:
1. 多尺度搜索是对图像按一定的ScaleFactor进行缩小,每缩小一次,在缩小后的图像上进行大小为20x20的人脸检测;
2. 单尺度搜索是在缩小到某一尺度的图像中,在x, y两个维度上通过一定步长(如2 pixel)进行20x20的窗口扫描,将截取的窗口送到分类器中进行特征提取和判决;
滑窗扫描示意图
可以看出,单尺度滑窗操作的待判断窗口数数量约为(height-20) /ystep *(width-20) /xstep,以100*100的待检测图像为例,xstep,ystep为2的情况下,需要判断的窗口数约为1600个;多尺度情况下,每个尺度都要进行滑窗,所以总检测窗口数数量会大很多。搜索空间大是所有基于多尺度滑窗检测算法在效率方面面临的主要问题。
下面对检测过程的时间用量分析采用了两种方式,一种是基于Visual Studio2013的分析工具profiler的分析结果,一种是在程序中嵌入时间测量代码进行断点测量结果。二者的测试平台均为PC, Win7 32bit, i5-4590 3.3GHz, 4G内存, OpenCV 2.4.10
注意,两种方法的测试图像不同,所以结果有所差异,但并不影响对程序中各部分用时的分析;结果的差异主要是测试的图像分辨率不同,导致不同步骤的运算量的变化量不同,在总时间的所占比例上会产生差异。
1. Profiler分析结果(图像分辨率为640*385)
其中相关函数说明如下:
detectMultiScale, 多尺度搜索;
resize, 尺度变换函数,插值方式为Bilinear;
groupRectangles, 检测窗口合并;
detectSingleScale, 单尺度搜索;
setImage, 计算积分图;
runAt, 判断一个20*20窗口;
predictCategoricalStump, 计算特征及分类器判断;
LBPEvaluator::operator(), Feature::calc,计算LBP特征值;
VS进行评估时,是以一定的频率抽样,用函数被抽到的次数来估计函数执行所用的时间,那么用抽样次数除以总抽样数可以得到函数时间用量比例。从图中可以看到单尺度检测消耗了96.39%的时间,其中特征计算消耗74.43%,分类器判断消耗20.33%。因此算法的主要瓶颈为特征计算和分类器判断环节。
2. 自测结果(图像分辨率3216*2136)
之前也对时间用量进行了自测,自测采用了一张分辨率较大的图像,结果记录如下:
函数 |
|
时间 ms |
比例 |
子函数 |
时间 ms |
比例 |
resize |
|
45 |
0.0061116 |
|
|
|
detectMultiScale |
|
7303 |
0.9918511 |
runAt |
7270 |
0.987369 |
|
|
|
|
setImage |
31 |
0.00421 |
groupRectangles |
|
15 |
0.0020372 |
|
|
|
|
|
|
|
|
|
|
可以看出特征计算和分类器判断占用率98.74%的时间。综上所述,在进行多尺度检测时,待判断的窗口数数量较大,特征计算和判断执行次数庞大,消耗了绝大多数时间。
1. 分类器模型的构成
分类器模型记录了区分人脸和非人脸的相关特征,以及使用这些特征进行判断的相关参数。对于AdaBoost+LBP分类器模型,是由特征对应的弱分类器进行加权组合后形成强分类器器,再把多级的强分类器进行级联得到。其中训练的特征和对应的弱分类器,弱分类器权重,一级中弱分类器的个数,强分类器的级数等都是由训练算法在用户设定的检出率和误检率的前提下训练得到。
在此对分类器中的特征分布进行说明。
分类器中的特征选择结果 MB-LBP的计算
如上图(左)示意为训练的分类器中所用到的MB-LBP特征所对应的 计算区域中心在人脸区域上的分布,其特点为:第一,矩形框的宽高大小随机(小于宽高的1/3);第二,矩形框在人脸图像中随机分布;第三,特征在每一级分类器中的分布是随机的。
2. 特征计算与分类器判断
如上图(右)所示,为MB-LBP的计算示意图,即以某特征对应的矩形为中心,在其周围以与该矩形同样尺寸找到其8邻域矩形区域(图中为3*3的矩形块, 1-8编号矩形为8邻域矩形);通过计算8邻域矩形的各自灰度平均值并与中间的矩形的灰度平均值进行比较,用8位二进制纪录比较结果,大于等于则置1,小于则置0,以此可以得到一个字节的编码数,其对应的0~255的数值即为MB-LBP特征值。
其中矩形块的平均值可以用和值替换,求和是用积分图来加速计算的。
下面对分类器的判断进行详解,如下图所示:
分类器判断流程
图中,f表示特征值,不同级分类器特征不同,Thd为二值化操作。
图中的过程描述为,特征经决策树(只有树桩)二值化之后,得到对应的权值;将该级所有特征对应的权值相加再和该级的阈值进行比较得到该级的判别结果,即如果大于该级阈值则认为需要进一步确定是否为人脸(Yes)进入下一级,反之,认为非人脸(No)跳出判断。到最后一级如果输出Yes则认为该窗口为人脸,返回该人脸窗口。
判断过程需要一级一级遍历弱分类器,在每个若分类器中主要操作为特征计算和决策树二值化操作,其中二值化操作对于LBP特征来说并非是进行阈值操作,而是通过一种较为复杂的规则进行映射,规则表示如下:
sum +=cascadeLeaves[subset[LBPValue >> 5] & (1 << (LBPValue &31)) ? leftLeaf : rightLeaf];
其中sum对该级所有的特征对应的权值进行求和;cascadeLeaves数组存储了特征对应的权值;subset中为训练出来的映射参数;LBPValue为LBP特征值;leftLeaf,rightLeaf为决策树的左右叶子,通过左右叶子值可以得到特征的权值。
仅从代码执行效率考虑,计算量主要集中在特征计算和分类器判断部分。则:
1. 特征计算主要为加减法运算和比较运算,由于特征区域的随机分布,在乱序的情况下,没有想到可行的SIMD加速方式;
2. 判断方式上,主要是移位运算和判断,没有加速方案;
3. 有文献采用提前终止判断的方式进行加速,个人实现后加速约10%。
目前从底层上没有想到有大的加速效果的相关方法。
后记: 欢迎在加速上进行各种讨论,谢谢。