【发布时间】:2010-12-15 00:34:30
【问题描述】:
我一直在实施Viola-Jones' face detection algorithm 的改编。该技术依赖于在图像中放置一个 24x24 像素的子帧,然后将矩形特征放置在图像内的每个位置,并且可能具有各种尺寸。
这些特征可以由两个、三个或四个矩形组成。下面给出一个例子。
他们声称详尽的集合超过 180k(第 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。 (请注意,这将有效地防止特征接触子框架的右侧和/或底部。)
现在当然是问题:他们在实施过程中是否犯了错误?考虑表面为零的特征是否有意义?还是我看错了?
【问题讨论】:
-
为什么我在运行您的代码时得到 count=114829?
-
为什么你的 x/y 循环从 1 开始?我假设 x/y 是特征矩形的左上角坐标。那么 x/y 不应该从 0/0 开始吗?
-
除了它是从 0 还是 1 开始之外,以
x < size结束与假设 #4 有关:我希望该功能保留在子帧内,但尺寸至少为 1x1。至于特征的维度是否不应该延伸到子帧之外,嗯,也许这也是一个假设。 -
同样,如果我从 0 开始 x,它必须运行到
x < size - 1,所以没有增益。 -
我已经完成了无数次循环。这对我来说似乎是错误的。
标签: algorithm image-processing computer-vision face-detection viola-jones