4장. 채널 처리와 히스토그램 분석
컬러 히스토그램
과일 가게의 하루 판매 장부를 사과, 귤, 라임으로 나눠 따로 적으면 어느 과일이 잘 팔렸는지 보입니다. 컬러 그림도 채널마다 히스토그램을 따로 세면 어느 색이 밝게, 많이 들어 있는지 보입니다. 세 히스토그램을 한 그래프에 줄 세 개로 겹쳐 그리는 것이 컬러 히스토그램입니다.
위가 노을, 아래가 호수입니다. 그래프의 파랑 줄이 B 채널, 초록 줄이 G 채널, 빨강 줄이 R 채널이고, 밝기를 8 씩 묶어 그렸습니다. 노을은 빨강 줄이 오른쪽(밝은 쪽)까지 퍼져 있고 파랑 줄은 왼쪽에 몰려 있습니다. 호수는 거꾸로 파랑 줄이 오른쪽 끝에 높이 솟았습니다. 여기서 과일별 장부가 채널별 히스토그램이고, 잘 팔린 과일이 오른쪽까지 뻗은 줄입니다.
컬러 히스토그램에서 읽을 것
| 보이는 모습 | 읽는 법 |
|---|---|
| 한 색의 줄만 오른쪽에 있다 | 그 색이 강한 사진(색 경향) |
| 세 줄이 거의 겹친다 | 회색에 가까운 사진, 쏠림이 적다 |
| 세 줄이 모두 왼쪽에 있다 | 색과 관계없이 어두운 사진 |
| 어느 줄이 255 에 높이 솟았다 | 그 색이 가득 차 넘친 곳(포화)이 있다 |
짧은 예시
import cv2
img = cv2.imread("ch04_scenes/lake.png")
# 채널마다 따로 센다. 둘째 인자 [ch] 가 채널 번호다
for ch, name in enumerate(["B", "G", "R"]):
# ravel(): 판에 따라 (256, 1) 일 수도 있는 결과를 한 줄로 편다
hist = cv2.calcHist([img], [ch], None, [256], [0, 256]).ravel()
# argmax: 가장 큰 값의 자리. 픽셀이 가장 많은 밝기를 찾는다
peak = int(hist.argmax())
print(f"{name} 채널: 픽셀이 가장 많은 밝기 {peak}, 그 픽셀 수 {int(hist[peak])}")argmax 는 argument of the maximum(가장 큰 값의 자리)을 줄인 이름입니다. 호수 그림에서는 B 150, G 120, R 100 에 픽셀이 가장 많이 몰려 있어, 파랑이 가장 밝은 쪽에 있습니다.
주의할 점
- 채널 번호는 BGR 순서입니다. 줄 색을 정할 때 0번을 빨강으로 칠하면 해석이 뒤집힙니다.
- 이 장의 그림은 도형을 한 색으로 칠해 만들어서, 256개 구간으로 세면 몇몇 밝기에만 막대가 뾰족하게 솟습니다. 실제 사진은 더 매끈한 언덕 모양이 됩니다. 뾰족해서 읽기 어려우면 구간을 32개쯤으로 줄여 봅니다.