1 枚の写真の中から、特定のオブジェクトを切り抜きするときに、一般的にマスクが使われる。切り抜きしたいオブジェクトを検出して、それを 2 値してマスクとして用いることで、オリジナル写真からその部分だけを切り抜くことができる。ここでは、OpenCV のマスク機能を利用して、次の写真からタネツケバナを抽出する例を示す。
植物個体の色は緑色をしているので、緑色の検出に有効な L*a*b* 空間を利用する。以下のコードでは、まず写真を読み込んでから L*a*b* 空間に変換している。OpenCV において、緑色は a* ≤ 110 なので、a* の値に閾値を設けて、緑色の部分が 225 (白)、それ以外の部分が 0 (黒)となるような画像を作成する。続いて、その画像をマスクとして、オリジナルの画像を切り抜きする。
import cv2
img_BGR = cv2.imread("./data/chirsuta.jpg")
# L*a*b*
img_Lab = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2Lab)
img_Lab_L, img_Lab_a, img_Lab_b = cv2.split(img_Lab)
# cv2.imwrite('chirsuta.a.jpg', img_Lab_L)
# detect green area with a* value
_thres, img_green = cv2.threshold(img_Lab_a, 110, 255, cv2.THRESH_BINARY_INV)
# get masked BGR images
img_green_masked = cv2.bitwise_and(img_BGR, img_BGR, mask=img_green)
# cv2.imwrite('chirsuta.mask.jpg', img_green)
cv2.imwrite('chirsuta.masked.jpg', img_green_masked)
次に、HSV 色空間を利用して、植物個体の切り抜きを行う例を示す。HSV 色空間において、緑色はおよそ 110 ≤ H ≤ 180 の範囲にある。そこで、inRange
を使用して、110 ≤ H ≤ 180 範囲にある画像だけを切り抜き、それをマスクとして利用する。
import cv2
img_BGR = cv2.imread("./data/chirsuta.jpg")
# HSV
img_HSV = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HSV)
# creat green mask (H value for green is from 100/360*179 until 180/360*179) in OpenCV
lower_green = np.array([100 / 360 * 179, 0, 0])
upper_green = np.array([180 / 360 * 179, 255, 255])
green_mask = cv2.inRange(img_HSV, lower_green, upper_green)
# crop green area
img_green_masked = cv2.bitwise_and(img_BGR, img_BGR, mask=green_mask)
cv2.imwrite('chirsuta.masked.jpg', img_green_masked)