使用 OpenCV SVM 进行对象检测

Posted

技术标签:

【中文标题】使用 OpenCV SVM 进行对象检测【英文标题】:Object detection with OpenCV SVM 【发布时间】:2015-02-09 03:13:33 【问题描述】:

我无法在互联网上的某个地方找到好的解释。有太多东西,而不是找出该做什么,我变得更加困惑。

我的目标:创建一个使用摄像头实时检测对象的 android 应用程序(我的对象是方向盘和汽车轮胎。)

直到现在我尝试了 haar 分类器,但它很难训练,花费了很多时间并且无法正确训练它,所以我决定寻找另一种方法来实现我的目标。

现在我了解了特征检测器和 SVM 训练。我的问题是:

1:我应该使用哪种算法(SURF、ORB、FREAK 等)?

2:您如何看待 HOG + Bag-Of-Words?

3:如果有的话,你会告诉如何训练 SVM 或提供链接吗? - 我没有找到任何关于这个的教程。我一直在寻找,但我的时间有限,我决定问问。

4:哪种算法会给出最好的结果?

5:我应该使用 Android NDK 以原生方式实现它,还是与 Java 实现不会有如此大的差异?

如果您有任何教程或参考资料,请将它们添加到您的答案或 cmets 中。很抱歉这个问题很长,正如我所说,我的时间有限(这是一个学校项目。)而且我认为如果人们能在一个地方找到这些答案会很好。我会感谢每一个答案,即使它不是一个完整的答案。提前谢谢!

【问题讨论】:

“(我的对象是方向盘和汽车轮胎。)” - 而且,恕我直言,你的主要问题。你能重新谈判吗? (学校问题)。从香蕉中区分苹果将是一个更友好的场景。你知道,“内部类方差”是什么意思吗?您之前的帖子表明,很难找到像“方向盘”这样的东西。即使使用更复杂的算法,它也不会变得更好。 我注意到我完全理解你想告诉我的内容(可能是因为我的英语水平不够好)。不,我不知道内部类方差是什么意思。 另外,我还没有实现我的目标,因为我是第一次使用 OpenCV,而且很难。 【参考方案1】:

1:没有适用于所有情况的最佳算法,但根据应用程序的要求适合某些非常特定情况的算法。

您可以尝试 SIFTSURF,它们是最流行的描述符,但效率不高(慢)并且需要大量内存。 如果效率是您的目标,您可以尝试二进制描述符(例如,BRIEF、ORB、BRISK、FREAK),它们更高效且需要更少的存储空间。看看 FAST 检测器。

2: 用于图像分类问题的词袋是一种识别对象类别的方法,给定一组包含对象类别的正训练图像,以及一组不包含对象类别的负训练图像。 t.

Bag-Of-Words 将为您提供每个训练图像的向量表示

获得此信息后,您必须训练分类器来区分对应于正面(方向盘和汽车轮胎)和负面训练图像的向量。 您可以为此使用 SVM 分类器。

3:您在这里有 OpenCV 2.3 中完整方法(BOW + SVM)的教程。您需要对代码进行一些更改,但总体思路是:http://www.morethantechnical.com/2011/08/25/a-simple-object-classifier-with-bag-of-words-using-opencv-2-3-w-code/

另外,SVM 的 OpenCV 教程: http://docs.opencv.org/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html

4:正如我之前所说,没有完美的算法,所以我无法回答你。我认为在使用 (1.) 中的替代方案进行一些测试后,您将能够回答我们。 :)

5.我认为您应该使用 Android NDK,但我对 Android 开发了解不多。

http://docs.opencv.org/doc/tutorials/introduction/android_binary_package/android_dev_intro.html http://opencv.org/platforms/android.html

【讨论】:

首先感谢您的详细解答!第二个我想问你,BOW + SVM 是实现我的目标的最佳方法还是好的方法? 正如我向您解释的那样,无法告诉您该方法是否能有效解决您的问题。不管怎样,我敢打赌,BOW + SVM 方法会给你带来好的结果。但是您需要尝试确认这一点。 首先,很抱歉我一直在问问题,但事情对我来说并不容易。我发现我不能将 BOW 与二进制描述符一起使用。不幸的是 SIFT 和 SURF 不是免费的,这就是我不想使用它们的原因。我找不到如何训练具有 FAST 提取特征的 SVM。那可能吗?你有这样做的参考吗?非常感谢您。 (也许如果您对这些问题有答案,最好将它们添加到您的答案中) 实际上你可以使用带有二进制描述符的 BOW。我的建议是首先使用 SIFT 或 SURF 尝试这种方法。如果结果不错,那么您可以尝试使用二进制描述符。正如我所说,FAST 只是一个检测器。也就是说,它只检测关键点,然后您需要使用描述符来描述关键点。

以上是关于使用 OpenCV SVM 进行对象检测的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV - 使用 SVM 和 HOG 进行人员检测

基于 HOG 特征的 SVM 分类器用于 OpenCV 中的“对象检测”

Hu矩SVM训练及检测-----OpenCV

学习 opencv---(11)OpenC 边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器

opencv进阶-HOG+SVM行人检测(已训练好的分类器)

opencv进阶-自定义对象检测