OpenCV Python 中使用分水嶺演算法進行影像分割


作為充滿激情的計算機視覺愛好者和 Python 程式設計師,我們一直被 OpenCV 庫的強大功能所吸引。尤其讓我們著迷的一種技術是影像分割,即把影像分割成不同區域的過程。本文將分享我們在使用 OpenCV Python 和分水嶺演算法進行影像分割方面的歷程和見解。透過利用物理景觀中水流的概念,分水嶺演算法已成為準確識別邊界和分離影像中物體的強大工具。我們將一起深入探討一步一步的過程,從預處理影像到應用分水嶺演算法,同時展示示例和輸出結果。加入我們,一起揭開使用 OpenCV Python 和分水嶺演算法進行影像分割的奧秘。

步驟 1:匯入庫和載入影像

首先,我們匯入兩個必要的庫:OpenCV 和 NumPy。OpenCV 廣泛用於影像處理,而 NumPy 以其在 Python 中的數值計算能力而聞名。有了這些強大的工具,我們進入下一步:載入我們要分割的影像。這是一個示例程式碼

import cv2
import numpy as np

# Load the image
image = cv2.imread('image.jpg')

步驟 2:影像預處理

現在,我們使用 OpenCV 庫中的 cv2.cvtColor() 函式將載入的影像轉換為灰度影像。此轉換透過以灰度顯示影像來簡化影像,使其更容易分析和處理。以下是將影像轉換為灰度的示例

# Convert the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

在上面的程式碼中,“image”指的是我們要分割的載入影像。cv2.cvtColor() 函式有兩個引數:影像和轉換標誌 cv2.COLOR_BGR2GRAY,它指定從 BGR 顏色空間到灰度空間的轉換。

步驟 3:應用閾值處理

閾值處理是影像分割中的一種關鍵技術,它將灰度影像轉換為二值影像。它在將我們感興趣的物件與背景分離中起著至關重要的作用。在二值影像中,物件由白色畫素表示,而背景由黑色畫素表示。物件和背景之間的這種清晰區分簡化了後續分割過程的步驟。

為了將步驟 2 中獲得的灰度影像應用閾值處理,我們使用 cv2.threshold() 函式。這是一個示例程式碼

# Apply thresholding
ret, threshold = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

步驟 4:使用形態學運算去除噪聲

步驟 4 涉及使用形態學運算去除影像中的噪聲。在影像處理中,噪聲是指會影響影像分析質量和準確性的不需要的隨機變化或不規則性。形態學運算是一組修改影像中物件形狀和結構的運算。然後,我們將執行形態學開運算,它結合了腐蝕運算和膨脹運算。此運算有助於去除噪聲,同時保留影像中物件的整體形狀和大小。

現在,讓我們檢查一下演示如何使用形態學開運算去除噪聲的程式碼片段

# Perform morphological opening to remove noise
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(threshold, cv2.MORPH_OPEN, kernel, iterations=2)

在上面的程式碼中,我們使用 NumPy 定義了一個核心,它是一個 3x3 的全 1 矩陣。核心決定了在形態學運算期間考慮的每個畫素周圍的鄰域。較大的核心尺寸可以幫助去除較大的噪聲或不規則性,但它也可能會使影像模糊。

步驟 5:建立標記影像

在使用分水嶺演算法進行影像分割時,建立標記影像起著至關重要的作用。標記影像用於標記影像中感興趣的區域,這有助於將影像準確地分割成不同的區域。以下程式碼片段演示瞭如何建立標記影像

# Find background region
sure_bg = cv2.dilate(opening, kernel, iterations=3)

# Find foreground region
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)

# Create marker image
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)

步驟 6:應用分水嶺演算法

現在到了激動人心的部分——應用分水嶺演算法進行影像分割。在此步驟中,我們將未知區域標記為零,並使用分水嶺演算法將影像分割成不同的區域。

# Apply Watershed algorithm
ret, markers = cv2.connectedComponents(sure_fg)
markers = markers + 1
markers[unknown == 255] = 0
cv2.watershed(image, markers)

透過執行這些程式碼行,我們有效地應用分水嶺演算法根據標記的區域分割影像,建立一個可以進一步視覺化和分析的分割圖。

步驟 7:視覺化分割後的影像

應用分水嶺演算法進行影像分割後,現在是視覺化分割影像的時候了。此步驟涉及為每個分割區域分配不同的顏色並將其與原始影像混合。

這是一個示例程式碼

# Apply colormap to the markers
colored_markers = np.zeros_like(image)
colored_markers[markers == -1] = [255, 0, 0]  # Boundaries in blue color

# Display the segmented image
segmented_image = cv2.addWeighted(image, 0.7, colored_markers, 0.3, 0)
cv2.imshow("Segmented Image", segmented_image)
cv2.waitKey(0)

最後,我們使用 cv2.imshow() 顯示分割後的影像,而 cv2.waitKey(0) 用於等待按鍵。現在可以檢視分割後的影像,並檢查分水嶺演算法的結果。

結論

總之,在 OpenCV Python 中使用分水嶺演算法進行影像分割提供了一種強大且通用的方法,可以將影像分割成有意義的區域。透過利用水流的概念並將其與 OpenCV 庫的功能相結合,我們可以準確地識別邊界並分離影像中的物體。

在本文中,我們探討了使用分水嶺演算法進行影像分割的分步過程。從載入影像和預處理影像以提高分割精度開始,我們涵蓋了諸如閾值處理、噪聲去除、建立標記影像以及應用分水嶺演算法本身等重要步驟。透過遵循這些步驟,我們可以獲得可靠且視覺效果良好的影像分割結果。

更新於:2023年7月25日

1K+ 瀏覽量

啟動您的職業生涯

透過完成課程獲得認證

開始學習
廣告
© . All rights reserved.