3장. 디지털 영상과 색공간 변환
그 밖의 색공간
같은 장소를 알려 줄 때도 도로명 주소, 위도·경도, "시청 앞 분수대에서 오른쪽"처럼 여러 방법이 있습니다. 택배 기사에게는 주소가, 비행기에게는 위도·경도가 편합니다. 색도 RGB, HSV 말고 쓰임에 따라 고안된 색공간이 더 있습니다.
그림의 세 색공간은 모두 "밝기"를 숫자 하나로 따로 떼어 적는다는 점이 같습니다. RGB 는 밝기가 세 숫자에 섞여 있어, 그늘이 지면 세 숫자가 함께 바뀝니다. 여기서 장소가 색이고, 주소·위도경도·랜드마크가 색공간입니다.
세 색공간 견주기
| 색공간 | 세 숫자 | 언제 쓰나 | OpenCV 코드 |
|---|---|---|---|
| Lab | L 밝기, a 초록↔빨강, b 파랑↔노랑 | 두 색이 사람 눈에 얼마나 달라 보이는지 잴 때, 색 품질 검사 | cv2.COLOR_BGR2Lab |
| YCrCb | Y 밝기, Cr 빨강 쪽 색차, Cb 파랑 쪽 색차 | 영상 압축(JPEG, Joint Photographic Experts Group 이 만든 형식), 밝기만 따로 다듬을 때 | cv2.COLOR_BGR2YCrCb |
| HLS | H 색상, L 밝기, S 채도 | HSV 와 비슷하게 색을 고를 때 | cv2.COLOR_BGR2HLS |
YCrCb 의 Y 는 앞 절의 흑백 밝기 식과 같은 식으로 구합니다. 그래서 YCrCb 로 바꾼 그림의 첫 채널은 Gray 그림과 거의 같습니다. 바구니 그림에서 견줘 보면 반올림 때문에 1 차이 나는 칸이 몇 개 있을 뿐입니다.
import cv2
import numpy as np
px = np.array([[[0, 0, 255]]], dtype=np.uint8) # 빨강 한 칸(BGR)
# 같은 빨강을 여러 색공간으로 바꿔 숫자를 견준다
for name, code in [("Lab", cv2.COLOR_BGR2Lab), ("YCrCb", cv2.COLOR_BGR2YCrCb), ("HLS", cv2.COLOR_BGR2HLS)]:
print(name, [int(v) for v in cv2.cvtColor(px, code)[0, 0]])
# YCrCb 의 Y(첫 숫자)는 흑백 밝기와 같다
print(int(cv2.cvtColor(px, cv2.COLOR_BGR2GRAY)[0, 0])) # 결과: 76주의할 점
- OpenCV 의 uint8 Lab 은 L(원래 0~100)을 0~255 로 늘리고, a 와 b 에 128 을 더해 담습니다. 다른 자료의 Lab 숫자와 바로 견주지 않습니다.
- 이름의 글자 순서를 정확히 적습니다.
COLOR_BGR2YCrCb와COLOR_BGR2YCR_CB처럼 비슷한 이름이 있으니, 처음 쓸 때 결과를 한 칸 찍어 확인합니다.