본문 바로가기
강의 (Lecture)/OpenCV 마스터 with Python (초급)

OpenCV + Python 색 공간 변환과 색상 검출

by codingwalks 2024. 10. 10.
728x90
반응형

안녕하세요. 코딩산책입니다.

이번 글에서는 색 공간(Color Space)에 대해서, 특히 많이 사용되는 RGB, CMYK, HSV, YUV, CIELab 색 공간을 알아보도록 하겠습니다. 추가적으로 OpenCV 라이브러리를 활용하여 이미지에서 특정 색상을 검출하는 방법을 소개하겠습니다. 그리고 각각의 색 공간이 색상 검출에 적합한 이유와 그 적용 분야를 설명하고, 실제 사용 사례도 함께 다뤄보겠습니다. 이를 위해  이미지 파일을 특정 색 공간으로 변환하고, 트랙바를 사용해 실시간으로 색상 범위를 조정하여 원하는 색상을 검출해 보겠습니다. 또한 Python 코드를 통해 쉽게 구현할 수 있는 예제를 단계별로 설명하겠습니다.

 

1. 색 공간(Color Space)과 변환

색 공간은 색을 수학적으로 표현하고, 색상, 채도, 밝기 등을 정의하는 체계입니다. 다양한 색 공간이 존재하며, 각 색 공간은 특정한 작업이나 장치에 최적화되어 있습니다. 대표적으로 RGB, CMYK, HSV, YUV, CIELab 등이 있습니다.

1.1. RGB (Red, Green, Blue)

RGB는 컴퓨터 모니터, 디지털카메라, 스캐너 등에서 널리 사용되는 색 공간으로, 빨강(Red), 초록(Green), 파랑(Blue)의 세 가지 색을 합성하여 다양한 색을 표현합니다. 색상, 채도, 밝기 등이 세 가지 채널로 표현되며, 각 채널 값은 0~255 범위를 가집니다.

  • 장점: 디스플레이와의 호환성이 높으며, 대부분의 이미징 장치에서 기본적으로 사용됩니다.
  • 적용 분야: 디지털 카메라, 모니터, 웹 그래픽에서 주로 사용됩니다.
  • 실제 사례: 웹 사이트에서 RGB로 색을 지정해 이미지를 표현하거나 사용자 인터페이스를 디자인할 때 자주 사용됩니다.

OpenCV 함수:

img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

1.2. CMYK (Cyan, Magenta, Yellow, Black)

CMYK는 주로 인쇄에 사용되는 색 공간입니다. RGB와 달리, 빛을 방출하는 방식이 아니라 빛을 흡수하여 색을 표현합니다. 청록(Cyan), 자홍(Magenta), 노랑(Yellow), 검정(Black)의 네 가지 잉크를 혼합해 색을 만듭니다.

  • 장점: 인쇄 과정에서 색이 정확하게 표현되며, 인쇄물의 컬러 제어에 탁월합니다.
  • 적용 분야: 인쇄, 출판, 패키징 산업에서 주로 사용됩니다.
  • 실제 사례: 잡지, 책, 포스터, 광고지 등에서 정확한 색 표현을 위해 사용됩니다.

OpenCV는 CMYK 변환을 직접 지원하지 않지만, PIL 라이브러리를 통해 변환할 수 있습니다.

from PIL import Image
img = Image.open('image.bmp')
cmyk_image = img.convert('CMYK')

1.3. HSV (Hue, Saturation, Value)

HSV는 색상(Hue), 채도(Saturation), 명도(Value)로 표현되는 색 공간입니다. 색상 정보를 분리하여 명확하게 표현할 수 있어 색상 검출에 자주 사용됩니다. Hue는 색상을, Saturation은 색의 강도, Value는 밝기를 나타냅니다.

  • 장점: 색상, 채도, 밝기를 분리하여 처리할 수 있어 특정 색 검출에 유리합니다. 조명 변화에 강한 면이 있어 안정적인 색상 검출이 가능합니다.
  • 적용 분야: 객체 추적, 컬러 필터링, 비디오 분석 등.
  • 실제 사례: HSV는 비디오 모니터링 시스템, 자동차의 차선 추적 시스템, 비전 기반 로봇에서 많이 사용됩니다.

OpenCV 함수:

img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)

1.4. YUV (Luma, Chrominance)

YUV는 밝기(Luma, Y)와 색차(Chrominance, U와 V)로 구성된 색 공간입니다. 밝기와 색 정보를 분리하여 저장하기 때문에 대역폭을 줄이거나 압축할 수 있어 비디오 압축에 자주 사용됩니다.

  • 장점: 밝기와 색상 정보를 분리함으로써 효율적인 비디오 압축이 가능하며, 비디오에서 노이즈를 줄이는데 효과적입니다.
  • 적용 분야: 비디오 인코딩, 방송 시스템, CCTV 등.
  • 실제 사례: YUV는 MPEG, JPEG 등의 이미지 및 비디오 압축 포맷에서 사용됩니다.

OpenCV 함수:

img_yuv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2YUV)

1.4. CIELab (L, a*, b*)

CIELab는 인간의 시각에 맞춰 설계된 색 공간으로, L은 밝기(lightness), a*b*는 색상 정보를 나타냅니다. CIELab는 장치 독립적 색 공간으로, 실제 인간이 인식하는 색상 차이를 잘 반영합니다.

  • 장점: 인간의 시각에 근접한 색 차이를 표현하기 때문에 색상 일치 작업에 유리합니다.
  • 적용 분야: 색상 보정, 제품의 품질 관리, 색상 매칭.
  • 실제 사례: CIELab는 사진 편집, 의류 디자인, 페인트와 같은 정확한 색상 매칭이 필요한 작업에서 많이 사용됩니다.

