注意
前往結尾下載完整的範例程式碼。或透過 Binder 在您的瀏覽器中執行此範例
分割和超像素演算法的比較#
此範例比較了四種流行的低階影像分割方法。由於很難獲得良好的分割,而且「良好」的定義通常取決於應用程式,因此這些方法通常用於獲得過度分割,也稱為超像素。然後,這些超像素作為更複雜演算法 (例如條件隨機場 (CRF)) 的基礎。
Felzenszwalb 的高效基於圖形的分割#
此快速 2D 影像分割演算法,在 [1] 中提出,在電腦視覺社群中很受歡迎。該演算法具有單一 scale
參數,該參數會影響區段大小。實際大小和區段數量可能會因局部對比度而異。
Quickshift 影像分割#
Quickshift 是一種相對較新的 2D 影像分割演算法,基於核均值移動的近似值。因此,它屬於局部模式搜尋演算法家族,並應用於由色彩資訊和影像位置組成的 5D 空間 [2]。
Quickshift 的優點之一是它實際上同時計算多個尺度上的階層式分割。
Quickshift 有兩個主要參數:sigma
控制局部密度近似的尺度,max_dist
選擇產生的階層式分割中的一個層級。色彩空間中的距離和影像空間中的距離之間也存在權衡,由 ratio
給出。
Quick shift 和用於模式搜尋的核方法,Vedaldi, A. 和 Soatto, S. European Conference on Computer Vision, 2008
SLIC - 基於 K 平均值的影像分割#
此演算法僅在色彩資訊和影像位置的 5d 空間中執行 K 平均值,因此與 Quickshift 密切相關。由於叢集方法較簡單,因此效率很高。此演算法必須在 Lab 色彩空間中運作才能獲得良好的結果。此演算法很快獲得關注,現在被廣泛使用。請參閱 [3] 以了解詳細資訊。compactness
參數會像 Quickshift 一樣,權衡色彩相似度和鄰近度,而 n_segments
選擇 kmeans 的中心數量。
Radhakrishna Achanta、Appu Shaji、Kevin Smith、Aurelien Lucchi、Pascal Fua 和 Sabine Suesstrunk,與最先進的超像素方法相比的 SLIC 超像素,TPAMI,2012 年 5 月。
梯度影像的緊湊分水嶺分割#
分水嶺不是將彩色影像作為輸入,而是需要灰階梯度影像,其中明亮的像素表示區域之間的邊界。該演算法將影像視為一個地形,其中明亮的像素形成高山峰。然後,從給定的標記中淹沒此地形,直到不同的洪水盆地在山峰處相遇。然後,每個不同的盆地形成不同的影像區段。[4]
與 SLIC 一樣,還有一個額外的緊湊度引數,使得標記更難淹沒遠處的像素。這使得分水嶺區域的形狀更加規則。[5]
https://en.wikipedia.org/wiki/Watershed_%28image_processing%29
Peer Neubert & Peter Protzel (2014)。緊湊分水嶺和搶先 SLIC:關於改善超像素分割演算法的權衡。ICPR 2014,第 996-1001 頁。DOI:10.1109/ICPR.2014.181 https://www.tu-chemnitz.de/etit/proaut/publications/cws_pSLIC_ICPR.pdf

Felzenszwalb number of segments: 194
SLIC number of segments: 196
Quickshift number of segments: 695
Watershed number of segments: 256
import matplotlib.pyplot as plt
import numpy as np
from skimage.data import astronaut
from skimage.color import rgb2gray
from skimage.filters import sobel
from skimage.segmentation import felzenszwalb, slic, quickshift, watershed
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float
img = img_as_float(astronaut()[::2, ::2])
segments_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
segments_slic = slic(img, n_segments=250, compactness=10, sigma=1, start_label=1)
segments_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)
gradient = sobel(rgb2gray(img))
segments_watershed = watershed(gradient, markers=250, compactness=0.001)
print(f'Felzenszwalb number of segments: {len(np.unique(segments_fz))}')
print(f'SLIC number of segments: {len(np.unique(segments_slic))}')
print(f'Quickshift number of segments: {len(np.unique(segments_quick))}')
print(f'Watershed number of segments: {len(np.unique(segments_watershed))}')
fig, ax = plt.subplots(2, 2, figsize=(10, 10), sharex=True, sharey=True)
ax[0, 0].imshow(mark_boundaries(img, segments_fz))
ax[0, 0].set_title("Felzenszwalbs's method")
ax[0, 1].imshow(mark_boundaries(img, segments_slic))
ax[0, 1].set_title('SLIC')
ax[1, 0].imshow(mark_boundaries(img, segments_quick))
ax[1, 0].set_title('Quickshift')
ax[1, 1].imshow(mark_boundaries(img, segments_watershed))
ax[1, 1].set_title('Compact watershed')
for a in ax.ravel():
a.set_axis_off()
plt.tight_layout()
plt.show()
腳本總執行時間: (0 分鐘 3.103 秒)