본문 바로가기

머신러닝,딥러닝/opencv

opencv 입문하기 7-2편 HSV, 특정 색상 추출(inRange)

1. HSV 

HSV 색 공간 또는 HSV 모델은 색을 표현하는 하나의 방법이자, 그 방법에 따라 색을 배치하는 방식이다. 색상(Hue), 채도(Saturation), 명도(Value)의 좌표를 써서 특정한 색을 지정한다. 비슷한 것으로 HSL(Lightness), HSI(Intensity) 등이 있다.

 RGB가 색을 빨강, 초록, 파랑의 조합으로 표현한다면, HSV는 우리가 보는 그대로의 색을 Hue 채널로 나타낸다. 그리고 그 색의 진하고 연한 정도를 Saturation 채널로 표현하고, 밝기를 Value로 결정한다.

 

RGB 색 공간보다는 좀 더 우리들이 색을 판단하는 과정과 유사한 것이 HSV 색 공간이다. 예를 들어 노란색을 표현하고자 하면, RGB 색 공간은 빨강과 초록의 조합으로 노랑을 표현해야하기에 직관성이 떨어진다. 반면 HSV 색 공간은 색들의 조합이 아닌 그 색깔 자체를 알려주므로 직관성이 좋다. 

 

만약 색깔을 통해 이미지에서 어떤 물체를 검출하고 싶다면, RGB 공간보다는 HSV 공간이 적합할 것이다.

 

다음 그림은 HVS 색 공간을 한 눈에 설명해준다. 원뿔 모양으로 HSV 공간을 표현했는데, 우선 색조는 원뿔의 밑면에 해당되고 360도 연속적으로 배치되어 있음을 볼 수 있다. 그리고 명도는 원뿔의 높이에 해당한다. 꼭지점으로 갈수록 어두워진다.

채도는 원뿔의 밑면의 중심에서 가까울수록 연해지고 멀어질수록 진해진다. 

 

 

 

 

 

색상 : H ) 0 - 360 의 범위를 가지고, 가장 파장이 긴 빨간색을 0도로 지정한다.
채도 : S ) 0 - 100 의 범위를 가지고, 색상이 가장 진한 상태를 100으로 하며, 진함의 정도를 나타낸다.
명도 : V ) 0 - 100 의 범위를 가지고, 흰색, 빨간색을 100, 검은색이 0이며, 밝은 정도를 나타낸다.

 

 

RGB -> HSV

import numpy as np
import cv2

color = [255,0,0]  # BGR 순서 ; 파란색
pixel = np.uint8([[color]]) # 한 픽셀로 구성된 이미지로 변환

# BGR -> HSV
hsv = cv2.cvtColor(pixel, cv2.COLOR_BGR2HSV)
print(hsv, 'shape:', hsv.shape )

# 픽셀값만 가져오기 
hsv = hsv[0][0]

print("bgr: ", color)
print("hsv: ", hsv) # +_ 10

 

앞선 포스팅에서 RGB2HSV 를 종종 사용했었다. 

위 코드를 실행해서 임의로 한 픽셀로 된 이미지를 만들어서 numpy array 를 살펴보자. 

 

 

 

어떤 수식으로 변환할걸까? 공식문서에서 나온 공식을 참고 해보자. 

 

 

H 는 0~360 , S 와 V 는 0~1 범위이다. 이는 맨 위에서 다룬 원뿔 모양으로 표현한 HSV 모델 구조를 생각해보면 이해가 될 것이다. 

H는 절반값이고 나머지는 maximize 된 것으로 이해된다. 

 

2. inRange(특정 색상 추출)

 

HSV 개념을 이해했다면 이를 활용하여 특정 생상을 추출해보겠습니다. 

일반적으로 BGR 보다는 HSV 가 성능이 좋습니다. 

 

결과

 

코드

# inRange

import numpy as np
import cv2

img_color = cv2.imread('color circle_w.jpg') # 이미지 파일을 컬러로 불러옴
print('shape: ', img_color.shape)

height, width = img_color.shape[:2] # 이미지의 높이와 너비 불러옴, 가로 [0], 세로[1]

img_hsv = cv2.cvtColor(img_color, cv2.COLOR_BGR2HSV) # cvtColor 함수를 이용하여 hsv 색공간으로 변환

lower_blue = (120-10, 30, 30) # hsv 이미지에서 바이너리 이미지로 생성 , 적당한 값 30
upper_blue = (120+10, 255, 255)
img_mask = cv2.inRange(img_hsv, lower_blue, upper_blue) # 범위내의 픽셀들은 흰색, 나머지 검은색

# 바이너리 이미지를 마스크로 사용하여 원본이미지에서 범위값에 해당하는 영상부분을 획득
img_result = cv2.bitwise_and(img_color, img_color, mask = img_mask) 


