LoginSignup
20

More than 5 years have passed since last update.

OpenCVでのHSV色空間lower,upperの取り扱い

Posted at

HSVはlower,upperで色選択できるのがメリットなんだけども、色に対するlower,upperが不明で苦労したのでメモする。

HSVとは

rgbの拡張みたいもんで、色相(Hue)、彩度(Saturation・Chroma)、明度で構成される。何が嬉しいのかというと色を範囲指定しやすいというメリットがある。
Hの部分はrgbの部分にあたる。

色相 - 色の種類  0 - 360の範囲
彩度 - 色の鮮やかさ  0 - 100 % の範囲。
明度 - 色の明るさ  0 - 100 % の範囲。

で設定する数値はソフトによって変わるそうだ。opencvだと明度とか100から255の間なんだと思う。

スクリーンショット 2017-07-05 21.53.25.png

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にコンバートする

convert.py
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をデバッグする

hsv.py
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を調整する。

hsv_sample.py
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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20