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

python

はじめに

画像処理において、重なり合ったオブジェクトを個別に識別することは重要な課題です。scikit-imageライブラリのwatershedアルゴリズムは、この問題を効果的に解決するためのツールを提供しています。本記事では、watershedセグメンテーションの基本概念から実装方法まで詳しく解説します。

コード

解説

モジュールのインポート

データの生成

重なり合った3つの円の画像を生成します。

np.indices((60, 60))を使用して、各ピクセルの座標を要素とする配列を生成します。

mask_circle1 = (x – x1)**2 + (y – y1)2 < r12 という式で、座標(x1, y1)を中心とする半径r1の円内部がTrueとなるブール配列を作成します。

np.logical_or(mask_circle1, mask_circle2)で配列の各要素に対して論理和演算を行い、2つの円が合体した形状を作ります。

さらに、np.logical_or(image, mask_circle3)を適用して3つの円を合体させます。この結果は以下のような画像になります。

ndi.distance_transform_edt(image)は画像内の各ピクセルから背景までの距離を計算します。円の中心部ほど背景からの距離が大きくなるため、距離マップ上ではその値も大きくなります。

局所的極大値を求める

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

[scikit-image] 51. 画像の局所的な極大値を検出(skimage.feature peak_local_max)
scikit-imageのpeak_local_max関数を使った画像内の局所的極大値(ピーク)検出技術の解説。パラメータ設定、前処理手法、応用例を含む実践的なガイドで、効率的な画像解析を実現するための知識を提供します。

local_maxiは極大値の部分がTrueとなる配列です。この配列のsumが3になることから、3つの円の極大値を正しく検出できていることがわかります。

極大値のラベリング

ndi.labelを使用して局所的極大値をラベリングします。markersでは極大値のTrue部分が1、2、3とラベル付けされるため、合計値(sum)は6になります。

watershedの適用 

-distanceとすることで極大値を極小値として反転させます。この-distanceを3Dグラフで表示すると以下のような形状になります。

これが、watershedアルゴリズムの基本原理です。画像内の「窪み」に水が徐々に溜まっていく過程をシミュレーションし、オブジェクトを分離します。実装では、markersをマーカーとして指定し、mask=imageパラメータを設定することで、効果的にセグメント化された結果配列が得られます。

画像の表示

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

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

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

まとめ

scikit-imageのwatershedアルゴリズムは、重なり合ったオブジェクトを効果的に分離するための強力なツールです。適切なマーカー設定と前処理を組み合わせることで、様々な画像処理タスクに応用できます。特に物体検出や画像セグメンテーションのパイプラインの一部として、高い実用性を持っています。

参考

Watershed segmentation — skimage 0.25.2 documentation
物体セグメンテーションアルゴリズム"watershed"を詳しく - Qiita
Watershed algorithm 接触する物体をうまい具体に分離(セグメンテーション)して認識してくれるアルゴリズム OpenCVでも利用可能 結構古典的なアルゴリズム watershed = 分水嶺? 画像の輝度勾配を山と谷の地形図...
skimage.morphology — skimage 0.26.0rc0.dev0 documentation

コメント