Computer vision 找出线条的形状

Computer vision 找出线条的形状,computer-vision,hough-transform,Computer Vision,Hough Transform,我有一个二值图像,我正在寻找一种健壮的方法来找到形状和拓扑中的线条(线条如何连接) 我已经在matlab中进行了实验(尽管我要求的是使用哪种方法) 我曾尝试在二值图像上使用骨架化,然后使用hough变换,有时有效,但不是一个可靠的解决方案。我与边界干扰作斗争 有人能告诉我在这里使用哪些方法的方向(以及顺序如何) 这确实是一个棘手的问题,从二进制图像到图形(即拓扑)。基本上涉及从像素和2D图像数据的离散世界到节点和连接的抽象数据结构的交叉 但是,什么能在两者之间提供“粘合剂”?恐怕这是一个相当

我有一个二值图像,我正在寻找一种健壮的方法来找到形状和拓扑中的线条(线条如何连接)

我已经在matlab中进行了实验(尽管我要求的是使用哪种方法)

我曾尝试在二值图像上使用骨架化,然后使用hough变换,有时有效,但不是一个可靠的解决方案。我与边界干扰作斗争

有人能告诉我在这里使用哪些方法的方向(以及顺序如何)


这确实是一个棘手的问题,从二进制图像到图形(即拓扑)。基本上涉及从像素和2D图像数据的离散世界到节点和连接的抽象数据结构的交叉

但是,什么能在两者之间提供“粘合剂”?恐怕这是一个相当开放的问题,需要对视觉数据进行复杂的解释

幸运的是,其他人在python中分享了一个很好的尝试:

(这显然是假设完整的python安装NetworkX和任何其他依赖项。我在Mac上使用homebrew通过一些调用实现了这一点,例如
>brew安装opencv;pip安装NetworkX;brew安装graph tool;brew安装graphviz
。下面的ipython笔记本还使用了和-这是一个相当令人兴奋的计算机视觉混合体。)nd图像处理代码!最后:您当然需要安装ipython…)

下面是一个示例(首先从上面下载的笔记本中加载-全部从以下位置运行:
>ipython-pylab
):

显示最初提供的Matlab数据的骨架化(边缘有缓冲区):

结果显示在下图中:

请注意,图形拓扑和布局与细化图像的结构相对应,包括最后创建的“杂散”。这是一个正在进行的问题/研究领域

编辑:但可以通过删除图中的杂弧(导致叶节点的阶数==1)来解决

remove = [node for node,degree in graph.degree().items() if degree == 1]

graph.remove_nodes_from(remove)

nx.draw(graph)

坦率地说,我一直在关注这个问题,希望找到有用的答案。任务本身似乎并不复杂(我会努力证明这一点),但优雅的解决方案离我还有一段距离

不久前,我解决了类似的任务,它看起来确实像是我自己开发的非常基本的解决方案,您的初始示例很容易跟踪:

这只是一个简单的扫描(1)、垂直和水平线识别(2)以及对更复杂区域的进一步分析(3)。对所有区域进行分析(3)并不难找到交点并对其进行优化(4)

结果相当粗略,但它证实了这种方法的可行性

我知道这与Matlab有点相去甚远,但我只想强调几个重要的时刻:

  • 骨架化可能会破坏初始几何体
  • 对骨架的进一步分析似乎有点棘手和不可靠
  • 通过一点增强的质量,您的图像可以用更简单的方法跟踪
顺便说一句,在我的方法中,不同的操作可以并行执行。扫描步骤可以调整,即使扫描次数减少,结果也非常好:

通过更多步骤,可以更精确地识别交点:

我得出的结论是,使用初始图像提供的所有信息非常重要。所有的简化等都将删除有价值的
事实
增加任务的总体复杂性

更新

如果图形没有大部分垂直线和水平线,这种方法是否有效

这些步骤是相当独立的,因此没有严格的要求有垂直或水平线。当然,更复杂的任务是识别交叉点并进行一些额外的调整以提高精度

很容易看出,在形状的开始和结束处,垂直线引入了一些明显的错误。非常简单的优化为我们提供了更好的结果:


骨骼化+使用
num_neighbours!=2查找像素(参考图像中的绿色/1邻居)应该给你连接点。你能在没有
B
的情况下上传B&W格式的图像进行测试吗?我以.mat文件的形式上传了图像,请参阅编辑的帖子。不是图像上的图像,而是我希望使用的方法。谢谢你的回复!第二个图像是你试图从第一个图像中获得的吗?可以吗中止一点hough变换有什么问题?你不认为骨架化会删除非常有价值的信息吗?做得好,谢谢分享。最终结果看起来很有希望。但是,如果图形没有大部分垂直和水平线,这种方法会起作用吗?
remove = [node for node,degree in graph.degree().items() if degree == 1]

graph.remove_nodes_from(remove)

nx.draw(graph)