[scikit-image] 56. Watershedセグメンテーション(skimage.morphology watershed)

python

はじめに

skimage.morphology のwatershedは、画像内の異なるオブジェクトを分離するためのアルゴリズムである。ここでは、watershedアルゴリズムを用いて、重なった円をそれぞれセグメント化した例について説明する。

コード

コードをダウンロード(.pyファイル)コードをダウンロード(.ipynbファイル)

解説

モジュールのインポート

データの生成

3つの円が重なった画像を生成する。
np.indices((60, 60))、によりインデックスを要素として持つ配列を生成する。
mask_circle1 = (x – x1)**2 + (y – y1)**2 < r1**2 により座標(x1, y1)を中心とする半径r1の円の内部がTrue となるbool配列を得る。
np.logical_or(mask_circle1, mask_circle2)により配列を各要素ごとに論理演算する。これにより円が2つ合体した風になる。
同様にして、np.logical_or(image, mask_circle3)で3つの円を合体させる。画像としては以下のようになる。

ndi.distance_transform_edt(image)でimageの背景からの距離を計算する。つまり、各円の中心は黒い部分からの距離が大きいため、要素も大きくなる。

局所的極大値を求める

局所的極大値を求めるskimage.feature peak_local_maxについては下記で解説した。

[scikit-image] 51. 画像の局所的な極大値を検出(skimage.feature peak_local_max)
skimage.featureのpeak_local_maxによる画像中の局所的な極大値を検出する方法について説明する。

local_maxiは極大値の部分がTrueとなった配列となる。sumをとると3であることから、3つの円の極大値を取れている。

極大値のラベリング

ndi.labelで局所的極大値をラベリングする。
markersは極大値のTrueの部分が1,2,3とラベリングされているので、合計値(sum)は6となる。

watershedの適用 

-distanceとすることで極大値を極小値として扱う。-distanceを3Dグラフで表示すると以下のようになる。

この3つの穴に水が溜まっていくようにしてセグメント化するのがwatershedアルゴリズムである。 markerとしてmarkersを指定し、 mask=imageとすることでセグメント化された配列が得られる。

画像の表示

左に元画像、中央にwatershedでセグメント化した像、右に背景からの距離を負に変換した画像を示している。

参考

Watershed segmentation — skimage v0.17.2 docs
物体セグメンテーションアルゴリズム"watershed"を詳しく - Qiita
Watershed algorithm 接触する物体をうまい具体に分離(セグメンテーション)して認識してくれるアルゴリズム OpenCVでも利用可能 結構古典的なアルゴリズム watershed = 分水嶺? 画像の輝度...
Module: morphology — skimage v0.18.dev0 docs

コメント