Scikit-Imageの細線化(Skeletonize)をOpenCVと組み合わせて試す。

20200803_ヤシの木

長雨が止み、ようやく夏らしくなってきた。
しかし、流行り病の弱自粛中で遠出は禁物とのこと。どうしたものか。

さて、細線化(スケルトン化)の画像処理アルゴリズムはOpenCVには無かった。※1
ただ、scikit-imageモジュールにあったのでOpenCVscikit-imageを組み合わせて
細線化をやってみましょうか。
今後、scikit-imageを使うにしても、メインはOpenCVで補助的に使うことになると思います。
ですからカテゴリーもOpenCV下のモルフォロジーのところに置いておくこととしました。


※1この時点ではないと思っていましたが、dandelion1124様 ご指摘によりOpenCV
 細線化(cv2.ximgproc.thinning)があるということが分かりました。 2020/08/08 追記



Scikit-image Skeletonizeについて

ここではOpenCV画像処理を行い、OpenCV画像をscikit-image Skeletonizeに
引き渡して処理をし、再び、OpenCVに戻すような感じで処理をします。

Scikit-image インストール

Anaconda パッケージの場合、インストールする必要があります。
インストールは、condaコマンドを使います。

インストール

conda install scikit-image


Pythonを起動、skimageをインポートしてバージョン番号を見ることで
インストールの確認としました。

$ python
Python 3.8.3 (default, Jul 2 2020, 17:30:36) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import skimage
>>> print(skimage.__version__)
0.16.2


インストール完了しました。

詳細は下記リンクを参照
  anaconda.org - Scikit Image :: Anaconda Cloud


Skeletonize() 関数について

skeletonize()という関数に画像を入力すると、細線化ができます。
ただ、2種類のアルゴリズムが用意されています。

関数
result = skeletonize(image, [method])
  • image - 入力画像(二値)
    0 or 1, Ture or Falseの画像を入力します。0 or 255ではできません。
  • ththod - アルゴリズム選択
    'Lee'を指定することで、Lee94アルゴリズムを選択することができます。
  • result - 出力イメージ
    Ture or Falseの二値画像を出力します。


  1. Zhang's method(Zha84)
    skeletonize(...)パラメータデフォルトで使用することができます。
    全体的に見ていると、こちらの方が一般的な感じがします。
  2. Lee's method(Lee94)
    skeletonize(...,method='lee')で使用することができます。
    画像の3次元処理をするときに使うとか。
    そのへんは良くわかりません。

この上記2点のアルゴリズムについて実装し、動きを確かめたいと思います。



Pythonサンプルプログラム

from skimage.morphology import skeletonize
#from skimage.util import invert
import cv2
import numpy as np

# 表示
def display_result_image(cap, color_image, skeleton):
colorimg = color_image.copy()
ski_result = np.zeros((color_image.shape[:2]), dtype=np.uint8)

# skeletonはTrue/False画像
ski_result[skeleton == True] = 255

# カラー画像に細線を転記
colorimg[skeleton == True] = 0

cv2.imshow(cap + '_skeleton', ski_result)
cv2.imshow(cap + '_color image', colorimg)
cv2.waitKey(0)

# 細線化
def main():
# 入力画像の取得
colorimg = cv2.imread('ballet_sample.png', cv2.IMREAD_COLOR)

# グレースケール変換
gray = cv2.cvtColor(colorimg, cv2.COLOR_BGR2GRAY)
_, gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

# Invert the horse image
image = cv2.bitwise_not(gray)
#image = invert(gray)
print('image:', image)

cv2.imshow('binary image', image.copy())

# 255から1に変換, 1と0の二値画像に変換
image[image == 255] = 1

# 細線化(スケルトン化) Zha84
skeleton = skeletonize(image)
print('skeleton:', skeleton)
display_result_image('Zha84', colorimg, skeleton)

# 細線化(スケルトン化) Lee94
skeleton_lee = skeletonize(image, method='lee')
display_result_image('Lee94', colorimg, skeleton_lee)

if __name__ == '__main__':
main()

細線化(スケルトン化)はZha84とLee94の2種類を実装しています。
二値画像の白黒反転は、scikit-imageではinvert()を使いますが、
OpenCVでは、bitwise_not()を使います。
skeletonize()にデータを入力するには、255を1に変換する必要があります。
skeletonize()の出力画像は、True/Falseの二値画像なので、これを0と255の
画像に変換します。


動作環境

Windows10 Anaconda
Python 3.8.3
OpenCV 4.0.1
scikit-image 0.16.2
numpy 1.19.1


試行


入力画像
20200803_ballet_sample.png

この画像を二値化し、反転させて使います。

二値画像
20200803_binimage.png

二値画像が上記。この画像を細線化(スケルトン化)します。


細線化(スケルトン化) Zha84


結果画像
20200803_Zha84_skeleton.png

細線化されていますね。


結果と入力画像との合成
20200803_Zha84_colorimg.png

どんな具合に細線化されているか見るために入力画像と合成しました。


細線化(スケルトン化) Lee94


結果画像
20200803_Lee94_skeleton.png

Zha84とは違う形で細線化されています。

結果と入力画像との合成
20200803_Lee94_colorimg.png

入力画像と細線化画像と合成したものが上記です。



感想

OpenCVに細線化が無かったので、作らないといけないかなと思いましたが、
ありました。
scikit-imageも良い画像処理ライブラリのようにも感じましたが、マルチプラットフォームなのかな?
その辺がひっかる箇所です。C++, C# ..etc いろいろな処理系で使えないと困ります。
それにしても、細線化がうまくできました。いい感じです。


追記

  • 2020/08/08
    OpenCVに無いと思っていた細線化がありましたので、その件について記載しました。
    OpenCV版細線化の記事についても書きました。
  • 2021/04/22 修正
    IntersectionObserver's による画像のオフスクリーン遅延読み込み処理に変更。
    IE11未対応。



参考



写真引用

熊澤充さんによる写真ACからの写真

#画像処理
#Scikit-Image

関連記事
スポンサーサイト



コメント

非公開コメント

thinningアルゴリズム

> 細線化(スケルトン化)の画像処理アルゴリズムはOpenCVには無かった。

cv::ximgproc::thinningに実装されているのでご参考ください。
https://docs.opencv.org/4.4.0/df/d2d/group__ximgproc.html#ga37002c6ca80c978edb6ead5d6b39740c

Re: thinningアルゴリズム

情報ありがとうございます。
助かります。