これを OpenCV を使って Python でやってみた。
大まかな流れとしては、
1. オリジナル画像から赤領域を抽出
2. オリジナル画像から赤領域を削除
3. 2.の画像をグレー化
4. 3.の画像に1.で抽出した赤領域を合成
となる。
まず、入力画像イメージ(img)から、h(色相 - Hue)、s(彩度 - Saturation)、v(明度 - Value)の各要素を取り出す。
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL) h = hsv[:, :, 0] s = hsv[:, :, 1] v = hsv[:, :, 2]次に色相の中央値(h_center)と対象とする幅(h_width)より、色相の範囲を決定する。
なお、範囲の上限値・下限値は h_center に対して h_width を加減することで取得するが、与えられた h_center と h_width 次第は、減算した結果が負数になったり、加算した結果が OpenCV の色相の上限値である 180 を超過することも考えられる。
これにより、下限値(h_low)が上限値(h_high)よりも大きくなる可能性があるが、下限値が上限値よりも大きいということは、色相の範囲が 下限値 < 360 = 0 < 上限値として考えることができる。
ちなみに、h_center に 0 を設定し、h_width に適当な範囲を設定すれば、赤領域のマスクが取得できる。
以下の処理では、彩度、明度については上限値・下限値が別途与えられるものとする。
mask = np.zeros(h.shape, dtype=np.uint8) h_low = (h_center - h_width) % 180 h_high = (h_center + h_width) % 180 if h_low < h_high: mask[((h > h_low) & (h < h_high)) & ((s > s_min) & (s <= s_max)) & ((v > v_min) & (v <= v_max))] = 255 else: mask[((h < h_high) | (h > h_low)) & ((s > s_min) & (s <= s_max)) & ((v > v_min) & (v <= v_max))] = 255 mask_inv = cv2.bitwise_not(mask)上記処理で作成したマスクを使用して、赤領域を抽出する。
img_red = cv2.bitwise_and(img, img, mask=mask)あとは、上で取得した mask および mask_inv を用いて、2. ~ 4. の処理を行う。
# 2.赤領域の削除 img_except_red = cv2.bitwise_and(img, img, mask=img_mask_inv) # 3.画像のグレー化 img2gray = cv2.cvtColor(cv2.cvtColor(img_except_red, cv2.COLOR_BGR2GRAY), cv2.COLOR_GRAY2BGR) # 4.画像の合成 outimg = cv2.bitwise_or(img2gray, img_red) cv2.imshow('apple', outimg) cv2.waitKey() cv2.destroyAllWindows()以下の画像は、h_center = 0, h_width = 30, s_min = 130, s_max = 255, v_min = 0, v_max = 255 とした場合の加工結果である。
0 件のコメント:
コメントを投稿