3

我正在编写一个滑动窗口来提取特征并将其输入 CvSVM 的预测函数。但是,我偶然发现 svm.predict 函数相对较慢。

基本上,窗口以固定的步长在图像尺度上滑动穿过图像。

  • 遍历图像加上为每个窗口提取特征的速度大约需要 1000 毫秒(1 秒)。
  • 包含由 adaboost 训练的弱分类器导致大约 1200 毫秒(1.2 秒)
  • 但是,当我将特征(已被弱分类器标记为正)传递给 svm.predict 函数时,整体速度减慢到大约 16000 毫秒(16 秒)
  • 在使用 TBB 的线程传递给 svm.predict 之前,首先尝试收集所有“积极”特征导致 19000 毫秒(19 秒),可能是由于创建线程所需的开销等。

我的 OpenCV 构建被编译为包括 TBB(线程)和 OpenCL(GPU)功能。

有没有人设法加快 OpenCV 的 SVM.predict 功能?

我已经被这个问题困住了很长一段时间,因为通过我的测试数据运行这个检测算法来进行统计和阈值调整是令人沮丧的。

非常感谢您阅读本文!

4

3 回答 3

4

(上面发布的答案是为了正式化我的评论:)

SVM 的预测算法需要 O( nSV * f ) 时间,其中nSV是支持向量的数量,f是特征的数量。支持向量的数量可以通过使用更强的正则化训练来减少,即通过增加超参数C(可能以预测准确性为代价)。

于 2013-04-24T15:01:43.347 回答
2

我不确定您要提取哪些特征,但从特征的大小(3780)来看,我会说您正在提取 HOG。在课堂上有一种非常健壮、优化和快速的 HOG“预测”方式cv::HOGDescriptor。您需要做的就是

  1. 提取你的 HOG 进行训练
  2. 将它们放入 svmLight 格式
  3. 使用 svmLight 线性核训练模型
  4. 计算预测所需的 3780 + 1 维向量
  5. 将向量提供给对象的setSvmDetector()方法cv::HOGDescriptor
  6. 使用detect()detectMultiScale()检测方法

以下文档包含有关如何实现您正在尝试做的事情的非常好的信息:http: //opencv.willowgarage.com/wiki/trainHOG虽然我必须警告您原始程序中存在一个小问题,但它教你如何正确处理这个问题。

于 2013-04-24T12:58:35.577 回答
0

正如 Fred Foo 已经提到的,您必须减少支持向量的数量。根据我的经验,5-10% 的训练基数就足以具有良好的预测水平。

使其工作更快的另一种方法:

  1. 减小特征的大小。3780太贵了。我不确定在您的情况下这种特征大小可以描述什么,但根据我的经验,例如,对汽车标志等图像的描述可以有效地打包成 150-200 大小:
    • PCA 可用于减小特征的大小并降低其“噪声”。有一些例子说明它如何与 SVM 一起使用;
    • 如果没有帮助 - 尝试其他图像描述原则,例如 LBP 和/或 LBP 直方图
  2. LDA(单独或与 SVM 一起使用)也可以使用。
  3. 首先尝试线性 SVM。如果您的集合原则上是线性可分的,那么它的速度要快得多,并且您的特征大小 3780(3780 维)足以在更高维度上具有良好的分离“空间”。如果不够好 - 尝试使用一些非常标准的设置(如 C = 1 和 gamma = 0.1)的 RBF 内核。只有在那之后 - POLY - 最慢的一个。
于 2019-11-10T06:58:52.050 回答