使用P. Viola和M. Jones框架计算最佳阈值的最佳方法

10

我正在尝试用C++实现P. Viola和M. Jones的检测框架(一开始只是序列分类器-非级联版本)。我认为我设计了所有必需的类和模块(例如积分图像、Haar特征),除了一个最重要的算法:AdaBoost核心算法。

我读过P. Viola和M. Jones的原始论文以及许多其他出版物。不幸的是,我仍然不明白如何找到一个弱分类器的最佳阈值?我只找到了有关“加权中位数”和“高斯分布”算法的小参考和许多数学公式...

我尝试使用OpenCV Train Cascade模块源代码作为模板,但它非常全面,反向工程代码非常耗时。我还编写了自己简单的代码来理解自适应增强的思想。

问题是:您能否向我解释计算一个弱分类器的最佳阈值的最佳方法是什么?

下面我呈现了从Google找到的样本中重新编写的AdaBoost伪代码,但我并不确定这是否是正确的方法。计算一个弱分类器非常慢(几个小时),我对计算最佳阈值的方法有疑虑。

(1) AdaBoost::FindNewWeakClassifier
(2) AdaBoost::CalculateFeatures
(3) AdaBoost::FindBestThreshold
(4) AdaBoost::FindFeatureError
(5) AdaBoost::NormalizeWeights
(6) AdaBoost::FindLowestError
(7) AdaBoost::ClassifyExamples
(8) AdaBoost::UpdateWeights

DESCRIPTION (1)
-Generates all possible arrangement of features in detection window and put to the vector
DO IN LOOP
    -Runs main calculating function (2)
END

DESCRIPTION(2)
-Normalizes weights (5)
DO FOR EACH HAAR FEATURE
    -Puts sequentially next feature from list on all integral images
    -Finds the best threshold for each feature (3)
    -Finds the error for each the best feature in current iteration (4)
    -Saves errors for each the best feature in current iteration in array
    -Saves threshold for each the best feature in current iteration in array
    -Saves the threshold sign for each the best feature in current iteration in array
END LOOP
-Finds for classifier index with the lowest error selected by above loop (6)
-Gets the value of error from the best feature
-Calculates the value of the best feature in the all integral images (7)
-Updates weights (8)
-Adds new, weak classifier to vector

DESCRIPTION (3)
-Calculates an error for each feature threshold on positives integral images - seperate for "+" and "-" sign (4)
-Returns threshold and sign of the feature with the lowest error

DESCRIPTION(4)
- Returns feature error for all samples, by calculating inequality f(x) * sign < sign * threshold

DESCRIPTION (5)
-Ensures that samples weights are probability distribution

DESCRIPTION (6)
-Finds the classifier with the lowest error

DESCRIPTION (7)
-Calculates a value of the best features at all integral images
-Counts false positives number and false negatives number

DESCRIPTION (8)
-Corrects weights, depending on classification results

感谢任何帮助。

1个回答

16

在原始的Viola-Jones论文(这里),第3.1节“学习讨论”(准确地说是第4段)中介绍了找到最佳阈值的过程。

我将快速总结该方法如下。


每个特征的最佳阈值依赖于样本权重,因此在adaboost的每次迭代中都会进行计算。最佳弱分类器的阈值会按照伪代码中所述保存。

在每一轮中,对于每个弱分类器,必须根据特征值排列N个训练样本。设置一个阈值可以将此序列分成两部分。这两部分都将有大多数正面或负面样本以及其他类型的少量样本。

  • T+: 正样本权重的总和
  • T-: 负样本权重的总和
  • S+: 阈值以下正样本权重的总和
  • S-: 阈值以下负样本权重的总和

特定阈值的错误为 -

e = MIN((S+) + (T-) - (S-), (S-) + (T+) - (S+))

为什么是最小值?这里有一个例子:
如果样本和阈值如下 -

+ + + + + - - | + + - - - - -

在第一轮中,如果所有权重都相等(=w),那么取最小值将会给出错误值4*w,而不是10*w

您需要对所有N种可能的分样本方式计算此错误。
最小误差将给出阈值范围值。实际阈值可能是相邻特征值的平均值(我不确定,需进行一些研究)。
这是您DO FOR EACH HAAR FEATURE循环的第二步。
与OpenCV一起提供的级联是由Rainer Lienhart创建的,我不知道他使用了什么方法。 您可以紧密跟随OpenCV源代码,以获得此过程的任何进一步改进。


谢谢。我读了原始论文的另一个版本,其中“学习讨论”章节不完整。根据您的建议和原始文本,我实现了完全新的算法版本。它可以在16分钟内选择一个弱分类器,而不是像我之前(基于网络)的算法需要10个小时!我正在尝试测试它,但这不是一项简单的任务,因为它非常复杂。目前我有两个问题:算法在非常小的数据集上给我一个等于零的错误(您认为这正确吗?),我没有一个好的想法来快速测试它。 - Viper
好的。请验证我的想法。对于小特征集,该算法在数值上是不稳定的。为什么?因为简单地说,可以找到一个分类器,其正确率达到100%。这个事实意味着分类误差为零,因此beta因子也为零,无法计算alpha。因此,避免这种情况的最佳且唯一的方法是使用数千个训练样本来提供算法。例如,一个特征将值排列如下——| +++++。 (T +)= 6w,(T-)= 4w,(S +)= 0w,(S-)= 4w。 (S +)+((T-)-(S-))= 0w,(S-)+((T +)-(S +))= 10w。最小值= 0。我说得对吗? - Viper
1
我自己没有试过。但是我记得读过 MIT-CMU面部数据库 对于正面人脸很好,而谢菲尔德数据库 则对于侧面人脸很好。 您可以按照 Naotoshi Seo的博客 中的训练程序进行操作。此外请注意,训练数据集不能是测试数据集,因此请保留一个公认的数据集进行测试。祝您的项目成功 :) - nac
如果对于每个特征,您都必须计算每个样本的所有值并对其进行排序,那么您如何拥有足够的内存来处理所有这些数据呢?如果您有160,000个特征,假设只有3000个样本,那么总共就有将近50亿个值,而在adaboost中我在继续之前就已经耗尽了内存。 - robev
@robev 1.78GB会让你的内存耗尽? - user334856
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接