cv2.imshow('img_origin', img_color)
cv2.imshow('img_mask', img_mask)
cv2.imshow('img_color', img_result)

cv2.waitKey(0)
cv2.destroyAllWindows()

 

중간에 color 이미지의 shape 은 shape:  (472, 600, 3) 인데요. 

여기서 472 는 행(Y축), 600 은 열(X축) , 3 은 행과열이 만나는 지점의 값이 몇개의 원소로 이루어져 있는지를 나타냅니다. 위 값의 의미는 이미지 사이즈는 600 * 472 (가로 * 세로) (너비 * 높이) 로 보시면 됩니다. 

 

472 = 가로 = 너비 

600 = 세로 = 높이 

 

입니다. 

위 결과를 조금 확대해서 보여드리자면, 

 

 

 

 

### 2번째 이미지 ### 

 

다른 이미지도 적용해보겠습니다. 

 

 

위와 같은 이미지에서 특정 색상을 추출해보겠습니다. 

 

 

 

# inRange 함수를 이용해서 특정 색상 검출

import cv2

src = cv2.imread('inRange.jpg')
# size 축소
src = cv2.resize(src, (0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)

src_hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)

#  0 < B < 100 ,   128 < G < 255 , 0 < R < 100
dst1 = cv2.inRange(src, (0, 128, 0), (100, 255, 100))
img_result = cv2.bitwise_and(src_hsv, src_hsv, mask = dst1)

dst2 = cv2.inRange(src_hsv, (50, 150, 0), (80, 255, 255))
img_result2 = cv2.bitwise_and(src_hsv, src_hsv, mask = dst2)

cv2.imshow('src', src)
cv2.moveWindow('src',400,100)

cv2.imshow('dst1', dst1)
cv2.moveWindow('dst1',400,450)

cv2.imshow('img_result', img_result)
cv2.moveWindow('img_result',800,450)


cv2.imshow('dst2', dst2)
cv2.moveWindow('dst2',400,800)


cv2.imshow('img_result2', img_result2)
cv2.moveWindow('img_result2',1100,450)

cv2.waitKey()
cv2.destroyAllWindows()

 

 

 

 

 

 

 

 

**  참고 **

 

ttps://ko.wikipedia.org/wiki/HSV_%EC%83%89_%EA%B3%B5%EA%B0%84

 

HSV 색 공간 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. HSV 색 공간 또는 HSV 모델은 색을 표현하는 하나의 방법이자, 그 방법에 따라 색을 배치하는 방식이다. 색상(Hue), 채도(Saturation), 명도(Value)의 좌표를 써서 특정한

ko.wikipedia.org

https://bskyvision.com/46

 

[색공간] HSV 색 공간을 활용해서 특정 색깔의 물체만 검출하기 (matlab 소스코드 포함)

▶ HSV 색 공간이란? HSV는 H(Hue; 색조), S(Saturation; 채도), V(Value; 명도)로 이미지를 표현하는 것으로 RGB와 같은 하나의 색 공간이다. RGB가 색을 빨강, 초록, 파랑의 조합으로 표현한다면, HSV는 우..

bskyvision.com

https://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html

 

Miscellaneous Image Transformations — OpenCV 2.4.13.7 documentation

Parameters: image – Input/output 1- or 3-channel, 8-bit, or floating-point image. It is modified by the function unless the FLOODFILL_MASK_ONLY flag is set in the second variant of the function. See the details below. mask – Operation mask that should

docs.opencv.org

https://velog.io/@nayeon_p00/OpenCV-Python-HSV-%EC%83%89%EA%B3%B5%EA%B0%84%EC%97%90%EC%84%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80%EC%9D%98-%ED%8A%B9%EC%A0%95%EC%83%89-%EC%B6%94%EC%B6%9C%ED%95%98%EA%B8%B0

 

OpenCV | Python | HSV 색공간에서 이미지의 특정색 추출하기

우선 색공간이란 색을 표현하는 방법을 3차원 좌표계로 표현한 것이다. 그 중 RGB 와 HSV 색공간이 존재한다.먼저 RGB 는 빛의 삼원색인 빨강, 초록, 파랑을 이용하여 색을 표현하는 방식이다. 따라�

velog.io

https://opencv-python.readthedocs.io/en/latest/doc/01.imageStart/imageStart.html

 

이미지 다루기 — gramman 0.1 documentation

cv2.imread() 함수를 이용하여 이미지 파일을 읽습니다. 이미지 파일의 경로는 절대/상대경로가 가능합니다. 이미지 읽기의 flag는 3가지가 있습니다. Note 3개의 flag대신에 1, 0, -1을 사용해도 됩니다.

opencv-python.readthedocs.io