[SciPy] 5. ndimageのmeasurements, morphologyで実生サボテンのラベリングとサイズ計測

python

コード & 解説

SciPy, ndimageのmeasurements, morphology の使い方について解説する。

モジュールのインポート

画像の読み込み

今回使用する画像は、アストロフィツム属のストロンギロゴナムの実生サボテンで種まき後8ヶ月ぐらい経過したもの。

おおきくなると、下記サイトのようになる。

Astrophytum myriostigma var. strongylogonum

白黒画像で読み込んで、形とサイズを調べると、shape=(727, 727), size =528529とのことだった。

画像のヒストグラムの表示

2値化

2値化は、im2 = (im>150)のようにすることで150以上の数値の部分のみTrueとなり、それ以外はFalseとなったデータが得られる。このデータのTrueの数は、im2.sum()でわかり、65179個となっている。

2値化像は以下のようになる。

画像のラベリング

scipy.ndimage.measurementsのlabel()で、 画像内の白い領域を数えられる。
返り値はlabels:ラベル付けされた領域の画像と、nbr_objects:ラベル付けされた領域の数となる。

2値化像の白い領域を計測するとその数は、 2195個となった。これは、画像中のサボテン以外のノイズも計測しているためで、ノイズを除去する必要がある。

binary_openingによる小さい領域の除去

morphology.binary_opening()により、画像中の小さい領域を除去できる。iterationsを大きくすると、より大きいものが除去される。

白い領域の数は45となった。

マスクによる小さい領域の除去

morphology.binary_opening()以外のノイズの除去方法として、マスクを用いる方法がある。

measurements.sum()により、ラベル付けされた白い領域それぞれの大きさを得ることができる。mask = areas > 755でマスクするサイズ以下のものをFalseとして、mask[labels_op]とすれば、大きさが755ピクセル未満の白い領域が除外された2値化像となる。

白い領域の個数は30個となった。

以上の2値化をまとめると以下の図のようになる。

ラベリングされた画像

最後の白い領域の個数が30個のもののラベリングされた画像を表示する。


背景が0なので1がどこにあるのか分かり難い。そこで以下のようにする。

0のところをnp.nanにすると、色が表示されなくなるので以下のような画像が得られる。わかりやすい。

ラベリングされた領域の重心

ラベリングした領域の重心は、measurements.center_of_mass()で求めることができる。
求めた重心を画像中に赤点で示した。加えて、重心の右上にそのインデクスを追記した。

ラベリングした領域の大きさ

ラベリングした領域の大きさは、measurements.sum()でそれぞれ求めることができる。
前節で求めた重心の位置を利用して、重心の右上に各領域のサイズを追記した。

大きさが最大のものと最小のものは以下のコードで求めることができる。

参考

scipy.ndimage.morphology.binary_opening — SciPy v0.16.1 Reference Guide
Multi-dimensional image processing (scipy.ndimage) — SciPy v0.16.1 Reference Guide
https://www.shuminoengei.jp/?m=pc&a=page_p_cactus_detail&target_cactus_code=97

scikit-imageによるラベリング

ndimageより多機能なscikit-imageによるラベリングについて下記で解説した。

[scikit-image] 53. 画像のラベリング(skimage.measure labelなど)
skimage.filtersのthreshold_otsu、morphologyのopening, closingなどによって、画像中の対象物をラベリングする方法について説明する。

コメント

  1. kub より:

    ありがとうございます。
    とても勉強になりました。