이미지 파일에 숫자로 저장되어있다. 화면에 보여질 때에는 숫자를 컬러의 강도로 변환하여 보여진다. 이미지는 픽셀로 구성되며 하나의 픽셀은 B,G,R 3개의 채널로 구성된다.
opencv에서는 RGB가 아니라 BGR로 채널 순서가 다르다.
색공간은 색을 표현하는 방법을 3차원 좌표계로 표시한 것이다.
RGB 색공간 / HSV 색공간
HSV
- 색조(Hue): HSV의 색공간의 Hue 성분은 특정색의 컬러가 일정한 범위를 갖기 때문에 원하는 색의 범위를 정하기가 쉽다.
opencv에서는 0 ~ 179 범위를 가지기 때문에, 원하는 색의 그림에 표시된 Hue 값에 0.5를 곱한 값이 opencv에서의 Hue 값이다.- 채도(Saturation): 색상의 진함(값이 클수록 진함), opencv에서는 0 ~ 255 가진다.
- 명도(Value): 색상의 밝은 정도(값이 클수록 밝음), opencv에서는 0 ~255 값 가진다.
import numpy as np
import cv2
color = [255,0,0] #파란색
pixel = np.uint8([[color]])
hsv = cv2.cvtColor(pixel, cv2.COLOR_BGR2HSV)
hsv = hsv[0][0]
print('bgr: ',color)
print('hsv: ',hsv)
실행결과
pixel = np.uint8([[color]])
cvtColor 함수의 입력으로 사용 할 수 있도록 한 픽셀로 구성된 이미지로 변환한다.
hsv = cv2.cvtColor(pixel, cv2.COLOR_BGR2HSV)
cvtColor 함수를 이용하여 HSV 색공간으로 변환한다.
hsv = hsv[0][0]
HSV 값을 출력하기 위해 픽셀 값만 가져온다.
이미지에서 파란색을 검출하는 코드
import cv2
img_color =cv2.imread('1.png')
height,width = img_color.shape[:2]
img_hsv = cv2.cvtColor(img_color, cv2.COLOR_BGR2HSV)
lower_blue = (120-10,30,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_color',img_color)
cv2.imshow('img_mask',img_mask)
cv2.imshow('img_result',img_result)
cv2.waitKey(0)
cv2.destroyAllWindows()
실행 결과
파란색에 대한 채도(Saturation),명도(Value) 변화를 주어도 같은 값으로 인식한다.
height,width = img_color.shape[:2]
이미지의 높이와 너비를 가져온다.
lower_blue = (120-10,30,30)
범위를 정하여 HSV 이미지에서 원하는 색영역을 Binary 이미지로 생성한다.
너무 어두워서 검은색에 가까운 색과 색이 옅어서 흰색에 가까운 값을 제외시키기 위해 채도(Saturation),명도(Value) 값은 30으로 한다.
upper_blue = (120+10,255,255)
채도(Saturation),명도(Value) 값은 255로 한다.
img_mask =cv2.inRange(img_hsv, lower_blue, upper_blue)
inRange 함수에 앞에서 정의한 범위값을 사용하여 Binary 이미지를 얻는다. 범위 내에 있는 픽셀들은 흰색, 나머지는 검은색이 된다.
img_result = cv2.bitwise_and(img_color, img_color, mask = img_mask)
Binary 이미지를 마스크로 사용하여 원본 이미지에서 범위 값에 해당하는 영상 부분을 획득한다.
한계
2 ~ 3개 경계에 있는 값을 인식시키려고 하는 경우 두가지 색이 같은 범위에 포함 될 수 있다.-> 좀 더 좁은 범위를 사용해야한다.
조명 범위에 따라 색이 다르게 보이는 것도 인식시키기 어렵다.
잘 보고 갑니다^.^)b