OpenCV実験python3 特定の色の抜き出し

特定の色のエリアを抜き出してみる実験を行ってみます。素材は私が取ったショウガ科の熱帯植物の花の写真で、花の赤い部分だけを抜いてみます。

ショウガ科花

サンプルコードは以下です。流れとしては

・画像を読み込んでHSVに変換

・HSVで赤の指定。前の記事でも書きましたが、赤はHue値が0以上のあたりと180以下のあたりに存在していますが、この画像の赤は180以下あたりの赤でして、これは予め調べてある前提で進めます。S,Vは適当に半分(128から256)を指定してあります。

・マスクを作ってbitwise_andでマスク指定された部分はそのまま、それ以外の部分は黒塗りにします。というか黒くなりますね。以下のファイルはRed.pyとでもします。

import cv2
import numpy as np


infile='ginger.png'
img = cv2.imread(infile)
        
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

#赤い色のHSV範囲指定。
lower = np.array([160,128,128], dtype=np.uint8)
upper = np.array([180,255,255], dtype=np.uint8)

#maskとbitwise_andで赤い部分を抜いてその他を黒に。
maskRed = cv2.inRange(hsv, lower, upper)     
img_red = cv2.bitwise_and(img,img,  mask= maskRed)
        
cv2.imwrite('ginger_redmask2.png',img_red)
$ python3 Red.py

で実際にできた画像は以下になります

赤い部分だけを抜き出した画像


背景が黒くなる理由はbitwise_andを実行するとSaturationとValueが全部0になってしまうので、黒くなるということでしょうか。たとえば0000と1111でand すると 0000ですよね。

上の花の部分は白くなっていますので、もう少し白い領域も取れるようにSaturationを広く取れるように変更して実施してみると、、(Sを128から0へ。)

lower = np.array([160,128,128], dtype=np.uint8)

を

lower = np.array([160,0,128], dtype=np.uint8)

に

と マスクの範囲をちょっと広くして実行してみると以下のような画像が取れます。

赤い部分だけを抜き出した画像。もうちょっと白い部分も抜き出し

いや楽しいですねOpenCV。。