今天早上我有了这个想法,我发现scikit-image可能可以解决这个问题。简单地说,我想删除等高线光栅图像中的水平标签和其他不必要的特征,并获得等高线的位置。
如下图所示:contour image with features to be removed。
但读了一段时间后,我开始不确定是否可以做到这一点。我的考虑如下:
1) find_contours可能会找到轮廓线,但我认为所有其他特征(箭头和标签)也会包括在内。
2)闭合可能会去掉标签,但我发现轮廓线也被去掉了,我认为这是因为它们只是细线,如果使用闭合函数,明亮的区域将被连接起来。
3)箭头大多与轮廓线相连,因此不能将这些特征视为单独的对象。它们可能是最难移除的部分。
我想要得到帮助的是,是否可以在skimage中删除标签和箭头以获得轮廓线。如果是这样的话,我会继续学习这个包。
发布于 2016-08-18 21:48:07
这是你的问题的部分解决方案。基本思想是将互连线的网络视为一个图,并删除该图的小边,因为它们(主要)对应于箭头和标签。第一步是计算二进制化相位的骨架。

当然,结果并不完美,您可以调整下面脚本的不同参数,以找到您认为最好的解决方案。如果需要在大量图像上重复此分割,还可以尝试手动选择要保留的图形的边作为训练集,并使用机器学习算法对要保留的边进行分类(使用边的特征,如长度、其他连接边的数量、方向、直线度等)。
import numpy as np
import matplotlib.pyplot as plt
from skimage import io, morphology
from scipy import ndimage
def skel_to_graph(skel):
"""
Transform skeleton into its branches and nodes, by counting the number
of neighbors of each pixel in the skeleton
"""
convolve_skel = 3**skel.ndim * ndimage.uniform_filter(skel.astype(np.float))
neighbors = np.copy(skel.astype(np.uint8))
skel = skel.astype(np.bool)
neighbors[skel] = convolve_skel[skel] - 1
edges = morphology.label(np.logical_or(neighbors == 2, neighbors ==1),
background=0)
nodes = morphology.label(np.logical_and(np.not_equal(neighbors, 2),
neighbors > 0), background=0)
length_edges = np.bincount(edges.ravel())
return nodes, edges, length_edges
# Open image and threshold
image = io.imread('contours.png')
im = image < 200
im = morphology.binary_closing(im, np.ones((5, 5)))
# Remove small connected components (small arrows)
only_big = morphology.remove_small_objects(im, 400)
# Skeletonize to get 1-pixel-thick lines
skel = morphology.skeletonize(only_big)
skel_big = morphology.remove_small_objects(skel, 30, connectivity=2)
nodes, edges, length_edges = skel_to_graph(skel_big)
# Keep only long branches of the skeleton
# The threshold can be adjusted
threshold = 35
long_edges = (length_edges < threshold)[edges]
edges[long_edges] = 0
# Visualize results
plt.figure(figsize=(10, 10))
plt.imshow(image, cmap='gray', interpolation='nearest')
plt.contour(edges > 0, [0.5], colors='red', linewidths=[2])
plt.axis('off')
plt.tight_layout()
plt.show()https://stackoverflow.com/questions/38898554
复制相似问题