OpenCV 함수:

img_lab = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2Lab)

1.5. 채널 분리 (Splitting)와 병합 (Merging)

이미지의 각 색상 채널을 개별적으로 분리하거나 분리된 색생 채널을 하나의 이미지로 병합할 수 있습니다. 예를 들어 RGB의 이미지를 사용할 경우, 채널 분리를 통해 빨간색, 초록색, 파란색 성분을 따로 분석하거나 조작할 수 있습니다. 또한, 이미지에서 각 색상 채널로 분리된 단일 채널 이미지를 다시 하나의 이미지로 병합하여 새로운 이미지를 만들 수 있습니다.

OpenCV에서 채널을 분리하고 병합하는 방법은 cv2.split()과 cv2.merge()를 사용합니다. 예를 들어, BGR 이미지의 각 채널을 분리한 후 특정 채널만 변경하거나, HSV 또는 다른 색 공간으로 변환한 후 색상을 검출할 때 각 채널의 조작이 가능합니다.

import cv2
import numpy as np

image_bgr = cv2.imread('resources/lena.bmp')

# Channel splitting (BGR)
blue_channel, green_channel, red_channel = cv2.split(image_bgr)

# Set the blue channel to 0 and merge
blue_channel[:] = 0
modified_image = cv2.merge([blue_channel, green_channel, red_channel])

cv2.imshow('Modified Image', modified_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

channel splitting
blue channel to 0 (merged image)

 

3. 색상 검출 (Color Segmentation)

이제 검출하려는 색상의 범위를 설정해야 합니다. 여기서는 주황색을 검출하려고 하며, HSV 색 공간에서 해당 색상의 최소 및 최대 범위를 설정합니다. 문제는 주황색의 정확한 HSV 값을 모른다는 점인데, 이를 해결하기 위해 트랙바(Trackbar)를 사용해 실시간으로 값을 조정할 수 있습니다. 추가적으로 Trackbar를 사용하여 다양한 색 공간에서의 실험도 가능하며, 각 색 공간의 특성에 맞게 최적화할 수 있습니다.

import cv2
import numpy as np

# Empty function to be used in the trackbar (for trackbar callbacks)
def empty(a):
    pass

image_bgr = cv2.imread('resources/fruits.bmp')

# HSV color space conversion
image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)

# Create a trackbar window
cv2.namedWindow("Trackbars")

# Trackbar settings (Minimum and maximum values
# for Hue, Saturation, and Value, respectively)
cv2.createTrackbar("Hue Min", "Trackbars", 0, 179, empty) # Hue ranges from 0 to 179
cv2.createTrackbar("Hue Max", "Trackbars", 179, 179, empty)
cv2.createTrackbar("Sat Min", "Trackbars", 0, 255, empty) # Saturation ranges from 0 to 255
cv2.createTrackbar("Sat Max", "Trackbars", 255, 255, empty)
cv2.createTrackbar("Val Min", "Trackbars", 0, 255, empty) # Value is in the range of 0 to 255
cv2.createTrackbar("Val Max", "Trackbars", 255, 255, empty)

while True:
    # Read values from the trackbar
    h_min = cv2.getTrackbarPos("Hue Min", "Trackbars")
    h_max = cv2.getTrackbarPos("Hue Max", "Trackbars")
    s_min = cv2.getTrackbarPos("Sat Min", "Trackbars")
    s_max = cv2.getTrackbarPos("Sat Max", "Trackbars")
    v_min = cv2.getTrackbarPos("Val Min", "Trackbars")
    v_max = cv2.getTrackbarPos("Val Max", "Trackbars")
    
    # Create arrays of minimum and maximum values
    lower = np.array([h_min, s_min, v_min])
    upper = np.array([h_max, s_max, v_max])
    
    # Detect only colors within the HSV range with a mask
    mask = cv2.inRange(image_hsv, lower, upper)
    
    # Apply the mask to the original image
    result = cv2.bitwise_and(image_bgr, image_bgr, mask=mask)
    
    cv2.imshow("Original", image_bgr)
    cv2.imshow("Mask", mask)
    cv2.imshow("Result", result)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
    	break
    
cv2.destroyAllWindows()

trackbar 조정으로 색상 검출

 

4. 결론

이번 글에서는 OpenCV를 이용하여 다양한 색 공간으로의 변환과 채널 분리 및 병합의 유용한 방법을 알아보았습니다. 이미지를 HSV 색 공간으로 변환하고 특정 색상을 검출하는 방법을 확인해 보았습니다. 트랙바를 사용해 실시간으로 색상 범위를 조정하고, 검출된 색상을 마스크를 통해 필터링했습니다. 실제 프로젝트에 적용하기 위해서는 각각의 색 공간의 특성과 변환 방법을 잘 이해하고, 이미지 처리에 적합한 색 공간을 선택하여 색상 검출을 수행하는 것이 중요합니다.

 

해당 포스트가 유용하셨다면 하단의 좋아요와 구독하기 부탁드립니다. ^^

Buy me a coffee

 

[Codingwalks]에게 송금하기 - AQR

[Codingwalks]에게 송금하기 - AQR

aq.gy

★ 모든 내용은 아래의 링크를 참조하였습니다. ★

 

OpenCV: OpenCV-Python Tutorials

Core Operations In this section you will learn basic operations on image like pixel editing, geometric transformations, code optimization, some mathematical tools etc.

docs.opencv.org

728x90
반응형