问题描述
对于超长问题很抱歉...我必须添加足够的图像来解释我的观点并演示不同的边缘情况
我正在尝试使用Python中的OpenCV检测减速带迹象。这些标志看起来像这样:
(这些只是我从互联网上下载的示例,以下分割轮廓不是这些图像的一部分)
我设法提取了这些标志的内部轮廓,它们看起来像这样:
一些不需要的三角形符号也通过我的三角形检测器:
这些已提取出轮廓如下:
所以我的目的是将提取的轮廓与一些标准图像(我已经保存过)进行比较。为此,我正在OpenCV中使用matchContours
函数。
我正在使用的标准图像,将与所有可能的图像进行比较(左侧有多个凸起,右侧有多个凸起):
我面临的问题是matchContours
的输出是非常可变的,我无法理解。与上面显示的标准之一(右)相比,以下水平堆叠图像描述了目标轮廓(左),左下角的值描述了以下代码的输出:
def compare_rois(standard,image):
cnt1,_ = cv2.findContours(standard,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
cnt2,_ = cv2.findContours(image,cv2.CHAIN_APPROX_NONE)
biggest1 = sorted(cnt1,key=cv2.contourArea,reverse=True)[0]
biggest2 = sorted(cnt2,reverse=True)[0]
return cv2.matchShapes(biggest1,biggest2,cv2.CONTOURS_MATCH_I1,0.0)
compare_rois(single_bump_template_inverted,image)
compare_rois(multiple_bumps_template_inverted,image)
# not displaying the stacking and adding text
从以上图像中,我可以说这些值(两次比较中的最小值)应该在0 and 1.6
之间,以便分类为“检测到减速带” ...
但是以下图像与该观察结果相矛盾。有时,错误检测到的斑点的值落在该范围内,而其他时候实际的“真实”检测值不在此范围内,更糟糕的是所有被认为与颠簸差异很大的形状也进入了范围(以“箭头”表示)或“ e”):
为什么会这样?请注意,ROI图像具有所有不同的形状...有些很小,有些很大... matchShapes
应该与物体的形状无关,并且应该能够检测到该形状尽管如此,atleast that is this site says。
如前所述,所有7个Hu矩在平移(沿x或y方向移动),缩放和旋转下都是不变的。
所以我的问题是:如何确保我从matchShapes
获得的返回值在正确的范围内?我可以对输入图像进行任何转换,以更好地“帮助” matchShapes
“看到”差异吗?
此SO question与我的相似,下面的两个注释似乎表明可能需要进行一些转换...
matchShapes()使用Hu不变量;旋转/平移/比例不变的形状的描述。即使您的结果看起来很怪异,现实情况是硬币的形状非常椭圆形,比衬衫还大,这意味着如果将它们炸成相同的大小,硬币的椭圆形会具有更大的“质量”(面积)比衬衫离中心更远。嗯,这件衬衫的matchShapes()更相似
解决了这个问题,只是做了一个扩展轮廓以具有正方形边界框的功能,以便以一定角度观看的硬币会面朝上出现。这可能适用于更复杂的形状...
我不确定OP在这种情况下做了什么,天气是否对我的情况有帮助,所以我问了这个问题。
我应该尝试使用其他两种已实现的方法吗? CONTOURS_MATCH_I2
和CONTOURS_MATCH_I3
?它们到底有什么不同? official documentation只能说这么多:
您可以从here下载整个数据集。并在与解压缩后的“数据集”文件夹相同的工作目录中运行以下代码:
import os
import cv2
dataset = "dataset"
folders = os.listdir(dataset)
folders.remove("standard")
single = cv2.imread(os.path.join(dataset,"standard","single.jpg"),0)
multiple = cv2.imread(os.path.join(dataset,"multiple.jpg"),0)
def compare_rois(roi,standard):
cnt1,_ = cv2.findContours(roi,0.0)
for folder in folders:
path_to_folder = os.path.join(dataset,folder)
roi = cv2.imread(os.path.join(path_to_folder,"image.jpg"),0)
ret1 = compare_rois(roi,single)
ret2 = compare_rois(roi,multiple)
single_resized = cv2.resize(single,roi.shape[::-1],interpolation = cv2.INTER_NEAREST)
multiple_resized = cv2.resize(multiple,interpolation = cv2.INTER_NEAREST)
stacked1 = np.hstack((roi,single_resized))
stacked2 = np.hstack((roi,multiple_resized))
h,w = stacked1.shape[:2]
cv2.putText(stacked1,"{:3f}".format(ret1),(10,h - h//w - 10),0.5,(255,255,255),1)
h,w = stacked2.shape[:2]
cv2.putText(stacked2,"{:3f}".format(ret2),1)
cv2.imshow("roi",roi)
cv2.imshow("compared with single",stacked1)
cv2.imshow("compared with multiple",stacked2)
if cv2.waitKey(0) == ord('q'):
cv2.destroyAllWindows()
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)