💫
【OpenCV】inRange(), floodFill()で取得したマスクの「座標」と「元の色」を取得する
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