OpenCV for Python之分水嶺算法

Opencv4 官方文檔 : https://docs.opencv.org/4.2.0/
Opencv4 for Python中文文檔點擊下載:OpenCV4 for Python 中文文檔

1 分水嶺算法

  任何灰度圖像都可以看作是一個地形表面,其中高強度表示山峯,低強度表示山谷。你開始用不同顏色的水(標籤)填充每個孤立的山谷(局部最小值)。隨着水位的上升,根據附近的山峯(坡度),來自不同山谷的水明顯會開始合併,顏色也不同。爲了避免這種情況,你要在水融合的地方建造屏障。你繼續填滿水,建造障礙,直到所有的山峯都在水下。然後你創建的屏障將返回你的分割結果。這就是Watershed背後的“思想”。你可以訪問Watershed的CMM網頁,瞭解它與一些動畫的幫助。但是這種方法會由於圖像中的噪聲或其他不規則性而產生過度分割的結果。因此OpenCV實現了一個基於標記的分水嶺算法,你可以指定哪些是要合併的山谷點,哪些不是。這是一個交互式的圖像分割。我們所做的是給我們知道的對象賦予不同的標籤。用一種顏色(或強度)標記我們確定爲前景或對象的區域,用另一種顏色標記我們確定爲背景或非對象的區域,最後用 0 標記我們不確定的區域。這是我們的標記。然後應用分水嶺算法。然後我們的標記將使用我們給出的標籤進行更新,對象的邊界值將爲 -1 。

2 算法流程

輸入圖像->灰度->二值->距離變換->尋找種子->生成marker->分水嶺變換->輸出圖像

3 相關api

cv.watershed(image, markers)

4 算法實現

先將圖片二值化:

blurred = cv.pyrMeanShiftFiltering(image, 10, 100)
    gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    cv.imshow("binary", binary)

在這裏插入圖片描述
圖像膨脹操作,確定背景區域

kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
    opening = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel=kernel, iterations=2)
    sure_bg = cv.dilate(opening, kernel, iterations=3)
    cv.imshow("morphology operation", sure_bg)

在這裏插入圖片描述
尋找前景區域:

dist_transform = cv.distanceTransform(opening, 1,5)
    dist_output = cv.normalize(dist_transform,0,1.0,cv.NORM_MINMAX)
    cv.imshow("distanct-t",dist_output*50)
    ret, surface = cv.threshold(dist_transform, 0.6*dist_transform.max(), 255, 0)
    cv.imshow('surface-bin',surface)

在這裏插入圖片描述
在這裏插入圖片描述
尋找未知區域

sure_fg = np.uint8(surface)
unknown = cv.subtract(sure_bg,sure_fg) #聯通區域
ret, markers1 =cv.connectedComponents(sure_fg)
print(ret)

類別標記

 markers = markers1 + 1
markers[unknown==255] = 0
markers3 = cv.watershed(image, markers=markers)
image[markers3 == -1] =[0, 0, 255]
cv.imshow("result", image)

result:
在這裏插入圖片描述

轉載請註明轉自:https://leejason.blog.csdn.net/article/details/106450380

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章