【发布时间】:2017-08-31 06:04:41
【问题描述】:
我正在尝试使用 opencv 在图像中查找交通锥。
代码使用多种方法从图像中裁剪出感兴趣的区域,并找到锥体的精确边界框。 效果很好的方法是按颜色进行分割,然后进行斑点检测,然后使用最近邻分类器来消除误报。
我想使用 Haar Cascades,而不是 blob 检测。这应该意味着区域是基于颜色(HSV 分割)和形状(Haar 级联)进行选择的。
我用过这个教程:http://docs.opencv.org/trunk/dc/d88/tutorial_traincascade.html
我只是在寻找特定类型的交通锥。它们具有已知的尺寸和颜色。所以我为交通锥的形状制作了一个模板。这是我用来生成训练样本的命令、模板和为训练生成的正样本之一(样本以更高分辨率生成,我使用 20x20 像素进行训练):
opencv_createsamples -vec blue.vec -img singles/blue.png -bg bg.txt -num 10000 -maxidev 25 -maxxangle 0.15 -maxyangle 0.15 -maxzangle 0.15 -w 20 -h 20 -bgcolor 0 -bgthresh 1
训练是用这个命令完成的:
opencv_traincascade -data blue_data/ -vec blue.vec -bg bg.txt -numPos 1000 -numNeg 9000 -numStages 10 -numThreads 8 -featureType HAAR -w 20 -h 20 -precalcValBufSize 4096 -precalcIdxBufSize 4096
训练很快结束:
===== TRAINING 3-stage =====
<BEGIN
POS count : consumed 1000 : 1000
NEG count : acceptanceRatio 9000 : 0.00248216
Precalculation time: 18
+----+---------+---------+
| N | HR | FA |
+----+---------+---------+
| 1| 1| 1|
+----+---------+---------+
| 2| 1| 1|
+----+---------+---------+
| 3| 1| 0.199556|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 5 minutes 44 seconds.
===== TRAINING 4-stage =====
<BEGIN
POS count : consumed 1000 : 1000
NEG count : acceptanceRatio 0 : 0
Required leaf false alarm rate achieved. Branch training terminated.
现在我已经将它应用到一张测试图像上,左上角的圆锥是我的模板,印在图像上。
我认为结果看起来不太好。 模板找到了,但是误报很多。 一些误报对我来说看起来很奇怪。 例如:左边有一个圆锥。它有一个明亮的底座和带有黑色条纹的尖端。颜色是黄色和黑色。 这被分类器巧妙地检测到。 但是如何,锥体基本上与模板相反(我没有使用倒色作为训练样本的增强)。
训练结束后,您可以做 3 件事来调整性能:
- 调整输入图像的大小
- 更改
detectMultiScale的比例因子 - 更改
minNeighbors参数。
它们都不适合我。事实上,上面的例子几乎是挑剔的。对于大多数其他设置,检测会发现很多误报,甚至会忽略角落中的模板。
我想仔细观察并从图像中裁剪出一个区域。 已通过以下方式处理:
cone_cascade.detectMultiScale(crop, scaleFactor=1.0001, minNeighbors=0)
我们的想法是确保查看所有比例并保留所有匹配项。
我完全不明白这些结果。
在使用 haar 级联时有什么要记住的吗? 我是不是做错了什么?
【问题讨论】:
-
首先,级联分类器的训练确实不是一件容易的事。看起来您只使用了一张图像并使用
opencv_createsample人为地创建了您的正数据集。最好使用多个真实图像。训练在迭代 4 处停止,这意味着它可以通过 3 个特征快速成功地对 pos 和 neg 数据集进行分类。这通常表明负集不够“难”或 pos 集太“相似”。更多信息here. -
嗯,我知道它们不是旋转不变的。我添加了少量的旋转作为样本创建的增强。我也知道神经网络。从 haar 级联开始的原因纯粹是实用的。我们已经使用了一个 opencv 软件堆栈。这似乎是整合形状检测的最简单方法。我完全同意你的看法:DNN 或者更确切地说 CNN 是此类任务的最先进技术。但是交通锥是如此简单,我本来希望 haar 级联有更好的性能。假的似乎很明显是错误的......
-
不只是负样本的硬度,您还应该使用更多不同的(真实)正样本。是的,收集和裁剪/标记样本需要做很多工作,但是在机器学习中没有免费的午餐……我所知道的最好的是从像你这样的简单分类器开始(或者只是一个不错的颜色分割),在现实世界中使用它并自动裁剪结果检测。然后检查这些结果并收集所有误报+真阳性+找到尽可能多的假阴性和真阴性并将它们添加到您的下一次培训中。
-
5 分钟肯定太快了,使用 HAAR 功能,一个好的培训需要几天时间。使用 LBP 功能,它要快得多(约一天)。在我看来,很少有真实图像(或只有一个)并人工生成具有背景组合的正图像不是要走的路。在这个paper 中,他们使用 4916 个手动标记的图像作为 pos 集和 9500 个图像作为 neg 集。最后,所有工作都是通过创建数据集来完成的。 minHitRate=0.999、maxFalseAlarmRate=0.5、numStages=20 是“默认”值。
标签: python opencv image-processing object-detection haar-classifier