【问题标题】:Defining an (initial) set of Haar Like Features定义一组(初始)Haar Like 特征
【发布时间】:2015-02-04 00:48:53
【问题描述】:

当谈到级联分类器(使用类似 haar 的特征)时,我总是读到 AdaBoosting 等方法用于选择“最佳”特征进行检测。但是,这仅在有一些初始功能集开始增强时才有效。

给定一个 24x24 像素的图像,有 162,336 个可能的 haar 特征。我在这里可能错了,但我不认为像 openCV 这样的库最初会针对所有这些特性进行测试。

所以我的问题是如何选择初始特征或它们是如何生成的?是否有关于初始功能数量的指导方针?

如果最初使用所有 162,336 个功能。它们是如何产生的?

【问题讨论】:

  • 我记得几年前我问过自己同样的问题。我什至想尝试训练所有的可能性,看看能不能得到更好的结果。不幸的是,我的级联训练器实现不允许在内存中完成如此大的数量,并且需要一个新的专用实现。我最终没有时间检查它,但很想知道是否有人发现了这一点。
  • 这个讨论是一个例子,说明 SO 如何误导正在学习一门学科的人,并根据他们最初的信念支持答案。一切都基于一个错误的陈述:“但是,这仅在有一些初始功能集开始增强时才有效”。事实上,Viola Jones 的原始配方和随后的配方并不关心它,因为它确实不是问题。正如我在回答中所说,真正的瓶颈是在级联的最后阶段收集负样本的过程。这可能会导致训练持续很多天。
  • 如果有人不同意,我邀请他/她给我看 Opencv 源代码的一部分(我很清楚,因为我经常修改它)或 Viola-Jones 和 Lienhart -Maydt 论文,如果另有说明。

标签: machine-learning computer-vision haar-classifier cascade-classifier


【解决方案1】:

根据您的问题,我可以理解您想知道什么是 1,62,336 个功能。

