对角线特征在原始的论文中没有使用。
特征值的计算方式如下:将黑色区域内的像素值的和减去白色像素内的和。如下图:即,将矩形区域内的紫色区域数字之和减去青色区域内数字之和,得到的就是特征值:[图片上传失败...(image-990054-1528899323306)]
Haar 特征数量的计算
以一个 24 × 24 的窗口为例,且使用下图中的特征矩形:[图片上传失败...(image-913c3-1528899323306)]
那么对于 (a) 存在都少可能的特征矩形呢?可以看到矩形的宽高比为 2:1 ,宽高可取的范围都为 24 ,即宽取1 ~ 24内的偶数,高 1 ~ 24,那么所有可能的组合就为(高 × 宽):1x2, 1x4, 1x6, 1x8, ..., 1x24, 2x2, 2x4, 2x6, 2x8, ..., 2x24, 3x2, 3x4, 3x6, ..., 一直到 24x24.
同理 (b) 的宽高比为 3:1 ,宽的取值需要时 3 的倍数,高的取值则是连续数。
那么,每一种可能的特征矩形(如 2x2)可产生的特征数为(24 - weight + 1)(24 - height + 1)。
# W/H 表示窗口的大小,w/h 表示特征矩形的宽高(最小情况下)
def calc_haar_count(W,H,w,h):
total = 0
# 特征矩形的宽可能取值
for i in range(w,W+1,w):
# 特征矩形的高可能取值
for j in range(h,H+1,h):
# 每种特征矩形产生的特征数量
total += (W - i + 1) * (H - j + 1)
return total
# a 2:1 43200
print(calc_haar_count(24,24,2,1))
# b 3:1 27600
print(calc_haar_count(24,24,3,1))
# c 1:2 43200
print(calc_haar_count(24,24,1,2))
# d 1:3 27600
print(calc_haar_count(24,24,1,3))
# e 2:2 20736
print(calc_haar_count(24,24,2,2))
可以看到五种特征矩形的宽高比分别为:(a) 2:1,(b) 3:1, (c) 1:2, (d) 1:3,(e) 2:2. 那么每种类型的特征值数量为:43200, 27600, 43200, 27600, 20736。总计为 160381 。五种可能的类型就产生了 16 万以上的特征值,这个是一个非常大数字了,如果把全部的可能都考虑上那计算量可想而知。
还有一种计算公式是作者在论文中提出来的,对于非旋转的可以使用:$$ XY(W + 1 - w\frac {X + 1}{2})(H + 1 - h\frac{Y + 1}{2}) $$
其中 $W×H$ 表示图片的宽高,$w×h$ 表示特征矩形的宽高,$X=\frac{W}{w}$,$Y=\frac{H}{h}$ 表示在水平以及垂直方向的缩放系数。
如上面的例子,其中 $W×H$ 为 24×24,对于 (a) 来说 $w×h$ 为 2×1,那么可以计算出 X 为 12,Y 为 24。因此特征数量为$$ 12×24×(24 + 1 - 2\frac {12 + 1}{2})×(24 + 1 - 1\frac{24 + 1}{2}) = 43200$$
与上面的计算结果是一致的。
对于产生旋转的特征矩形,特征矩形的宽高需要产生变化,X/Y 需要按照新特征矩形的宽高来重新计算。新的特征矩形的计算如下图:[图片上传失败...(image-3441d8-1528899323306)]
新的计算公式如下:$$ XY(W + 1 - z\frac {X + 1}{2})(H + 1 - z\frac{Y + 1}{2}) $$
其中 $z=w+h$,那么 $X = \frac{W}{z}$,$Y = \frac{W}{z}$
积分图
积分图(integral image),又称总和面积表( ** summed area table ** ,简称SAT). 对于一幅灰度的图像,积分图像中的任意一点(x,y)的值是指从图像的左上角到这个点的所构成的矩形区域内所有的点的灰度值之和。如下图[图片上传失败...(image-6308ce-1528899323306)]
即求第4行第7列的分I(4,7),就是让左上角蓝色区域内的值求和,所得的值就是 I(4,7) 的积分值,即130.
不仅可以计算左上角的积分值,还可以计算任意矩形区域内的积分值,如下图:[图片上传失败...(image-3887c8-1528899323306)]
上面的公式虽然可以计算积分值,但是当图片的尺寸扩大计算量是非常大的,此时我们就可以使用积分图来进行高效的计算。
首先我们需要获取一张图的积分图,积分图的算法构建如下:
用 $s(i,j)$ 表示行方向的累加和,初始化$s(i,-1)=0$,每一行的初始值为 0;
用 $ii(i,j)$ 表示一个积分图像,初始化 $ii(-1,j)=0$,每一列的初始值为 0 ;
逐行扫描图像,计算每个像素 $(i,j)$ 行方向的累加和 $s(i,j)$ 和积分图像 $ii(i,j)$ 的值:
$$s(i,j)=s(i,j-1)+i(i,j) \quad(1)\ ii(i,j)=ii(i-1,j)+s(i,j) \quad(2)$$
- 扫描图像一遍,当到达图像右下角像素时,积分图像ii就构造好了。
上面的公式(1)和(2)是两个递推公式。这样我们就计算好了积分图,在 google Spreadsheets 中计算积分图也很方便。
再看下面这幅图,其中 A、B、C、D 表示一张图中的四个区域,1、2、3、4 表示 D 区域的四个顶点。
可以看到 D 区域内使用上述方法计算时,1、2、3、4点在积分图中对应的四个点(蓝色圈中的点)为:
ii(1) = 49
ii(2) = 96
ii(3) = 88
ii(4) = 157
那么 ii(D) = ii(4) + ii(1) - ii(2) - ii(3) = 157 + 49 - 96 - 88 = 22 ,计算的结果正是 D 区域内所有元素的和。
那么对于 haar 特征矩形该如何算呢?如下图:[图片上传失败...(image-4ecbc4-1528899323306)]
我们可以看到 如果是二矩形需要在积分图中查找 6 次,三矩形需要查找 8 次就可以得到计算 haar 特征的所有值。二阶矩形的 haar 特征值计算为黑色区域内的和减去白色区域内的和,那么:
$sum(black) = ii(4) + ii(1) - ii(2) - ii(3) = 62 + 8 - 14 - 33 = 23$
$sum(white) = ii(4) + ii(1) - ii(2) - ii(3) = 91 + 14 - 18 - 62 = 25$
$haar \ value = sum(black) - sum(white) = 23 - 25 = -2$
其他特征矩形的计算与此类似,旋转特征矩形的计算暂时没有看,可以参考原始论文中的方法。
【参考】
百度百科 - 积分图像
wikipedia - 积分图
积分图像(Integral Image)与积分直方图 (Integral Histogram)
Number of haar like features in 24x24 window
【图像处理】计算Haar特征个数
人脸Haar特征与快速计算神器:积分图
机器视觉中的图像积分图及其实现
特征提取之Haar特征
FACE DETECTION USING OPENCV AND PYTHON: A BEGINNER’S GUIDE
OpenCV - Face Detection using Haar Cascades
原始论文 - An extended set of Haar-like features for rapid object detection