https://growth-coder.tistory.com/239
이전 포스팅에서 간단하게 파이썬에서 cv2를 사용하는 방법에 대해서 알아보았다.
이번 포스팅에서는 이미지로부터 원하는 색상을 가진 객체만 인식하는 방법에 대해서 알아보려고 한다.
색을 표현하는 방식
색을 표현하는 방식에는 여러가지가 존재한다.
그 중 자주 사용하는 방식이 RGB, HSV, YUV 인데 이 중 RGB와 HSV만 알아보자.
RGB는 빛의 삼원색인 빨강(Red), 초록(Green), 파랑(Blue)을 이용하여 색을 표현하는 방식이다.
색을 혼합하면 할수록 밝아지는 가산혼합이다.
HSV는 색상(Hue), 채도(Saturation), 명도(Value)를 사용하여 색을 표현하는 방식이다.
우리가 색상을 판단하는 방식은 색을 섞는 RGB 보다는 색상, 명도, 채도를 함께 사용하는 HSV에 가깝다.
그래서 이미지를 검출해낼 때도 RGB보다는 HSV 색 공간으로 변경한 후 사용하는 것이 좋다.
HSV 색 공간을 자세히 보면 원뿔 형으로 되어있고 색상(Hue)이 밑면을 차지하고 있는 모습을 볼 수 있다.
cv2에서는 Hue 값의 범위는 각도(0~179)로 나타내고 Saturation, Value의 경우 (0~255)로 나타낸다.
이 범위를 적절히 조절한다면 우리가 원하는 색상만 검출해낼 수 있다.
Hue 값의 범위에 따른 색은 다음과 같다.
ROI와 mask
ROI는 Region Of Interest의 약자로 이미지에서 우리가 원하는 영역을 의미한다.
mask는 검은색과 흰색으로만 이루어진 이미지로 ROI를 위해서는 mask를 이용하는 것이 좋다.
그렇다면 원하는 색상의 객체만 인식하고 싶을 때 ROI와 mask를 어떤 식으로 활용할 수 있을까?
예를 들어 다음과 같은 이미지에서 초록색 풍선만 골라내고 싶다고 하자.
그렇다면 원하는 HSV 범위를 알아낸 다음 아래와 같은 mask 이미지를 얻어낸다.
이제 원래 색을 알아내야 하기 때문에 bitwise and 연산을 진행하면 아래와 같이 원하는 색상의 이미지만 얻어낼 수 있는 것이다.
HSV 색 공간 범위 알아내기
이제 원하는 색의 HSV 범위를 알아내보자.
이미지에서 색상은 주변 환경(조명, 위치 등등)에 따라 달라지기 때문에 원하는 이미지에서 직접 값을 조절해보면서 구해보는 편이 좋다.
하나씩 값을 대입하는 방식을 사용하면 시간이 오래 걸리기 때문에 cv2에서 제공하는 track bar를 사용해보자.
track bar를 사용하면 아래처럼 bar를 직접 움직이면서 값을 조정할 수 있다.
아래 이미지에서 초록색 풍선의 mask를 구해보자.
import cv2
import numpy as np
# 윈도우 생성
cv2.namedWindow("track bars")
# 윈도우 크기 지정
cv2.resizeWindow("track bars", 640, 240)
# 트랙바가 바뀔 때마다 실행될 함수
def empty(a):
pass
# (트랙바 이름, 윈도우 이름, 첫 값, 최대 값, 함수)
cv2.createTrackbar("Hue Min", "track bars", 0, 179, empty)
cv2.createTrackbar("Hue Max", "track bars", 179, 179, empty)
cv2.createTrackbar("Sat Min", "track bars", 130, 255, empty)
cv2.createTrackbar("Sat Max", "track bars", 255, 255, empty)
cv2.createTrackbar("Val Min", "track bars", 0, 255, empty)
cv2.createTrackbar("Val Max", "track bars", 255, 255, empty)
위 empty 함수는 track bar가 바뀔 때마다 실행할 함수로 지금은 딱히 필요가 없으니 pass를 넣어주자.
그리고 반복문을 통해서 mask 이미지를 생성해보자.
참고로 cv2.imread로 읽어온 이미지는 BGR 색 공간을 사용하기 때문에 이를 cvtColor 메소드를 통해 HSV 색 공간으로 바꿔준다.
while True:
# 색 감지를 위해서 HSV로 변환. HSV는 색상, 채도, 명도의 좌표를 사용
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# (트랙바 이름, 윈도우 이름)
h_min = cv2.getTrackbarPos("Hue Min", "track bars")
h_max = cv2.getTrackbarPos("Hue Max", "track bars")
s_min = cv2.getTrackbarPos("Sat Min", "track bars")
s_max = cv2.getTrackbarPos("Sat Max", "track bars")
v_min = cv2.getTrackbarPos("Val Min", "track bars")
v_max = cv2.getTrackbarPos("Val Max", "track bars")
# track bar를 조절해가면서 이미지가 선명하게 보이는 값 찾아내기
# lower, upper를 통해 해당 범위의 이미지를 출력
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])
mask = cv2.inRange(imgHSV, lower, upper)
cv2.imshow("mask", mask)
if cv2.waitKey(1)&0xFF == ord('q'):
break
다음과 같이 track bar를 조절해가면서 적절한 범위를 찾아내자.
mask를 이용한 연산
mask를 이용하여 여러 연산을 할 수 있다.
그 중 cv2.bitwise_and 연산만 알아보려고 한다.
bitwise_and를 사용하면 mask의 흰색 부분에 해당하는 원본 이미지만 얻어낼 수 있다.
다음과 같은 mask로부터 원본 이미지를 얻어내자.
result = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow("result", result)
이번 포스팅에는 원하는 색상의 객체를 검출할 때 필요한 개념과 cv2 사용법을 알아보았다.
다음 포스팅에는 원하는 색상의 객체의 contour를 그리고 bounding rectangle을 그려보려고 한다.
참고
https://github.com/murtazahassan/Learn-OpenCV-in-3-hours
'공부 > Computer Vision' 카테고리의 다른 글
[Computer Vision] 원하는 색상을 가진 객체의 윤곽선과 외접 사각형 그리기 (0) | 2023.09.08 |
---|---|
[Computer Vision] 파이썬 OpenCV 기본 사용법 (0) | 2023.08.17 |
댓글