はじめに
skimage.morphology のwatershedは、画像内の異なるオブジェクトを分離するためのアルゴリズムである。ここでは、watershedアルゴリズムを用いて、重なった円をそれぞれセグメント化した例について説明する。
コード
解説
モジュールのインポート
データの生成
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については下記で解説した。
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でセグメント化した像、右に背景からの距離を負に変換した画像を示している。
コードをダウンロード(.pyファイル) コードをダウンロード(.ipynbファイル)
コメント