計算機視覺 - 影像分割



什麼是影像分割?

影像分割是將影像分割成多個片段的過程,以使影像更容易分析。每個片段或區域通常對應於不同的物體或物體的一部分。

透過分割影像,我們可以專注於特定區域,從而更容易識別和分析影像中的物體。

影像分割的重要性

影像分割對於計算機視覺中的各種應用非常重要,例如:

  • 目標檢測:識別和定點陣圖像中的物體。
  • 醫學影像:分析醫學影像以檢測和診斷疾病。
  • 自動駕駛:透過識別道路、車輛、行人等來理解周圍環境。
  • 影像編輯:選擇和操作影像的特定部分。

影像分割型別

影像分割有多種型別,它們是:

  • 閾值分割
  • 基於邊緣的分割
  • 基於區域的分割
  • 基於聚類的分割
  • 基於深度學習的分割

閾值分割

閾值分割是最簡單的分割技術之一。它透過設定閾值將灰度影像轉換為二值影像。

強度值高於閾值的畫素被分配一個值(例如,白色),而低於閾值的畫素被分配另一個值(例如,黑色)。

我們可以使用以下方法應用閾值分割:

  • 全域性閾值:對整幅影像使用單個閾值。
  • import cv2
    
    # Load image in grayscale
    image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
    _, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)
    
  • 自適應閾值:對影像的不同區域使用不同的閾值。
  • adaptive_binary_image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
    

基於邊緣的分割

基於邊緣的分割檢測影像中的邊緣,並使用它們來定義片段的邊界。此方法依賴於檢測強度值的顯著變化。

常用的邊緣檢測方法是Canny 邊緣檢測器。它是一種多階段演算法,可以檢測各種邊緣。

edges = cv2.Canny(image, 100, 200)

基於區域的分割

基於區域的分割根據預定義的標準(例如強度值或紋理)將畫素分組到區域中。其思想是將具有相似屬性的相鄰畫素分組到同一區域。

常見的基於區域的方法如下所示:

  • 區域生長:從種子點開始,透過新增滿足某些條件的相鄰畫素來增長區域。
  • 分水嶺演算法:將影像視為地形表面,並找到分水嶺線來分割區域。

以下是如何應用基於區域的分割的示例:

# Apply Watershed Algorithm
import numpy as np

# Convert image to binary
_, binary_image = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# Perform distance transform
distance_transform = cv2.distanceTransform(binary_image, cv2.DIST_L2, 5)
_, foreground = cv2.threshold(distance_transform, 0.7 * distance_transform.max(), 255, 0)
foreground = np.uint8(foreground)
unknown = cv2.subtract(binary_image, foreground)
# Marker labeling
_, markers = cv2.connectedComponents(foreground)
markers = markers + 1
markers[unknown == 255] = 0
# Apply watershed
markers = cv2.watershed(image, markers)
image[markers == -1] = [255, 0, 0]

基於聚類的分割

基於聚類的分割根據畫素的相似性將畫素分組到聚類中。K均值聚類是此類分割的常用方法。

以下是如何應用 K 均值聚類的示例:

import numpy as np

# Convert image to float32
image = np.float32(image)
# Define criteria and apply K-means
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
_, labels, centers = cv2.kmeans(image, 3, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
# Convert back to uint8 and reshape the image
centers = np.uint8(centers)
segmented_image = centers[labels.flatten()]
segmented_image = segmented_image.reshape((image.shape))

基於深度學習的分割

基於深度學習的分割使用卷積神經網路 (CNN) 來分割影像。此方法非常準確,可以處理複雜的影像。

以下是常見的深度學習模型:

  • 全卷積網路 (FCN):用卷積層替換全連線層以生成分割圖。
  • U-Net:一種流行的生物醫學影像分割模型,使用編碼器-解碼器架構。

以下是如何應用基於深度學習的分割的示例:

from keras.models import Model
from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, concatenate

inputs = Input((image_height, image_width, 1))
conv1 = Conv2D(64, 3, activation='relu', padding='same')(inputs)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
conv2 = Conv2D(128, 3, activation='relu', padding='same')(pool1)
up1 = concatenate([UpSampling2D(size=(2, 2))(conv2), conv1], axis=3)
conv3 = Conv2D(64, 3, activation='relu', padding='same')(up1)
outputs = Conv2D(1, 1, activation='sigmoid')(conv3)
model = Model(inputs=[inputs], outputs=[outputs])
廣告