대상: 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 → RGB | cv2.COLOR_BGR2RGB |
| RGB → BGR | cv2.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️⃣ 색상 공간 비교
| 색상 공간 | 특징 | 사용 사례 |
|---|---|---|
| BGR | OpenCV 기본 포맷 | 일반 이미지 입출력 |
| 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” — 이렇게 기억하면 된다.