opencv距離變換函式distanceTransform

阳光天气發表於2024-04-30

當影像內的各個子圖沒有連線時,可以直接使用形態學的腐蝕操作確定前景物件,但是如果影像內的子圖連線在一起時,就很難確定前景物件了。此時,藉助於距離變換函式
cv2.distanceTransform()可以方便地將前景物件提取出來。

距離變換函式 cv2.distanceTransform()計算二值影像內任意點到最近背景點的距離。一般情況下,該函式計算的是影像內非零值畫素點到最近的零值畫素點的距離,即計算二值影像中所有畫素點距離其最近的值為 0 的畫素點的距離。當然,如果畫素點本身的值為 0,則這個距離也為 0。

距離變換函式 cv2.distanceTransform()的計算結果反映了各個畫素與背景(值為0的畫素點)
的距離關係。通常情況下:

如果前景物件的中心(質心)距離值為 0 的畫素點距離較遠,會得到一個較大的值。
如果前景物件的邊緣距離值為 0 的畫素點較近,會得到一個較小的值。
如果對上述計算結果進行閾值化,就可以得到影像內子圖的中心、骨架等資訊。距離變換函式 cv2.distanceTransform()可以用於計算物件的中心,還能細化輪廓、獲取影像前景等,有多種功能。
距離變換函式 cv2.distanceTransform()的語法格式為:
dst=cv2.distanceTransform(src, distanceType, maskSize[, dstType]])
src 是 8 位單通道的二值影像。
distanceType 為距離型別引數,其具體值和含義如表 17-1 所示。


maskSize 為掩模的尺寸,其可能的值如表 17-2 所示。需要注意,當 distanceType =cv2.DIST_L1 或 cv2.DIST_C 時,maskSize 強制為 3(因為設定為 3 和設定為 5 及更大值沒有什麼區別)。

dstType 為目標影像的型別,預設值為 CV_32F。
dst 表示計算得到的目標影像,可以是 8 位或 32 位浮點數,尺寸和 src 相同。
示例:使用距離變換函式 cv2.distanceTransform(),計算一幅影像的確定前景,並觀察效果。

點選檢視程式碼
img = cv2.imread('D:\pic\coin.png',cv2.IMREAD_UNCHANGED)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
ishow=img.copy()
#對影像閾值化處理,得到二值影像,黑色背景,白色前景,前景為我們要提取的目標,背景為0,前景為1
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#定義一個3*3的卷積核,卷積核的作用是將前景與背景分離
kernel = np.ones((3,3),np.uint8)
#對二值影像進行開運算,去除噪聲,開運算是先腐蝕再膨脹的過程,它可以去除小的干擾塊,平滑較大的物件邊界,同時並不明顯改變其面積
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
#距離變換,得到每一個前景畫素點到最近的背景畫素點的距離,然後對其進行閾值化處理,得到的結果就是前景
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
#對膨脹後的影像進行閾值化處理,得到前景,前景為我們要提取的目標,背景為0,前景為1,這樣就得到了我們要提取的目標,但是目標並不連續
ret, fore = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)

plt.subplot(131)
plt.imshow(ishow)
plt.axis('off')
plt.subplot(132)
plt.imshow(dist_transform)
plt.axis('off')
plt.subplot(133)
plt.imshow(fore)
plt.axis('off')
plt.show()

結果如下:

相關文章