我需要在从相机检索的图像中找到所有轮廓。因此,我首先使用Canny边缘检测器找到边缘,然后找到轮廓。很简单
但是,我的轮廓被“合并”了。例如,在下面的图像中,我显然有4个不同的对象。边缘在某些点上略有接触,所以我得到一个大轮廓,而不是四个单独的轮廓。我尝试更改阈值,侵蚀,形态学操作和类似操作,但是边缘保持轻微接触。有没有人对如何在类似于以下图像的图像中获得单独的轮廓有任何建议?(下面的图像显然只是一个例子,我的实际图像要复杂得多,但是具有相同的基本问题)。
我需要在从相机检索的图像中找到所有轮廓。因此,我首先使用Canny边缘检测器找到边缘,然后找到轮廓。很简单
但是,我的轮廓被“合并”了。例如,在下面的图像中,我显然有4个不同的对象。边缘在某些点上略有接触,所以我得到一个大轮廓,而不是四个单独的轮廓。我尝试更改阈值,侵蚀,形态学操作和类似操作,但是边缘保持轻微接触。有没有人对如何在类似于以下图像的图像中获得单独的轮廓有任何建议?(下面的图像显然只是一个例子,我的实际图像要复杂得多,但是具有相同的基本问题)。
Answers:
如果要检测不同的组件,则可能有其他方法可以检测轮廓。这是Mathematica中的示例。在检测之前,先进行腐蚀然后再进行扩张,以缩小第二个组件中的间隙(如果不执行此操作,则不会检测到它)。
img = Binarize@Import["http://i.stack.imgur.com/yqDyu.png"];
Colorize[MorphologicalComponents[Dilation[Erosion[img,1],1]]]
下图左图显示了不完美的对象检测(未缩小间隙),右图显示了正确的检测(运行以上代码)。
但是,如果您确实只想分离轮廓,这是一个示例。像以前一样执行腐蚀和膨胀以缩小间隙,然后将所得图像通过Canny边缘检测器。我已经明确了默认选项,以便您可以看到正在使用的内容。
img2 = EdgeDetect[Dilation[Erosion[img, 1], 1], Method -> "Canny"]
这将同时为您提供内侧和外侧边缘(请参见下面左图),因为周围的像素宽度均大于1。由于性能下降,我想让它变薄没有太多运气(对于其他图像可能有所不同)。内部轮廓就是您想要的轮廓,外部轮廓只是所有4个组件的组合轮廓。现在我们需要做的就是删除最外面的一个:
SelectComponents[img2, "EnclosingComponentCount", # > 0 &]
这仅给您内部轮廓(请参阅右下角)。换句话说,它仅拾取那些被至少一个其他轮廓包围的轮廓,这将自动取消最外面的轮廓的资格。我不知道openCV中这些命令/操作的等效性。
请注意,图中的明显中断是由于以较小的尺寸保存到jpeg引起的。它在我的屏幕上看起来不是那样。
这不是您问题的答案,但是轮廓分析容易出错。您对此无能为力,它只能在非常简单的情况下使用。
如果您在使用它时遇到麻烦,则应该寻找一种完全不同的算法。有更复杂,更强大的解决方法,但这取决于您要实现的目标(对象检测,跟踪等)。
轮廓不一定开放,因为您已经使用canny来检测它们。Canny的问题已经在这里讨论了。关于canny 的讨论为您提供了基本的思想,即在canny之上仍需要进行诸如闭合和膨胀之类的操作才能评估闭合轮廓。
这也取决于我们要寻找轮廓还是分割(Canny与Graphcuts之类的方法)。所以我想寻找可靠的解决方案取决于您的最终应用。