HSVはlower,upperで色選択できるのがメリットなんだけども、色に対するlower,upperが不明で苦労したのでメモする。
#HSVとは
rgbの拡張みたいもんで、色相(Hue)、彩度(Saturation・Chroma)、明度で構成される。何が嬉しいのかというと色を範囲指定しやすいというメリットがある。
Hの部分はrgbの部分にあたる。
色相 - 色の種類 0 - 360の範囲
彩度 - 色の鮮やかさ 0 - 100 % の範囲。
明度 - 色の明るさ 0 - 100 % の範囲。
で設定する数値はソフトによって変わるそうだ。opencvだと明度とか100から255の間なんだと思う。
wiki参照
https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93
シミュレーター
http://www.rapidtables.com/convert/color/hsv-to-rgb.htm
#RGBからlower,upperにコンバートする
import sys
import numpy as np
import cv2
#rgb
red = sys.argv[1]
green = sys.argv[2]
blue = sys.argv[3]
color = np.uint8([[[blue, green, red]]])
hsv_color = cv2.cvtColor(color, cv2.COLOR_BGR2HSV)
hue = hsv_color[0][0][0]
print("Lower bound is :"),
print("[" + str(hue-10) + ", 100, 100]\n")
print("Upper bound is :"),
print("[" + str(hue + 10) + ", 255, 255]")
python convert.py 255 255 255
こんな感じで変換するんだけども、こいつはざっくりでしかコンバートできてない。
#HSVのlower,upperをデバッグする
import cv2
import numpy as np
image_hsv = None # global ;(
pixel = (20,60,80) # some stupid default
# mouse callback function
def pick_color(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDOWN:
pixel = image_hsv[y,x]
#you might want to adjust the ranges(+-10, etc):
upper = np.array([pixel[0] + 10, pixel[1] + 10, pixel[2] + 40])
lower = np.array([pixel[0] - 10, pixel[1] - 10, pixel[2] - 40])
print(pixel, lower, upper)
image_mask = cv2.inRange(image_hsv,lower,upper)
cv2.imshow("mask",image_mask)
def main():
import sys
global image_hsv, pixel # so we can use it in mouse callback
image_src = cv2.imread(sys.argv[1]) # pick.py my.png
if image_src is None:
print ("the image read is None............")
return
cv2.imshow("bgr",image_src)
## NEW ##
cv2.namedWindow('hsv')
cv2.setMouseCallback('hsv', pick_color)
# now click into the hsv img , and look at values:
image_hsv = cv2.cvtColor(image_src,cv2.COLOR_BGR2HSV)
cv2.imshow("hsv",image_hsv)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__=='__main__':
main()
python hsv.py hoge.png
起動してhsvの画面でダブルクリックするとマスクされる。
例えば黄色と緑は非常に似ている。
ピンクと赤も。この場合ピンクをクリックしてるのに赤も反応したりする。
つまり色の濃さと明るさを微調整しないといけない。
自動のやり方は不明だったので手動でいじった。
#手動でHSVを調整する。
import sys
import cv2
import numpy as np
import sys
import cv2
import numpy as np
#yellow
# lower = np.array([30,100,250])
# upper = np.array([40,255,255])
#pink
lower = np.array([160,50,50])
upper = np.array([180,255,255])
#yellowgreen
# lower = np.array([30,100,200])
# upper = np.array([60,255,250])
image_src = cv2.imread(sys.argv[1])
image_src = cv2.cvtColor(image_src,cv2.COLOR_BGR2HSV)
image_src = cv2.inRange(image_src,lower,upper)
while True:
cv2.imshow("image_src",image_src)
if cv2.waitKey(10) == 27: # ESC
break
非常に原始的な方法ではあるが、yellowと非常に似ているyellowgreenのマスクもうまくいった。
#やってないけども。。。
こんなので表示して、チョット範囲指定すれば自動化もできたのかもしれない。
>>> green = np.uint8([[[0,255,0 ]]])
>>> hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
>>> print( hsv_green )
[[[ 60 255 255]]]
#参考
How to define the “lower” and “upper” range of a color?
http://answers.opencv.org/question/134248/how-to-define-the-lower-and-upper-range-of-a-color/
http://docs.opencv.org/trunk/df/d9d/tutorial_py_colorspaces.html