我一直在实施Viola-Jones的人脸检测算法的改编。该技术依赖于在图像内放置一个24x24像素的子帧,然后在每个位置以各种尺寸放置矩形特征。
这些特征可以由两个,三个或四个矩形组成。提供以下示例。
他们声称穷举集超过18万(第2节):
假设检测器的基本分辨率为24x24,则详尽的矩形特征集非常大,超过180,000。请注意,与Haar基础不同,矩形要素集过于完整。
本文中未明确陈述以下陈述,因此它们是我的假设:
- 只有2个两个矩形的特征,2个三个矩形的特征和1个四个矩形的特征。其背后的逻辑是,我们正在观察突出显示的矩形之间的差异,而不是显式地观察颜色或亮度或任何类似的东西。
- 我们无法将要素类型A定义为1x1像素块;它必须至少为1x2像素。同样,类型D必须至少为2x2像素,并且该规则也适用于其他功能。
- 我们无法将要素类型A定义为1x3像素块,因为无法对中间像素进行分区,并且从自身中减去它就等于1x2像素块;仅为均匀宽度定义此要素类型。同样,要素类型C的宽度必须被3整除,并且该规则也适用于其他要素。
- 我们无法定义宽度和/或高度为0的要素。因此,我们将x和y迭代为24减去要素的大小。
基于这些假设,我计算了详尽的集合:
const int frameSize = 24;
const int features = 5;
// All five feature types:
const int feature[features][2] = {{2,1}, {1,2}, {3,1}, {1,3}, {2,2}};
int count = 0;
// Each feature:
for (int i = 0; i < features; i++) {
int sizeX = feature[i][0];
int sizeY = feature[i][1];
// Each position:
for (int x = 0; x <= frameSize-sizeX; x++) {
for (int y = 0; y <= frameSize-sizeY; y++) {
// Each size fitting within the frameSize:
for (int width = sizeX; width <= frameSize-x; width+=sizeX) {
for (int height = sizeY; height <= frameSize-y; height+=sizeY) {
count++;
}
}
}
}
}
其结果是162,336。
我发现逼近Viola&Jones所说的“超过180,000”的唯一方法是放弃假设4,并在代码中引入错误。这涉及分别将四行更改为:
for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)
结果是180,625。(请注意,这将有效防止要素接触子框架的右侧和/或底部。)
当然,现在的问题是:他们在实施中是否犯了错误?考虑表面为零的特征有意义吗?还是我看错了方向?