【问题标题】:Find lines in shape在形状中查找线条
【发布时间】:2015-09-22 03:07:12
【问题描述】:

我有一个二进制图像,我正在寻找一种可靠的方法来查找形状和拓扑中的线条(线条如何连接)。

我在 matlab 中进行过实验(尽管我要求的是使用哪些方法)。

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

谁能告诉我这里使用哪些方法(以及以什么顺序)。

Binary file for testing

【问题讨论】:

  • 骨架化 + 使用 num_neighrbours != 2 查找像素(参考图像中的 green / 1 个邻居)应该为您提供连接点。您可以上传没有B 的黑白格式的图像进行测试吗?
  • 我将图像上传为 .mat 文件,请参阅编辑后的帖子。不是图像上的那个,而是我希望采用这种方法的那个。感谢您的回复!
  • 第二张图片是你试图从第一张图片中实现的吗?您能否详细说明一下您在使用霍夫变换时遇到了什么问题?

标签: computer-vision hough-transform


【解决方案1】:

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

前段时间我解决了类似的任务,并且看起来确实像我非常基本的本土解决方案一样,您的初始示例很容易追踪:

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

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

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

  • 骨架化可能会破坏初始几何图形
  • 对骨架的进一步分析似乎有点棘手和不可靠
  • 通过提高质量,您的图像可以通过更简单的方法进行跟踪

顺便说一句,在我的方法中,不同的操作可以并行执行。扫描步长可调,即使扫描次数减少,效果也很好:

步数越多,交叉点越准确:

我得出结论,使用初始图像提供的所有信息非常重要。所有的简化等都会消除有价值的facts,从而增加任务的整体复杂性。

更新

如果图形没有大部分的垂直和水平线,这种方法会起作用吗?

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

很容易看出,在形状的开头和结尾处垂直线引入了一些重大错误。非常直接的优化给了我们更好的结果:

【讨论】:

  • 干得好,感谢分享。最终结果看起来非常有希望。但是,如果图形没有大部分垂直和水平线,这种方法是否可行?
【解决方案2】:

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

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

还好有人在python这里分享了一个不错的尝试:http://planet.lengrand.fr/?post_id=267

(这显然假设一个完整的 python 安装 NetworkX 和任何其他依赖项。我在 Mac 上通过一些调用(例如 > brew install opencv; pip install networkx; brew install graph-tool; brew install graphviz)使用自制软件完成了此操作。下面的 ipython 笔记本也使用了 http://scikit-image.orghttp://mahotas.readthedocs.org/en/latest/ -如此令人兴奋的计算机视觉和图像处理代码鸡尾酒!最后:你当然需要安装 ipython...)

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

%run C8Skeleton_to_graph-01.ipynb

import scipy.io as sio # Need this to load matlab files...

mat = sio.loadmat('bw.mat')

img = np.zeros((30,70),np.uint8) # Buffered image border

img[5:25,5:65] = mat['BW'] # Insert matrix data into middle

skeleton = mh.thin(img) # Do skeletonization... 

graph = nx.MultiGraph() # Graph we’ll create

C8_Skeleton_To_Graph_01(graph, skeleton) # Do it!

figure(1)
subplot(211)
plt.imshow(img,plt.get_cmap('gray'), vmin=0, vmax=1, origin='upper');
subplot(212)
plt.imshow(skeleton,plt.get_cmap('gray'), vmin=0, vmax=1, origin='upper');

figure(2)
nx.draw(graph)

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

结果如下图:

请注意图形拓扑和布局与细化图像的结构相对应 - 包括最后创建的“马刺”。这是一个持续存在的问题/研究领域,采用这种方法......

编辑: 但可以通过移除图中的杂散弧(导致度数==1 的叶节点)来解决。例如

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

graph.remove_nodes_from(remove)

nx.draw(graph)

【讨论】:

  • 你不认为骨架化会删除非常有价值的信息吗?
猜你喜欢
  • 2017-02-06
  • 2018-08-30
  • 2012-12-04
  • 2015-08-20
  • 1970-01-01
  • 2016-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多