はじめに
ブロブ(塊)とは、似た特徴を持った画像内の領域を意味します。例えば、下の様な画像では、丸などの図形がブロブだと言えます。
OpenCVには、ブロブを自動的に検知できる関数が組み込まれており、簡単に見つけることができます。
やりたいこと
丸形を見つけてカウントしたい。
# コード
import cv2
import numpy as np
# 画像の読み込み
image = cv2.imread('shapes.jpg', 0)
# パラメータの初期化
params = cv2.SimpleBlobDetector_Params()
# ブロブ領域(minArea <= blob < maxArea)
params.filterByArea = True
params.minArea = 100
# 真円度( 4∗π∗Area / perimeter∗perimeter によって定義される)
#(minCircularity <= blob < maxCircularity)
params.filterByCircularity = True
params.minCircularity = 0.85
# 凸面の情報(minConvexity <= blob < maxConvexity)
params.filterByConvexity = True
params.minConvexity = 0.1
# 楕円形を表す(minInertiaRatio <= blob < maxInertiaRatio)
params.filterByInertia = True
params.minInertiaRatio = 0.1
# 検知器作成
detector = cv2.SimpleBlobDetector_create(params)
# ブロブ検知
keypoints = detector.detect(image)
# ブロブを赤丸で囲む
blank = np.zeros((1, 1))
blobs = cv2.drawKeypoints(image, keypoints, blank, (0, 0, 255),
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
# ブロブの個数
count = len(keypoints)
print(f'丸の個数: {count}')
# 画像を表示
cv2.imshow("out.jpg", blobs)
cv2.waitKey(0)
cv2.destroyAllWindows()
#結果
>python blob.py
丸の個数: 8
※枠が赤から黒に変化したのは、グレースケールで読み込んだためです。
#実行で失敗した話
他のサイトで紹介されていたコードを試したら、Pythonがクラッシュしました。
調べてみるとOpenCVのバージョンが影響してたようです。以前のバージョンのOpenCVでは、SimpleBlobDetector_create()の代わりに、SimpleBlobDetector()という関数が使われており、コピペでコード実行 → 現在は使われていない関数を参照 → クラッシュという流れが発生したのだと思います。
対策としては、SimpleBlobDetector_create()を使うか、下のコードに書き換えるとエラーを回避できます。
ver = (cv2.__version__).split('.')
if int(ver[0]) < 3:
detector = cv2.SimpleBlobDetector(params)
else:
detector = cv2.SimpleBlobDetector_create(params)
おわりに
ブロブ検知の応用例としては、個数のカウントや位置検知があります。OpenCVによって簡単に使えるので、この例以外でも試して行きたいと思います。
最後までご覧いただきありがとうございました。コメント・ご指摘等ありましたらよろしくお願いします。
# 参考URL
https://www.programcreek.com/python/example/89350/cv2.SimpleBlobDetector
https://www.visco-tech.com/technical/direction-presence/blob/