Viola-Jones的人脸检测声称有18万个功能
computer-vision
image-processing
5
0

我一直在实施Viola-Jones的面部检测算法的改编版。该技术依赖于在图像内放置一个24x24像素的子帧,然后在每个位置以各种尺寸放置矩形特征。

这些特征可以由两个,三个或四个矩形组成。提供以下示例。

矩形特征

他们声称穷举集超过18万(第2节):

假设检测器的基本分辨率为24x24,则详尽的矩形特征集非常大,超过180,000。请注意,与Haar基础不同,矩形要素集过于完整。

本文中未明确陈述以下陈述,因此它们是我的假设:

  1. 只有2个两个矩形的特征,2个三个矩形的特征和1个四个矩形的特征。其背后的逻辑是,我们正在观察突出显示的矩形之间的差异 ,而不是显式地观察颜色或亮度或任何类似的东西。
  2. 我们无法将要素类型A定义为1x1像素块;它必须至少为1x2像素。另外,类型D必须至少为2x2像素,并且此规则也适用于其他功能。
  3. 我们无法将要素类型A定义为1x3像素块,因为无法对中间像素进行分区,并且将其自身减去后就等于1x2像素块;仅为均匀宽度定义此要素类型。同样,要素类型C的宽度必须被3整除,并且该规则也适用于其他要素。
  4. 我们无法定义宽度和/或高度为0的要素。因此,我们将xy迭代为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 。 (请注意,这将有效防止要素触及子帧的右侧和/或底部。)

当然,现在的问题是:他们在实施中是否犯了错误?考虑表面为零的特征有意义吗?还是我看错了方向?

参考资料:
Stack Overflow
收藏
评论
共 4 个回答
高赞 时间 活跃

仔细观察,您的代码对我来说是正确的;这使一个人想知道原始作者是否有一个单一的错误。我想有人应该看看OpenCV是如何实现的!

尽管如此,一个更容易理解的建议是先遍历所有大小,然后遍历给定大小的可能位置来翻转for循环的顺序:

#include <stdio.h>
int main()
{
    int i, x, y, sizeX, sizeY, width, height, count, c;

    /* All five shape types */
    const int features = 5;
    const int feature[][2] = {{2,1}, {1,2}, {3,1}, {1,3}, {2,2}};
    const int frameSize = 24;

    count = 0;
    /* Each shape */
    for (i = 0; i < features; i++) {
        sizeX = feature[i][0];
        sizeY = feature[i][1];
        printf("%dx%d shapes:\n", sizeX, sizeY);

        /* each size (multiples of basic shapes) */
        for (width = sizeX; width <= frameSize; width+=sizeX) {
            for (height = sizeY; height <= frameSize; height+=sizeY) {
                printf("\tsize: %dx%d => ", width, height);
                c=count;

                /* each possible position given size */
                for (x = 0; x <= frameSize-width; x++) {
                    for (y = 0; y <= frameSize-height; y++) {
                        count++;
                    }
                }
                printf("count: %d\n", count-c);
            }
        }
    }
    printf("%d\n", count);

    return 0;
}

结果与之前的162336相同


为了验证这一点,我测试了4x4窗口的情况并手动检查了所有情况(因为1x2 / 2x1和1x3 / 3x1形状仅旋转了90度,形状却很容易计数):

2x1 shapes:
        size: 2x1 => count: 12
        size: 2x2 => count: 9
        size: 2x3 => count: 6
        size: 2x4 => count: 3
        size: 4x1 => count: 4
        size: 4x2 => count: 3
        size: 4x3 => count: 2
        size: 4x4 => count: 1
1x2 shapes:
        size: 1x2 => count: 12             +-----------------------+
        size: 1x4 => count: 4              |     |     |     |     |
        size: 2x2 => count: 9              |     |     |     |     |
        size: 2x4 => count: 3              +-----+-----+-----+-----+
        size: 3x2 => count: 6              |     |     |     |     |
        size: 3x4 => count: 2              |     |     |     |     |
        size: 4x2 => count: 3              +-----+-----+-----+-----+
        size: 4x4 => count: 1              |     |     |     |     |
3x1 shapes:                                |     |     |     |     |
        size: 3x1 => count: 8              +-----+-----+-----+-----+
        size: 3x2 => count: 6              |     |     |     |     |
        size: 3x3 => count: 4              |     |     |     |     |
        size: 3x4 => count: 2              +-----------------------+
1x3 shapes:
        size: 1x3 => count: 8                  Total Count = 136
        size: 2x3 => count: 6
        size: 3x3 => count: 4
        size: 4x3 => count: 2
2x2 shapes:
        size: 2x2 => count: 9
        size: 2x4 => count: 3
        size: 4x2 => count: 3
        size: 4x4 => count: 1
收藏
评论

所有。中提琴和琼斯的论文仍然有些混乱。

在他们的CVPR'01文件中明确指出:

“更具体地说,我们使用三种特征。 两个矩形特征的值是两个矩形区域内像素之和之间的差。这些区域具有相同的大小和形状,并且在水平或垂直方向上相邻(参见图1)。 三矩形特征计算两个外部矩形内的总和,然后减去中心矩形中的总和。最后得到一个四矩形特征 “。

在IJCV'04论文中,说的完全相同。 因此,共有4个功能 。但是很奇怪的是,他们这次说详尽的功能集是45396!那似乎不是最终版本,我想这里引入了一些其他约束,例如min_width,min_height,宽度/高度比甚至位置。

请注意,这两篇论文都可以在他的网页上下载。

收藏
评论

在没有阅读整篇文章的情况下,您的报价措词向我伸出来

假设检测器的基本分辨率为24x24,则详尽的矩形特征集非常大,超过180,000。请注意,与Haar基础不同,矩形要素集过于完整。

“矩形特征集过于完备”“详尽集”

对我来说,这听起来像是一个设置,我希望论文撰写者能够对它们如何将搜索空间缩小为更有效的集合进行解释,例如,摆脱一些琐碎的情况,例如零矩形的情况表面积。

编辑:或使用某种机器学习算法,如摘要所示。穷举集意味着所有可能性,而不仅仅是“合理”的可能性。

收藏
评论

不能保证任何论文的任何作者的所有假设和发现都是正确的。如果您认为假设4是正确的,则保留该假设,然后尝试您的理论。您可能比原始作者更成功。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号