2013-03-02 48 views
0

我有用轮廓算法(我正在做天体物理源提取)提取特征的图像。这种方法产生了一个“特征地图”,每个像素都标有一个整数(通常每个地图有大约1000个独特的特征)。基于“标签蒙版”的轮廓

我想将每个单独的特征显示为自己的轮廓。我能做到这一点

一种方法是:

for ii in range(labelmask.max()): 
    contour(labelmask,levels=[ii-0.5]) 

然而,这是非常缓慢的,尤其是对于大型的图像。有更好的(更快)的方法吗?

P.S. 一个小测试显示skimage's find-contours不会更快。

按@ tcaswell的评论,我需要解释为什么contour(labels, levels=np.unique(levels)+0.5))或类似的东西不起作用:

1. Matplotlib spaces each subsequent contour "inward" by a linewidth to avoid overlapping contour lines. This is not the behavior desired for a labelmask. 
2. The lowest-level contours encompass the highest-level contours 
3. As a result of the above, the highest-level contours will be surrounded by a miniature version of whatever colormap you're using and will have extra-thick contours compared to the lowest-level contours. 
+0

我会尝试遮住你手中的图像,轮廓到感兴趣的区域,提取它返回的路径,然后将它们移动到正确的位置。或者在你的面具上使用某种边缘检测。 – tacaswell 2013-03-02 18:18:05

+0

边缘检测如何提供帮助?我认为'面具'图像应该已经尽可能地尖锐......是否有将锐利边缘变成可用作轮廓的点集的例程? – keflavich 2013-03-02 18:19:54

+0

这个问题是相关的和有用的:http://stackoverflow.com/questions/14572933/contours-around-scipy-labeled-regions-in-a-2d-grid(描述'find_contours'和创建'标签'地图我已经有) – keflavich 2013-03-02 18:29:16

回答

1

对不起,我回答我自己...急躁(好运)让我的好。

的关键是使用matplotlib的低级别的C例程:

I = imshow(data) 
E = I.get_extent() 
x,y = np.meshgrid(np.linspace(E[0],E[1],labels.shape[1]), np.linspace(E[2],E[3],labels.shape[0])) 

for ii in np.unique(labels): 
    if ii == 0: continue 
    tracer = matplotlib._cntr.Cntr(x,y,labels*(labels==ii)) 
    T = tracer.trace(0.5) 
    contour_xcoords,contour_ycoords = T[0].T 
    # to plot them: 
    plot(contour_xcoords, contour_ycoords) 

注意labels*(labels==ii)将把每一个标签的轮廓在一个稍微不同的位置;如果要在相邻标签之间重叠轮廓,请将其更改为labels==ii

+0

回答你自己的问题是非常酷的。请记住也接受它。 – tacaswell 2013-03-02 19:16:21

+0

补充说明:如果你想让轮廓不偏移,使用'tracer = matplotlib._cntr.Cntr(x,y,(labels == ii))'代替 – keflavich 2013-03-07 01:12:24

+0

你应该编辑你的答案以包含那个注释,注释不稳定。 – tacaswell 2013-03-07 01:58:51