今回はOpenCVを使って画像のラベリングを行います。いらすとやさんの画像を使わせていただきました。
ラベリングは画像を連続する領域ごとにラベルを付けることです。上の画像であれば、左の棒人形と右の棒人形が分離しているので、別々のラベルになります。
opencv-pythonでラベリングするメソッドは2つありますが、後者のconnectedComponentsWithStatsの方がより詳細な情報を返します。このため、connectedComponentsWithStatsのみを紹介します。
cv2.connectedComponentsWithStatsを使った実装は以下です。
- まず2値化して領域を分離します
- connectedComponentsWithStatsの引数は3つで、画像、4 or 8、型です
- 2つ目の引数は4連結・8連結の区別です
- connectedComponentsWithStatsの返り値は4つで、ラベル数、ラベルのマッピング画像、各ラベルの矩形領域 (x, y, width, height) 、各ラベルの中心点です
- ラベル数は0の領域 (背景) も含むので、1の領域に限定する場合は-1する必要があります
import cv2 import numpy as np import matplotlib.pyplot as plt # グレースケールで読み込み img = cv2.imread("./figure_talking.png", cv2.IMREAD_GRAYSCALE) # 2値化 _, img = cv2.threshold(img, 16, 255, cv2.THRESH_BINARY) # ラベリング labels, label_imgs, bbox, center = cv2.connectedComponentsWithStats(img, 8, cv2.CV_32S) print(labels) # 3 -> 背景を含むラベル数 print(bbox) # [[ 0 0 375 400 73936] -> 背景の矩形領域 # [ 7 7 166 384 36567] -> 左の棒人形の矩形領域 # [ 148 7 218 384 39497]] -> 右の棒人形の矩形領域 print(center) # [[193.08560106 206.94814434] # [ 77.2717751 192.04099325] # [277.19639466 192.46319974]] print(label_imgs.shape, np.unique(label_imgs)) # (400, 375) [0 1 2] -> ラベルには0, 1, 2が使われている plt.imshow(label_imgs)
ラベルのマッピング画像を表示すると、棒人形が異なる色で表示されており、別のラベルとなっていることがわかります。