💫

【OpenCV】inRange(), floodFill()で取得したマスクの「座標」と「元の色」を取得する

2022/09/19に公開

inRange()で色範囲を絞ってマスクを取得したとき、範囲内の色のピクセルの座標と、実際の各ピクセルのBGR情報の取得の、numpyを駆使した実装方法をご紹介します。

np.where()の戻り値は、条件を満たす要素のインデックスのリストなので、今回のケースでは要素のインデックス=y,x座標のため、簡単に座標が取得できちゃいます

また、ファンシーインデックスで配列の[]にリストを渡すことで複数の要素を取得可能なので
取得した座標のリストをそのまま渡すことで、たった一行でマスクしたピクセルの実際のBGRのリストを取得が可能!
この手の処理に多重forブン回さなくて済むpythonサイコー🤗

inRange()で取得したマスクの座標・元の色を取得

import cv2
import numpy as np

img = cv2.imread(r"src.bmp")
    
lower = (21, 61, 57)
upper = (21, 61 ,57)
mask = cv2.inRange(img, lower, upper)
    
idxs = np.where(mask == 255) # np.where()は条件満たす要素のインデックスを返す
    
ys = idxs[0]
xs = idxs[1]
    
color = img[ ys, xs ]
   
print("x座標", xs)
print("y座標", ys)
print("元の色", color)

floodFill()で塗りつぶした座標・元の色を取得

import cv2
import numpy as np

img = cv2.imread(r"src.bmp")

# フラッドフィル処理のため周囲1px膨張した空マスク作成
mask = np.zeros((img.shape[0] + 2, img.shape[1] + 2), dtype=np.uint8)
_, newImg, newMask, rect = cv2.floodFill(
    img,
    mask=mask,
    seedPoint=(x, y),
    newVal=(0, 0, 255), # red
    loDiff=(0, 0, 0),
    upDiff=(0, 0, 0),
    flags = 4 | 255 << 8,
)

idxs = np.where(newMask == 255)
idxs = np.array(idxs) - 1 # 膨張した分1px引く

ys = idxs[0]
xs = idxs[1]

color = img[ ys, xs ]
   
print("x座標", xs)
print("y座標", ys)
print("元の色", color)

Discussion