【问题标题】:The best way to calculate the best threshold with P. Viola, M. Jones Framework使用 P. Viola、M. Jones 框架计算最佳阈值的最佳方法
【发布时间】:2012-04-04 08:35:46
【问题描述】:

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

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

我曾尝试使用 OpenCV Train Cascade 模块源作为模板,但它非常全面,以至于对代码进行逆向工程非常耗时。我还编写了自己的简单代码来理解 Adaptive Boosting 的概念。

问题是:你能解释一下计算一个弱分类器的最佳阈值的最佳方法吗?

下面我将展示 AdaBoost 伪代码,它是从 Google 中找到的示例重写的,但我不相信它是否正确。一个弱分类器的计算速度非常慢(几个小时),我特别怀疑计算最佳阈值的方法。

(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

感谢您的帮助

【问题讨论】:

    标签: machine-learning artificial-intelligence computer-vision pattern-recognition viola-jones


    【解决方案1】:

    在 viola-Jones 的原始论文 here,第 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 小时内选择一个弱分类器,就像我之前的(基于网络的)算法!我正在尝试对其进行测试,但这不是一项简单的任务,因为它非常复杂。目前我有两个问题:算法给我的错误等于零,数据集非常小(你认为它正确吗?),我没有一个好主意来快速测试它。
    • 好的。请验证我的想法。对于小特征集,该算法在数值上不稳定。为什么?因为,那么很容易找到具有 100% 正确性的分类器。这一事实意味着分类误差为零,因此 beta 因子也为零,因此无法计算 alpha。因此,避免这种情况的最好也是唯一的一种方法是为算法提供数千个训练样本。例如,一个特征按这样的顺序排列值 - - - - | + + + + + +。 (T+)=6w, (T-)=4w, (S+)=0w, (S-)= 4w.(S+)+((T-)-(S-))=0w,(S-)+( (T+)-(S+))=10w。 Min = 0。我说的对吗?
    • 你是对的!如果一个特征可以正确地将人脸与非人脸分开,那么理想情况下,这就是你的最终分类器!!但这远不是我们想要的。这就是为什么 Viola-Jones 使用了 20000 个精心挑选的训练样本,并针对所有可能的特征(总共 160000 个)对它们进行了训练。实际上这是巨大的,可能需要几个月的微调。我不明白的一件事是你想为实际的人脸检测或训练和检测编写代码。可以在OpenCV中单独训练,通过自己的检测代码运行cascade,会更简单。
    • 使用OpenCV框架当然更简单,但我需要自己编写软件,因为它是我的硕士论文的一部分。 Viola 和 Jones 使用了 200 个弱分类器是序列版本。如果我只需要大约 15 分钟就可以在 20000 个 19x19 px 样本上训练一个弱分类器,那么我认为我只需要大约两天(50 小时)来训练序列 AdaBoost。将来我计划设计一个级联版本并使用遗传算法进行快速特征选择。我希望我能做到。顺便提一句。您可以推荐哪些用于训练的人脸数据库(FERET 除外)?
    • 我自己没试过。但我记得读过MIT-CMU face database 适合正面,sheffield database 适合侧面。您可以关注Naotoshi Seo's blog 进行培训。还要记住,训练数据集不能是您的测试数据集,因此请保留一个公认的数据集以用于测试目的。祝你的项目好运。 :)
    猜你喜欢
    • 2017-10-07
    • 2013-11-14
    • 2013-12-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 2013-11-27
    • 1970-01-01
    相关资源
    最近更新 更多