[scikit-image] 58. 日本地図を都道府県で分割(skimage.morphology opening, measure.label, filters.sobel)

python

はじめに

画像の輪郭をsobelフィルタにより抽出し、抽出した輪郭ごとにラベリングする方法について、都道府県の境界が表示された日本地図のイラストを例として、説明する。

コード

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

解説

モジュールのインポート

画像の読み込み

用いる画像は下記サイトから取得した。

日本地図のイラスト(都道府県ごとに区切り)
いらすとやは季節のイベント・動物・子供などのかわいいイラストが沢山見つかるフリー素材サイトです。

以下の画像を用いる。

img_cはRGB画像であり、それをrgb2grayでグレースケール化したものをimageとする。

sobelフィルタの適用

sobelフィルタで画像の輪郭を抽出する。sobelフィルタを適用した画像は以下のようになる。

sobelフィルタを適用した画像の2値化

値として0.04より小さい部分をTrueとすると以下のような画像が得られる。

ノイズの除去

opening処理を2値化像に適用することでノイズを除去する。ここでは2回openingした。結果として以下の画像が得られる。

画像のラベリング

label(openimg)でさっきの画像をラベリングする。
label2rgbでラベルごとにcmapsの色を適用して表示する。結果は以下のようになる。

重心とラベル番号の表示

regionprops(label_image)のcentroidでラベル領域の重心が得られるので、その部分に赤丸とラベル番号を表示すると下のようになる。

ラベル領域を切り取って表示

regionprops(label_image).bboxでラベル領域を囲む四角形の座標が得られるので、その部分で画像を切り取り、一覧を表示したのが下の図となる。
この場合、他の領域も周りに混ざってくるのでわかり難い図となっている。

ラベリングした部分のみを切り取る

im_label = (licrop==region.label)でラベル番号が一致する部分のみをTrueとしたbool配列を得る。
この配列をもとのRGB画像と掛け合わせる。bool配列はTrueが1、Falseが0で計算されるのでTrueの部分以外は0となり黒くなり、ラベリングした部分のみが残る。例を以下に示す。

各都道府県を表示

すべてのラベリングした領域に上記の処理を行うことで各都道府県を分離できる。

参考

[scikit-image] 16. エッジ演算子(filters.roberts, sobel)
skimage.filters の roberts, sobelを用いた画像のエッジ検出
[scikit-image] 53. 画像のラベリング(skimage.measure labelなど)
skimage.filtersのthreshold_otsu、morphologyのopening, closingなどによって、画像中の対象物をラベリングする方法について説明する。
[scikit-image] 54. ラベリングした領域のサイズ、角度、重心などの測定(skimage.measure regionprops)
skimage.measureのregionpropsによって、ラベリングした領域の性質を取得する方法について説明する。
Module: measure — skimage v0.17.dev0 docs
Module: filters.rank — skimage v0.17.dev0 docs

コメント