来自 4 个原版中提琴琼斯特征(http://en.wikipedia.org/wiki/Viola%E2%80%93Jones_object_detection_framework)

我们可以通过改变 4 个原始特征的大小及其在 24*24 输入图像上的位置来生成 1,62,336 个特征。

例如,考虑具有两个彼此相邻的矩形的原始特征之一。 让我们考虑每个矩形的大小是 1 个像素。最初,如果在 24*24 图像的 (0,0) 上存在一个矩形,则将其视为一个特征,现在如果将其水平移动一个像素(到 (1,0) ),则将其视为第二个特征它的位置更改为 (1,0)。通过这种方式,您可以将其水平移动到 (22,0),生成 23 个特征。同样,如果您沿着垂直轴从 (0,0) 向上移动到 (0,23),那么您可以生成 24 个特征。现在,如果您移动覆盖每个位置的图像(例如 (1,1),(1,2).....(22,23) ),那么您可以生成 24*23=552 个特征。

现在如果我们考虑每个矩形的宽度是 2 像素,高度是 1 像素。最初,如果一个矩形出现在 (0,0) 上并沿水平轴移动到 (20,0) 如上所述,那么我们可以有 21 个特征,因为如果我们从 (0, 0) 到 (0,23) 我们可以有 24 个特征。因此,如果我们移动以覆盖图像上的每个位置,那么我们可以拥有 24*21=504 个特征。

这样,如果我们将每个矩形的宽度增加一个像素,并且每次覆盖完整图像时每个矩形的高度为 1 个像素,那么它的宽度从 1 个像素变为 24 个像素,我们得到否。特征数 = 24*(23+21+19.....3+1)

现在,如果我们考虑每个矩形的宽度为 1 像素,高度为 2 像素。最初,如果一个矩形出现在 (0,0) 上并沿水平轴移动到 (23,0),那么我们可以有 23 个特征,因为它的宽度是 1 像素,如果我们沿着垂直轴移动,它的高度是 2 像素从 (0,0) 到 (0,22) 那么我们可以有 23 个特征。因此,如果我们移动以覆盖图像上的每个位置,那么我们可以拥有 23*23=529 个特征。

类似地,如果我们将每个矩形的宽度增加一个像素,并在每次覆盖完整图像时将每个矩形的高度保持为 2 个像素,这样它的宽度就会从 1 个像素变为 24 个像素,我们得到否。特征数 = 23*(23+21+19.....3+1)

现在,如果我们将每个矩形的宽度从 1 像素更改为 24 像素,然后将每个矩形的高度增加 1 像素,直到每个矩形的高度变为 24 像素,那么

没有。特征数 = 24*(23+21+19.....3+1) + 23*(23+21+19.....3+1) + 22*(23+21+19... ..3+1) +..................+ 2*(23+21+19.....3+1) + 1*(23+21+ 19.....3+1)

            = 43,200 features

现在,如果我们考虑 2nd viola jones 原始特征,它有两个矩形,一个矩形在另一个矩形之上(即矩形垂直排列),因为这类似于 1st viola jones 原始特征,它也将具有

没有。特征数 = 43,200

类似地,如果我们按照上面的过程,从第 3 个原始 viola jones 特征中,有 3 个沿水平方向排列的矩形,我们得到 ​​p>

没有。特征数 = 24*(22+19+16+....+4+1) + 23*(22+19+16+....+4+1) + 22*(22+19+16+ ....+4+1) +................+ 2*(22+19+16+....+4+1) + 1*(22 +19+16+....+4+1)

            =27,600

现在,如果我们考虑另一个特征,它有 3 个垂直排列的矩形(即一个矩形在另一个上),那么我们得到 ​​p>

没有。 of features = 27,600(因为它类似于第 3 个原始 viola jones 功能)

最后,如果我们考虑第 4 个原始 viola jones 特征,它有 4 个矩形,我们得到 ​​p>

特征数 = 23*(23+21+19+......3+1) + 21*(23+21+19+......3+1) + 19* (23+21+19+......3+1) ......................+ 3*(23+21+19+...... .3+1) + 1*(23+21+19+......3+1)

           = 20,736

现在总结所有这些特征,我们得到 = 43,200 + 43,200 + 27,600 + 27,600 + 20,736

                                     = 1,62,336 features

因此,Adaboost 从以上 1,62,336 个特征中选择其中的一些来形成强分类器。

【讨论】:

  • 我的问题是,提供足够大的数据集,在所有位置上测试单个原始特征将花费大量时间。此外,还有许多可以尝试的原创功能,而不仅仅是提到的 4 Viola 和 Jones。所以我想知道如何选择这些原始特征或算法如何做到这一点(如果有的话)。之后可以使用 AdaBoost 进一步减少特征量,但是如何获得初始集呢?
【解决方案2】:

我想,你对 Viola/Jones 的 original work 这个话题很熟悉。

您首先手动选择特征类型(例如矩形 A)。这为您提供了一个掩码,您可以使用它来训练您的弱分类器。为了避免逐个像素地移动掩码和重新训练(这将花费大量时间并且不会提高准确性),您可以指定每个训练的弱分类器在 x 和 y 方向上移动多少。跳跃的大小取决于您的数据大小。目标是让面罩能够移入和移出检测到的对象。特征的大小也可以是可变的。

使用各自的特征(即掩码位置)训练多个分类器后,您可以像往常一样继续进行 AdaBoost 和 Cascade 训练。

特征/弱分类器的数量在很大程度上取决于您的数据和实验设置(即您使用的分类器类型)。您需要可扩展地测试参数,以了解哪种类型的功能效果最好(矩形/圆形/类似俄罗斯方块的对象等)。我在 2 年前研究过这个,我们花了很长时间来评估哪些特征和特征生成启发式产生了最好的结果。

如果您想从某个地方开始,只需选取 4 个 Viola/Jones 原始特征中的 1 个,然后训练一个分类器,将其应用到 (0,0)。用 (x,0) 训练下一个分类器。接下来是 (2x,0)....(0,y), (0,2y), (0,4y),.. (x,y), (x, 2y) 等... 看看会发生什么。很可能您会发现使用较少的弱分类器是可以的,即您可以继续增加决定掩码如何滑动的 x/y 步长值。你也可以让面具长大或做其他事情来节省时间。这种“惰性”特征生成起作用的原因是 AdaBoost:只要这些特征使分类器比随机分类器稍微好一点,AdaBoost 就会将这些分类器组合成一个有意义的分类器。

【讨论】:

  • 所以最初的特征集总是手工制作的,没有像“选择至少一个(完整的)小波基”这样的规则?
  • 您的功能池是手工制作的 try&error,并来自 Adaboost 的反馈。我为文本检测所做的(6 年前)是限制几何形状,例如过滤奇数坐标。从这个池中,我使用了所有阶段的所有功能(集成图像使这个便宜)。有关详细信息,请查看我的Master's thesis about text detection (pdf) 中的第 6.1 章。
  • 是的,就像 maxy 所说的那样。在选择特征时,没有可以应用于每个问题和数据的启发式方法。
【解决方案3】:

在我看来这里有点混乱。
即使是接受的答案对我来说似乎也不正确(也许我没有很好地理解它)。 最初的 Viola-Jones 算法,后来的主要改进为 Lienhart-Maydt 算法,以及 Opencv 的实现,它们都依次评估了特征集的每一个特征。
您可以查看 Opencv 的 source code(以及您喜欢的任何实现)。
在函数 void CvHaarEvaluator::generateFeatures() 结束时,您有 numFeatures,对于 BASIC 模式和大小为 24x24,它仅为 162,336。
当所有的特征集以featureEvaluator(source)的形式提供时,依次检查所有这些:

bool isStageTrained = tempStage->train( (CvFeatureEvaluator*)featureEvaluator, curNumSamples,
  _precalcValBufSize, _precalcIdxBufSize, *((CvCascadeBoostParams*)stageParams) );

每个弱分类器都是通过检查每个特征并选择在该点产生最佳结果的特征来构建的(在决策树的情况下,过程类似)。
在这个选择之后,样本的权重会相应地改变,以便在下一轮从所有特征集中再次选择一个不同的特征。 单个特征评估的计算成本很低,但乘以 numFeatures 可能要求很高。
一个级联的整个训练可能需要数周时间,但瓶颈不是特征评估过程,而是最新阶段的负样本收集。
从您提供的维基百科链接中,我读到:

在一个标准的 24x24 像素子窗口中,总共有 M=162,336 可能的功能,并且评估成本过高 测试图像时全部使用它们。

不要被这个误导,这意味着在经过长时间的训练之后,您的检测算法应该非常快,并且只需要检查很少的特征(只是在训练期间选择的特征)。

【讨论】:

  • 是的,样本集中的每一个特征都由 Viola-Jones 考虑,并(通过 ada boost)选择构建一个级联分类器。我的问题是关于这些功能的第一个样本集。这是因为理论上可能的特征集是完全成熟的哈尔小波基础加上这些的所有可能的线性组合(因为特征可能是冗余的)。构造它是不平凡的,在这个空间中搜索也是如此。所以我想知道它是如何在应用程序中完成的。
  • “这些特征的第一个样本集”这个词没有意义。理论上可能的特征集不是特征的组合,而只是特征本身,一个一个。在训练阶段它不被认为是特征的组合,而只是最终的结果是特征的组合。 Adaboost 的优势在于它允许您仅通过考虑孤立的特征来探索特征空间。
  • 它的工作原理是这样的:您通过逐一检查(而不是它们的组合)来搜索产生最佳结果的单个特征。一旦找到它(并计算与之关联的弱分类器的系数),就保留它。然后修改样本的权重并重复该过程。最后,您将获得一组特征及其系数,这些特征构成了您的分类器(实际上只是 Viola-Jones 的一个阶段)。没有一组初始功能。任何地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-14
  • 2014-07-30
  • 2015-06-26
  • 1970-01-01
  • 2011-01-04
  • 2016-12-30
  • 1970-01-01
相关资源
最近更新 更多