前一篇文章分析了Haar特征,即通过“平移+放大”能够产生一系列数量巨大的Haar子特征,同时给出了Haar特征值计算公式。那么这就有一个问题:如何快速的计算出图像任意位置的某个Haar特征值?这就需要用到本节介绍的积分图。
缩进对于灰度图像中任意一点image(x,y),定义其积分图为sum(x,y)为:
图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中的“扩边”积分图计算方式:
- // 初始化积分图二维数组元素全部为0,保证第一行和第一列为0
- for r = 0:h-1 // row index
- for c = 0:w-1 // col index
- sum(r,c) ← 0
- end
- end
- // 计算积分图二维数组每个元素的值
- for r = 1:h
- for col = 1:w
- sum(r,c) ← sum(r-1,c) + sum(r,c-1) - sum(r-1,c-1) + image(r-1,c-1)
- end
- 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
图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文档