많은 사람들에게 이미지 처리는 어렵고 부담스러운 작업처럼 느껴질 수 있지만, 생각만큼 어렵지 않습니다. 이 튜토리얼에서는 Python과 OpenCV를 활용해 기본적인 색상 감지 방법을 단계별로 살펴보겠습니다.
컴퓨터에서 색상은 어떻게 표현될까?
컴퓨터에서 색상은 컬러 스페이스(Color Space) 또는 컬러 모델을 통해 표현됩니다. 이는 다양한 색상의 범위를 숫자 튜플 형태로 기술하는 체계입니다.
모든 색상을 하나씩 다루기보다는, 가장 널리 사용되는 두 가지 색 공간인 RGB(Red, Green, Blue)와 HSV(Hue, Saturation, Value)에 대해 알아보겠습니다.
RGB 색 공간
RGB는 색상을 세 가지 구성 요소의 튜플로 표현합니다. 각 구성 요소는 0부터 255 사이의 값을 가지며, (0, 0, 0)은 검정색, (255, 255, 255)는 흰색을 나타냅니다. 예를 들어 화면에 순수한 파란색 픽셀을 표시하려면 R 값은 0, G 값은 0, B 값은 255가 됩니다.
아래는 RGB로 표현한 색상의 몇 가지 예시입니다.
| 색상 | RGB 값 |
|---|---|
| 빨강 | 255, 0, 0 |
| 주황 | 255, 128, 0 |
| 분홍 | 255, 153, 255 |
HSV 색 공간
HSV 역시 픽셀을 세 가지 매개변수로 표현하지만, 그 대상은 색조(Hue), 채도(Saturation), 명도(Value)입니다. RGB와 달리 HSV는 원색의 조합으로 픽셀을 나타내지 않고, 대신 색조, 즉 픽셀의 고유한 색이나 음영을 사용합니다.
- 채도(Saturation): 색의 강도를 나타냅니다. 0은 무채색 상태, 255는 최대 강도를 의미합니다.
- 명도(Value): 색이 얼마나 밝은지 또는 어두운지를 결정합니다.
원하는 색상 감지하기
먼저 작업에 사용할 이미지를 준비합니다.

이제 이미지가 준비되었으니 본격적으로 재미있는 부분을 시작해 보겠습니다. 자주 사용하는 Python 편집기나 IDE를 열고 따라와 주세요.
import cv2
import numpy as np
import imutils
img = cv2.imread('color2.jpg')위 코드에서 처음 두 줄은 필요한 모듈을 임포트하는 부분입니다. 세 번째 줄에서는 이미지 크기 조절과 색상 범위 탐색에 유용한 imutils 모듈을 불러오고 있습니다. 네 번째 줄에서 이미지 파일을 열어 변수에 저장합니다.
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
이제 이미지를 HSV 이미지로 변환합니다. HSV는 색상과 명암 강도를 서로 분리해 다룰 수 있어 색상 감지 작업에 매우 유용하기 때문입니다.
lower_range = np.array([110,50,50]) upper_range = np.array([130,255,255])
다음으로 감지하려는 파란색의 하한(lower)과 상한(upper) 값을 정의합니다. 이 한계값을 찾으려면 imutils 라이브러리에 포함된 range-detector 스크립트를 활용할 수 있습니다. 찾은 값들은 NumPy 배열에 담아 사용합니다.
mask = cv2.inRange(hsv, lower_range, upper_range)
여기서 지정한 파란색 범위에 해당하는 마스크(mask)를 생성합니다. 마스크는 이미지 중 특정 영역만을 나타내는 일종의 필터입니다. 이 코드는 HSV 이미지를 훑으면서 하한 범위와 상한 범위 사이에 속하는 색상을 찾아내고, 일치하는 영역만 마스크 변수에 저장합니다.
cv2.imshow('image', img)
cv2.imshow('mask', mask)
while(True):
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()마지막으로 원본 이미지와 마스크 이미지를 나란히 출력해 차이를 확인할 수 있습니다. 코드에서 0xFF의 의미가 궁금하다면 관련 문서를 참고하세요. 프로그램은 사용자가 'Esc' 키를 누를 때까지 대기하며, Esc 입력 시 종료되고 모든 창을 닫아 리소스를 정리합니다.
최종 전체 코드
import cv2
import numpy as np
import imutils
img = cv2.imread('color2.jpg')
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_range = np.array([110,50,50])
upper_range = np.array([130,255,255])
mask = cv2.inRange(hsv, lower_range, upper_range)
cv2.imshow('image', img)
cv2.imshow('mask', mask)
while(True):
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()실행 결과

위 결과 이미지를 보면 마스크 안에 몇 개의 검은 점들이 보입니다. 이것이 바로 노이즈(noise)입니다. 노이즈 제거에는 모폴로지 연산(morphological operations)이나 블러링 같은 후처리 기법을 추가로 적용하면 더 깔끔한 결과를 얻을 수 있습니다.