【人脸检测】OpenCV中的Haar+Adaboost级联分类器分解(二):积分图和45°旋转积分图

前一篇文章分析了Haar特征,即通过“平移+放大”能够产生一系列数量巨大的Haar子特征,同时给出了Haar特征值计算公式。那么这就有一个问题:如何快速的计算出图像任意位置的某个Haar特征值?这就需要用到本节介绍的积分图。

-------------------------------------------
缩进以OpenCV自带的人脸分类器haarcascade_frontalface_alt.xml为例,其中存储了213个大小和位置都不相同的Haar特征(XML文件解释见下节)。在运算中,伴随着检测窗口的移动,如何快速计算Haar特征值就成了一个很重要的问题。试想一下,如果采用最笨的办法,每次移动检测窗口时都进行一系列的求和运算,机器彻底要卡死。为了解决这个问题,在设计Haar+AdaBoost算法时,Paul Viola等人就提出积分图。
缩进说明:本文中提到的索引都是从0开始,即符合C语言习惯。

(一)一般积分图
缩进在连续空间中一般采用积分方式计算体积、面积等和重量等物理量;而在离散空间中也可以用积分方式计算,只不过这里的“积分”实际上就是求和而已。用于计算Haar特征值灰度图像是一个离散的二维矩阵,所以我认为“积分图”这个词应该改为“加和图”更确切。废话到此为止,接下来我们一起看看积分图的定义。
缩进对于灰度图像中任意一点image(x,y),定义其积分图为sum(x,y)为:
其中image(x',y')为点(x',y')处的原始灰度图。这样就定义了一张类似于数学中“积分”的积分图。如图1,如果要计算D区域内灰度和,只需计算sum(x4,y4)-sum(x3,y3)-sum(x2,y2)+sum(x1,y1),其中ii是积分图,(x1,y1)、(x2,y2)、(x3,y3)和(x4,y4)依次代表图1中image的1 2 3 4点的图像坐标。需要说明,在计算D区域灰度和时sum(x1,y1)深蓝色区域被减去了2次,最后需要补上。显然可以通过此方法快速计算图像中任意位置和大小区域的灰度和,即通过积分图只需要做有限次操作就能获得任意位置的Haar特征值


图1 积分图计算Haar矩形框示意图

缩进与上面理论不同的是,为了方便计算,在OpenCV中width*height的灰度图计算出的积分图大小为(width+1)*(height+1)。OpenCV中的积分图定义为:


这种方式实际上对原积分图进行了“扩边”,积分图中第0行和第0列的值都为0。采用这种“扩边”方式计算积分图主要是为了方便计算。为了便于说明,设计算灰度图是w*h大小的二维数组image(w,h),积分图是一个(w+1)*(h+1)大小的二维数组sum(w+1,h+1),那么用伪代码表示OpenCV中的“扩边”积分图计算方式:

[cpp]  view plain  copy
  1. // 初始化积分图二维数组元素全部为0,保证第一行和第一列为0  
  2. for r = 0:h-1 // row index  
  3.     for c = 0:w-1 // col index  
  4.         sum(r,c) ← 0  
  5.     end  
  6. end  
  7.   
  8. // 计算积分图二维数组每个元素的值  
  9. for r = 1:h  
  10.     for col = 1:w  
  11.         sum(r,c) ← sum(r-1,c) + sum(r,c-1) - sum(r-1,c-1) + image(r-1,c-1)  
  12.     end  
  13. end  

缩进以图2为例说明此段伪代码。积分图sum矩阵被初始化为全0,这就保证了积分图第0列和第0行的值都为0;之后从第1行和第1列开始遍历积分图矩阵,计算方式如下为:

(r,c)点积分图值 = (r,c)点左边积分图值 + (r,c)点右边积分图 - (r-1,c-1)点左上积分图值 + (r,c)点对应的灰度图灰度值

sum(r,c) = sum(r-1,c) + sum(r,c-1) - sum(r-1,c-1) + image(r-1,c-1)

其中(r-1,c-1)左上点积分图值对应的深蓝区域被加了2次,所以要减去1次。这样就能够很快的求出积分图。


图2


(二)45°旋转积分图
缩进 为了提高Haar+Adaboost算法检测精度,Rainer Lienhart等人首先提出了45°旋转积分图,如图3。旋转积分图用于快速计算上一篇文中介绍的titled_x2和titled_y2等共6种旋转Haar特征。

图3

缩进与一般积分图类似,OpenCV中45°旋转积分图同样采用了“扩边”方式(即旋转积分图比原灰度图多1行和1列,其中第1行和第1列元素为0),对应的计算公式为:


缩进有了旋转积分图如何计算任意位置和大小的45°倾斜长方形区域的灰度和呢?设有如图4红色方框大小的灰度图image,其计算出来的45°旋转灰度图为titled(第1行和第1列为0),虚线代表image中cv::Rect为<3 1 2 3>区域。显然虚线区域的灰度和为:titled(2,6) - titled(1,4) - titled(6,3) + titled(1,4),应该不难理解。

图4

缩进在实际中,如果使用旋转特征,则需要多计算一张积分图。但是旋转特征的效果往往不理想,得不偿失,不建议使用。故仅做了解就可以了。


-------------------------------------------

参考文献:


[1]An Extended Set of Haar-like Features for Rapid Object Detection.
[2]OpenCV文档
------------------------------------------

猜你喜欢

转载自blog.csdn.net/qq_36097393/article/details/80026132