バージョン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
と出力されるはずである。