物理の駅 by onsanai

Physics Station → PhSt 質問・疑問・間違いの指摘は、コメントに書くか、直接伝えるときっと良いことがあります。主にWindows or Ubuntu用の記事です

Pythonで画像のラベリング→輝度値0以外の領域を分割して領域ごとの座標と輝度値リストを取得する

バージョン3以降のOpenCVには、画像のラベリングできる関数が実装されている。

connectedComponents は、入力画像と同じサイズの画像にラベルの番号が書かれた画像を返してくれる。

connectedComponentsWithStats はStats、すなわち面積、重心等を含めた情報を返してくれる(以下の例では使っていない)。

つまり輝度値が0以外の領域を上下左右の周辺4方向や、周辺8方向で繋げて、繋がらない部分を分割して、領域ごとの座標と輝度値のリストを取得するには、connectedComponents を使えば良い。

import cv2
# 画像読み込み
img = cv2.imread(r"file0117.png",-1)
thr=cv2.add(img,-55)

##接続条件は上下左右(4)のみ
n, label = cv2.connectedComponents(thr,None,4)

# [x y 輝度値]の配列を格納する
connected = []
for _ in range(n):
    connected.append([])

#Labelから輝度値を抜き出す
for y, (y1,y2) in enumerate(zip(thr,label)) :
    for x, (x1, x2) in  enumerate(zip(y1,y2)):
        if connected[x2] is None:
            continue
        if x1==0:
            connected[x2]=None
            continue
        connected[x2].append([x,y,int(x1)])

#輝度0の領域を排除する
connected = [c for c in connected if c is not None]

#領域数を出力
print("Number of connected area is", len(connected))

サンプル画像を使うと Number of connected area is 20112 と出力されるはずである。

f:id:onsanai:20200618213954p:plain