skimage slic:获得相邻的细分

时间:2014-10-07 13:48:22

标签: python scikit-learn

在python sklearn包中的skimage.segmentation包中有一个很好的超分辨率段生成(SLIC)实现。

slic()方法返回整数标签集。我的问题是如何才能获得彼此空间邻居的片段?我想要做的是使用这些段构建图形,边缘将连接直接邻居。但是,我无法弄清楚如何获得一个片段的直接邻居。

执行SLIC的python代码如下:

from skimage import io
from skimage.segmentation import slic
from skimage.segmentation import find_boundaries
# An image of dimensions 300, 300
image = img_as_float(io.imread("image.png"))

# call slic. This returns an numpy array which assigns to every 
# pixel in the image an integer label
# So segments is a numpy array of shape (300, 300)
segments = slic(image, 100, sigma = 5)

# Now I want to know the neighbourhood segment for each super-pixel
# There is a method called find_boundaries which returns a boolean
# for every pixel to show if it is a boundary pixel or not.

b = find_boundaries(segments)

在这里,我被困住了。我想知道如何解析这个边界索引并找出给定的标签索引(比如0),哪个标签索引共享一个带有索引0的标签的边界。有没有办法有效地做到这一点而不通过边界数组循环对于每个标签索引?

2 个答案:

答案 0 :(得分:8)

我这样做的方法是构建一个图形,其中包含从每个像素到其左下像素的边缘(所以是4个邻域),用它们的超像素数标记它们并删除重复项。 您可以在my blog post中找到代码和详细信息。

你可以找到一些相关的函数here,认为它们还没有很好地记录(尚未)。

答案 1 :(得分:0)

一种简单的方法,仅使用HttpClient来摆放每个分段图像像素,而不是右边和下面的像素:

np.unique

slic neighbors using np unique

使用Delaunay细分的另一种方法(且有些不完整):

from skimage.data import astronaut
from skimage.segmentation import slic
from scipy.spatial import Delaunay
from skimage.segmentation import mark_boundaries
from matplotlib.lines import Line2D

img = astronaut().astype(np.float32) / 255.

# SLIC
segments = slic(img, n_segments=500, compactness=20)
segments_ids = np.unique(segments)

# centers
centers = np.array([np.mean(np.nonzero(segments==i),axis=1) for i in segments_ids])

vs_right = np.vstack([segments[:,:-1].ravel(), segments[:,1:].ravel()])
vs_below = np.vstack([segments[:-1,:].ravel(), segments[1:,:].ravel()])
bneighbors = np.unique(np.hstack([vs_right, vs_below]), axis=1)

fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
plt.imshow(mark_boundaries(img, segments))
plt.scatter(centers[:,1],centers[:,0], c='y')

for i in range(bneighbors.shape[1]):
    y0,x0 = centers[bneighbors[0,i]]
    y1,x1 = centers[bneighbors[1,i]]

    l = Line2D([x0,x1],[y0,y1], alpha=0.5)
    ax.add_line(l)

不完整,因为镶嵌将不会产生某些边界邻居。

slic neighbors using tessellation