我想製作一個實時應用程序,它涉及到查找二進制掩碼的邊緣。我需要一些快速的,如果可能的話沒有GPU,運行時希望在每幅圖像0.0005秒以下,大小(1000,1000)。我將使用以下二進制圖像的示例,大小爲(1000,1000)。從Python中的二進制掩碼檢索輪廓掩碼的快速方法
(代碼複製:)
import numpy as np
im=np.zeros((1000,1000),dtype=np.uint8)
im[400:600,400:600]=255
做事快的第一個邏輯方法是使用了OpenCV庫:
import cv2
timeit.timeit(lambda:cv2.Laplacian(im,cv2.CV_8U),number=100)/100
0.0011617112159729003
其預期導致: laplacian
我發現這種方式非常耗時。在此之後,我嘗試了findContours:
def usingcontours(im):
points=np.transpose(cv2.findContours(im,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)[1][0])
tmp=np.zeros_like(im)
tmp[tuple(points)]=255
return tmp
timeit.timeit(lambda:usingcontours(im),number=100)/100
0.0009052801132202148
它給出了與上面相同的結果。 這樣比較好,但還是不如我想。我提出與numpy的使用情況,以近似拉普拉斯採用梯度,作爲最後的手段,雖然我知道這將是更糟:
def usinggradient(im):
tmp=np.gradient(im)
return ((tmp[0]+tmp[1])>0).astype(np.uint8)
timeit.timeit(lambda:usinggradient(im),number=100)/100
0.018681130409240722
那麼,有沒有人對我怎樣才能加快我的算法任何進一步的想法?我強調我希望這個算法用於二進制圖像,所以我想必須有更好的實現。
你可以做一些NumPy和Scipy形態侵蝕和按位操作NumPy。查看'scipy.ndimage.morphology.binary_dilation'和'np.logical_ *'函數。 – YXD
'1000 x 1000/0.0005s = 2 x 10^9像素/秒 - 即每個像素1-2個時鐘週期,甚至可以使用矢量化和並行處理,這些處理工作無需太多工作。 –
@DanMašek2 x 10^9像素/秒錶示按位圖像2x10^9位/秒。假設一個好的程序在一個8核2GHz CPU中使用了所有內核,我認爲每個內核有4個線程,我可以在每個時鐘週期處理32個像素(位),所以64 * 10^9像素/秒= 1000×1000/0.00016s。所以我要求任何現成的實現低於O(3 * n)的複雜度,這在二進制映像中我認爲是可能的。 –