2013-03-02 78 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