OpenCVによる細線化.(スケルトン化)

モルディブの青い海とビーチ

前回の細線化(スケルトン化)記事の中で、Scikit-Imageモジュールを使って細線化を行いました。

前回の細線化記事
    Emotion Explorer - Scikit-Imageの細線化(Skeletonize)をOpenCVと組み合わせて試す。


探し方が悪く、OpenCVには細線化が無いんだと思っていたら、ありました。

関数
dst = cv.ximgproc.thinning(src[, dst[, thinningType]])
  • src - 入力画像(8ビットグレースケール)
  • dst - 出力 出力画像(8ビットグレースケール)
    返却値と共通です。
  • thinningType - オプション
    THINNING_ZHANGSUEN - Zhang-suen(Zha84)
    THINNING_GUOHALL -

OpenCVの細線化(thinning)を試してみます。



Pythonサンプルプログラム

import cv2
import numpy as np

# 表示
def display_result_image(cap, color_image, skeleton):
colorimg = color_image.copy()

# カラー画像に細線化を合成
colorimg = colorimg // 2 + 127
colorimg[skeleton == 255] = 0

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

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

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

# 二値画像反転
image = cv2.bitwise_not(gray)

# 細線化(スケルトン化) THINNING_ZHANGSUEN
skeleton1 = cv2.ximgproc.thinning(image, thinningType=cv2.ximgproc.THINNING_ZHANGSUEN)
display_result_image('ZHANGSUEN', colorimg, skeleton1)

# 細線化(スケルトン化) THINNING_GUOHALL
skeleton2 = cv2.ximgproc.thinning(image, thinningType=cv2.ximgproc.THINNING_GUOHALL)
display_result_image('GUOHALL', colorimg, skeleton2)

if __name__ == '__main__':
main()

前回記事と同じような構造で作っています。

display_result_image()関数内で、下記のように画像合成していますが、
これは、色を薄くして、細線化の線を見やすくするために行っています。

# カラー画像に細線化を合成
colorimg = colorimg // 2 + 127
colorimg[skeleton == 255] = 0



動作環境

Windows10 Anaconda
Python 3.8.3
OpenCV 4.0.1
numpy 1.19.1



試行


入力画像
  20200808_handstand.png

入力画像は、こんな感じ。
左側はヨガのポーズ アド・ムカ・ブリクシャーサナ (ハンドスタンド)、右側がBの文字。
上にちょろっとあるのはフリーハンドの落書き。
これでやってみます。


二値画像
  20200808_hand_binimage.png

細線化アルゴリズムのデモは、ここの二値画像からで十分なのですが、画像が地味なので
あえてカラー画像からやっています。


細線化(スケルトン化) THINNING_ZHANGSUENオプション


結果画像
  20200808_ZHANGSUEN_skeleton.png

細線化されています。

結果と入力画像との合成
  20200808_ZHANGSUEN_colorimg.png

細線化画像と、入力カラー画像を合成しています。入力カラー画像は、細線化の線を見やすくするために
色を薄くする処理を行っています。


前回記事(Scikit-Image)での画像で細線化(参考)
  20200808_ZHANGSUEN_ballet.png

比較のため前回のScikit-Image細線化で用いた画像の処理結果を掲載しておきます。
実装が違うので、異なるのは当たり前なのですが、やっぱりなという感じがします。



細線化(スケルトン化) THINNING_GUOHALLオプション


結果画像
  20200808_GUOHALL_skeleton.png

結果と入力画像との合成
  20200808_GUOHALL_colorimg.png


前回記事(Scikit-Image)での画像で細線化(参考)
  20200808_GUOHALL_ballet.png

比較のため前回のScikit-Image細線化で用いた画像の処理結果を掲載しておきます。



感想

dandelion1124さんから、無いと思っていたOpenCVの細線化の情報を頂き、この記事を書くことが
出来ました。ありがとうございました。
細線化をやってみましたが、Scikit-ImageとOpenCVで、同じZhang's method(Zha84)でも、
ちょっと違いました。
この処理を利用する場合、いったん細線化アルゴリズムコードを確定したら、
やたらに変更できないですね。変更するとテストが大変になる気がします。

この実験はおもしろかったです。いいかんじ。


修正・加筆

  • 2021/04/21 修正
    IntersectionObserver’s による画像のオフスクリーン遅延読み込み処理に変更。
    IE11未対応。



関連



参考



写真引用

Andreworkさんによる写真ACからの写真

#画像処理
#モルフォロジー

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



コメント

非公開コメント