2014-02-13 107 views
2

我有許多從1024x1024顯微鏡圖像的z堆棧中識別出的輪廓對象。每個z步驟包含大約10000-40000個輪廓。等高線平均4個像素。OpenCV/numpy:使用numpy快速比較大量輪廓對象

我所試圖做的是確定哪些輪廓存在於多個z平面(它們相互接觸時,圖像重疊),以及他們的3維區域。我可以完成這個(大約),但代碼是非常緩慢和非常大的內存(我正在打出一個32GB的RAM計算機)。

我目前的做法如下:

  1. 自卸每個輪廓的所有內部點成塊狀列表並進行索引列表,與它一起去。

  2. 做X和喜歡ÿ什麼的二進制比較:

    x_intersections=np.array(np.equal(np.matrix(z1[:,0]).T,z2[:,0])) 
    y_intersections=np.array(np.equal(np.matrix(z1[:,1]).T,z2[:,1])) 
    intersections=x_intersections*y_intersections 
    
  3. 重新編制原始列表來確定它指向跨Z-步驟相匹配。

  4. 確定音量。

我主要對第2步感到好奇,是更快的方法來做到這一點?我嘗試過使用稀疏數組或者使用np.in1d()一次一個地運行每個輪廓,而且看起來沒有更快運行。我已經嘗試過以前使用點比較工具構建的OpenCV,並且它看起來並不快。

此外,有沒有辦法不用拉40000x40000矩陣到RAM(因爲它需要大量的RAM)是否有該款這些列表合理,快捷的方式?有沒有一種聰明的方式來使用numpy來操作數組的一部分而不是一次整個數組?有沒有一種有效的方法來暫時從RAM轉儲到磁盤上?這將允許我在更多的計算機上同時運行它,這大大減少了運行時間。

這是一個問題,將受益於Numba的AutoJIT?還是Blaze?還是pypy?有沒有類似的工具,我不知道這可以在這裏工作?

更廣泛地說,我在這裏做些傻事嗎?我的方法是否構成這個問題的錯誤方法?

我有一些像20的z步驟,3個信道,和100+圖像有時所以即使代碼,每比較需要10秒最終會採取一小時每圖像(約其中我現在有它)。我可以在一些服務器上傳播它,以加速它,但我真的很想盡可能地降低它。

下面是一些Python代碼的大致情況型號:

z1=[] 
i=0 
while i<20000: 
    temp=np.array([[[1,1]],[[1,2]],[[2,1]],[[2,2]]])+np.round(np.random.rand(1,1,2)*1024) 
    z1.append(temp.astype(int)) 
    i+=1 
z2=z1[1:10000] 
i=0 
while i<10000: 
    temp=np.array([[[1,1]],[[1,2]],[[2,1]],[[2,2]]])+np.round(np.random.rand(1,1,2)*1024) 
    z2.append(temp.astype(int)) 
    i+=1 
random.shuffle(z2) 

(我的輪廓是不是所有的長度爲4有些更有些少,但是這應該是足夠接近演示)

然後我由近似代碼轉儲它們作爲數組:

output=(0,0) 
index_list=(0,0) 
for itemsN,items in enumerate(z1): 
    output=np.vstack([output,items.squeeze()]) 
    index_list=np.vstack([index_list,np.ones((len(items),1))*itemsN]) 
output=np.delete(output,0,0) 
index_list=np.delete(index_list,0) 

然後我使用上面列出的碼中步驟2向列表一起投(這是一種緩慢的,是一個MAS的部分sive memory hog,如果運行它可能會導致內存錯誤),並使用索引列表找出屬於一起的輪廓對。

回答

2

下面是一些建議(基於我對你的問題的理解,如果這不是你想要的,請告訴我)。

  1. 要比較兩個輪廓,您可以在OpenCV中使用cv2.matchShapes()函數。
  2. 或者你可以計算所有輪廓的某些特徵,如面積,周長,質心等,然後先比較它們。只有它們匹配,才能比較整個輪廓。兩個具有相同質心和麪積的輪廓最有可能是相同的輪廓,因此您可以將這些輪廓作爲一個整體進行比較,其他可以忽略的輪廓會加快速度。
+1

這個工作我比較質心預先排序列表成較小的子集之前進行逐個像素的比較。謝謝! – Ionox