본문 바로가기

Python OpenCV

특정 색상 영역 추출하기

🙋‍♂️ 오늘은 특정 색상 영역 추출하기에 대해서 공부한 내용을 정리합니다!

 

이전에 제 블로그에서 썼던 글인 "컬러 영상 처리와 색 공간"이라는 내용에서

RGB 혹은 BGR보다 일반적인 컬러 영상처리에서는 HSV, YCrCb, LAB을 더 많이 사용한다고 작성하였습니다.

이와 관련하여 특정 색상 영역을 추출할 시에 왜 HSV가 더 좋은지 정리해 보도록 하겠습니다.

 

🖼️ 예시 이미지

왼쪽부터 원본이미지와 밝기를 낮춘 이미지

 

위 예시이미지는 원본 이미지와 밝기를 낮춘 이미지로써 초록색을 추출하여 결과를 보도록 하겠습니다.

 

🖼️ 결과 이미지 (BGR)

왼쪽부터 원본이미지와 밝기를 낮춘 이미지의 결과 (BGR)

 

 위 결과 사진과 같이 원본 이미지와 밝기를 낮춘 이미지에서 초록색을 똑같은 Parameter로 추출 시에 일부 영역에서는 초록색을 정확히 추출하지 못하는 현상을 확인할 수 있습니다. 왜일까요?

왜냐하면 BGR의 경우 단순히 빨간색, 초록색, 파란색의 Pixel Value로 분류를 하기 때문에 밝기가 낮은 부분에 대해서는

반영이 어렵습니다. 이번에는 HSV로 동일하게 추출을 해보도록 하겠습니다.

 

🖼️ 결과 이미지 (HSV)

왼쪽부터 원본이미지와 밝기를 낮춘 이미지의 결과 (HSV)

 

위 HSV로 추출한 결과 약간의 차이는 있지만 밝기의 차이와 상관없이 결과가 나온다는 것을 알 수 있습니다. 

 

📝 이 부분은 매우 중요합니다. 왜냐하면 원본 RGB보다는 노이즈가 있는 것처럼 조그마한 픽셀이 남긴 하지만

실제 색 추출 검사기를 만든다고 가정하였을 때 외부 환경에 따라 밝기의 변화가 있을 가능성이 높기 때문에 이런 부분까지 고려한다면 HSV가 훨씬 더 좋은 결과라는 것을 알 수 있습니다.

 

 예제 코드 (위 결과에 대한 소스코드)

import sys
import numpy as np
import cv2
 
# 원본 이미지
src = cv2.imread('candies.png')
# 밝기를 낮춘 이미지
src2 = cv2.imread('candies2.png')
 
if src is None or src2 is None:
    print('Image load failed!')
    sys.exit()
 
# 원본 이미지에서 HSV로 변경한 이미지
src_hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
# 밝기를 낮춘 이미지에서 HSV로 변경한 이미지
src_hsv2 = cv2.cvtColor(src2, cv2.COLOR_BGR2HSV)
 
# 원본 이미지의 결과
rst1 = cv2.inRange(src, (01280), (100255100))
# 밝기를 낮춘 이미지의 결과
rst2 = cv2.inRange(src2, (01280), (100255100))
# 원본 이미지에서 HSV로 변경 후 결과
rst3 = cv2.inRange(src_hsv, (501500), (80255255))
# 밝기를 낮춘 이미지에서 HSV로 변경 후 결과
rst4 = cv2.inRange(src_hsv2, (501500), (80255255))
 
cv2.imshow('src', src)
cv2.imshow('src2', src2)
cv2.imshow('rst1', rst1)
cv2.imshow('rst2', rst2)
cv2.imshow('rst3', rst3)
cv2.imshow('rst4', rst4)
cv2.waitKey()
 
cv2.destroyAllWindows()
cs

 

 예제 코드 (Trackbar를 이용한 HSV 별 검출 결과 소스코드)

import sys
import numpy as np
import cv2
 
src = cv2.imread('candies.png')
 
if src is None:
    print('Image load failed!')
    sys.exit()
 
src_hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
 
def on_trackbar(pos):
    hmin = cv2.getTrackbarPos('H_min''dst')
    hmax = cv2.getTrackbarPos('H_max''dst')
 
    dst = cv2.inRange(src_hsv, (hmin, 1500), (hmax, 255255))
    cv2.imshow('dst', dst)
 
cv2.imshow('src', src)
cv2.namedWindow('dst')
 
cv2.createTrackbar('H_min''dst'50179, on_trackbar)
cv2.createTrackbar('H_max''dst'80179, on_trackbar)
on_trackbar(0)
 
cv2.waitKey()
 
cv2.destroyAllWindows()
cs

 

🖼️ 결과 이미지

왼쪽부터 원본이미지와 노란색만 추출한 결과

 

마지막으로 만약 빨간색을 추출하고 싶은데 HSV의 특성으로 인하여 HUE 값이

0 ~ 13, 169 ~ 172와 같이 두 가지일 경우 아래와 같이 소스코드를 작성하여

이미지를 추출하면 더 좋은 결과를 도출할 수도 있으니 참고하시면 좋을 것 같습니다.

 

 예제 코드 (OR 연산자를 이용한 이미지 추출)

import sys
import numpy as np
import cv2
 
# 원본 이미지
src = cv2.imread('candies.png')
 
if src is None:
    print('Image load failed!')
    sys.exit()
 
# 원본 이미지에서 HSV로 변경한 이미지
src_hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
013 까지의 hue 값을 추출한 결과
rst = cv2.inRange(src_hsv, (01500), (13255255))
169172 까지의 hue 값을 추출한 결과
rst2 = cv2.inRange(src_hsv, (1691500), (172255255))
 
# or 연산자를 사용하여 이미지 합성
rst3 = cv2.bitwise_or(rst, rst2)
 
cv2.imshow('src', src)
cv2.imshow('rst', rst3)
cv2.waitKey()
 
cv2.destroyAllWindows()
cs

 

본 학습 내용은 "OpenCV를 활용한 컴퓨터비전과 딥러닝" 을 참고하였음을 알려드립니다.

'Python OpenCV' 카테고리의 다른 글

영상의 확대와 축소  (0) 2024.02.12
영상의 이동 변환과 전단 변화  (2) 2024.02.10
히스토그램 분석  (0) 2024.02.09
컬러 영상 처리와 색 공간  (0) 2024.02.09
OpenCV 그리기 함수  (0) 2024.02.04