BGR, RGB, GRAY, YUV: OpenCV에서 색상 공간 제대로 이해하기

대상: OpenCV를 이용해 영상처리, 이미지 필터링, 색상 기반 객체 인식을 하고 싶은 개발자
환경: Ubuntu 20.04 / 22.04, Python 3.x, OpenCV 4.x


1. 문제/주제 요약

OpenCV로 이미지를 처리하다 보면 색이 이상하게 보이거나,
RGB값이 예상과 다르게 나오는 경우가 많다.

예를 들어,

img = cv2.imread("test.jpg")
plt.imshow(img)   # 색이 이상하게 보임!

Matplotlib에서 색이 왜곡되어 보이는 이유는,
OpenCV가 BGR 순서로 이미지를 읽기 때문이다.

이 글에서는 BGR, RGB, GRAY, YUV 등 OpenCV의 주요 색상 공간
개발자 입장에서 정확히 구분하고 변환하는 방법을 정리한다.


2. 원인/배경 설명

🧩 OpenCV의 기본 색상 순서: BGR

OpenCV는 C/C++ 시절부터의 관행으로, 이미지를 BGR (Blue-Green-Red) 순서로 저장한다.
그래서 cv2.imread() 로 이미지를 읽으면 BGR 배열이 반환된다.

반면, 대부분의 라이브러리(Matplotlib, PIL, TensorFlow)는 RGB (Red-Green-Blue) 순서를 사용한다.
→ 이 차이 때문에 시각화나 연산 결과가 예상과 다를 수 있다.


3. 해결 및 변환 방법

1️⃣ BGR ↔ RGB 변환

Matplotlib로 이미지를 올바르게 표시하려면 변환이 필요하다.

import cv2
import matplotlib.pyplot as plt

img_bgr = cv2.imread("test.jpg")
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)

plt.imshow(img_rgb)
plt.show()

요약:

변환코드
BGR → RGBcv2.COLOR_BGR2RGB
RGB → BGRcv2.COLOR_RGB2BGR

2️⃣ BGR ↔ GRAY (흑백 영상)

흑백 영상 처리(에지 검출, threshold 등)에 자주 사용된다.

gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
  • 출력은 2차원 배열 (H×W) 이 된다.
  • 채널이 하나뿐이라, 색상 대신 밝기 정보만 가진다.

흑백으로 변환 후 다시 컬러로 돌리고 싶다면:

gray_bgr = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)

3️⃣ BGR ↔ HSV

HSV는 색상(Hue), 채도(Saturation), 명도(Value)로 색을 표현한다.
색상 기반 객체 탐지(예: 특정 색 마스크)에서 매우 유용하다.

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

예: 파란색 영역만 추출하기

lower_blue = (100, 150, 0)
upper_blue = (140, 255, 255)
mask = cv2.inRange(hsv, lower_blue, upper_blue)
result = cv2.bitwise_and(img_bgr, img_bgr, mask=mask)

4️⃣ BGR ↔ YUV (또는 YCrCb)

YUV는 밝기(Y)와 색차(U/V)를 분리한 색상 공간으로,
비디오 압축이나 카메라 출력 포맷에서 자주 쓰인다.

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

Y(밝기)만 추출하려면:

y_channel = yuv[:, :, 0]

특징:

  • Y 채널만 사용하면 조명 영향을 줄인 분석 가능.
  • U, V 채널은 색상 정보만 가지고 있음.

5️⃣ 색상 공간 비교

색상 공간특징사용 사례
BGROpenCV 기본 포맷일반 이미지 입출력
RGB일반 표준 (디스플레이용)시각화, Matplotlib
GRAY밝기만 보존에지 검출, threshold
HSV색상/채도/명도 분리색상 기반 객체 탐지
YUV (YCrCb)밝기와 색상 분리영상 인코딩, 조명 보정

4. 추가 팁 / 자주 하는 실수

  • plt.imshow() 에 바로 cv2.imread() 결과를 넣지 말 것!
    → 색 왜곡이 생긴다. 반드시 cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 후 표시.
  • GRAY 이미지를 3채널 컬러 이미지처럼 다루면 에러 발생
    → 예: cv2.bitwise_and() 사용 시 shape 불일치.
  • 카메라 입력 시 색상 공간 확인
    → OpenCV VideoCapture는 기본 BGR 프레임을 반환한다.
  • YUV와 YCrCb 혼동 주의
    → OpenCV에서는 cv2.COLOR_BGR2YCrCb 도 존재하며, 내부 인코딩은 약간 다르다.
    → 영상 처리에서는 YCrCb가 더 자주 사용된다.

5. 정리

  • OpenCV는 BGR이 기본 색상 순서이다.
  • Matplotlib, PIL 등은 RGB를 사용하므로 시각화 시 변환 필요.
  • cv2.cvtColor() 함수로 다양한 색상 공간 간 변환이 가능하다.
  • 색상 기반 탐지는 HSV, 밝기 기반 처리는 GRAY, 영상 인코딩은 YUV가 적합하다.

실무 팁: “시각화용이면 RGB, 연산용이면 GRAY, 색 탐지용이면 HSV” — 이렇게 기억하면 된다.

댓글 남기기