OpenCV 비전 실무5장 · 영상 향상과 학습용 전처리9 / 21← 이전목차다음 →MetaContents

5장. 영상 향상과 학습용 전처리

컬러 사진의 평활화

그림을 세 사람이 나눠 칠한다고 해 봅시다. 한 사람은 파랑, 한 사람은 초록, 한 사람은 빨강만 맡아서 저마다 "내 색을 고르게 진하게" 칠하면, 셋이 맞춰 두었던 색의 비율이 깨져 엉뚱한 색이 나옵니다. B, G, R 채널마다 따로 평활화하면 이런 일이 생깁니다. 3장에서 본 YCrCb 나 HSV 처럼 밝기를 따로 떼어 둔 색공간으로 바꾸면, 밝기 채널 하나만 평활화하고 색은 건드리지 않을 수 있습니다.

B, G, R 채널마다 평활화하는 방법과 밝기 채널만 평활화하는 방법을 견준 그림

왼쪽 상자는 채널 세 장을 저마다 평활화하는 방법, 오른쪽 상자는 YCrCb 의 Y(밝기)만 평활화하는 방법입니다. 여기서 세 사람이 저마다 칠하는 것이 채널마다 평활화이고, 한 사람이 조명의 세기만 바꾸는 것이 밝기 채널만 평활화입니다. 3장에서 YCrCb 의 Y 가 흑백 밝기와 같은 식으로 구해진다고 했습니다.

어둑하고 누런빛인 과일 상자 원본, B G R 채널마다 평활화한 결과, Y 채널만 평활화한 결과

가운데 그림은 채널마다 평활화한 결과입니다. 누런 벽이 하늘색으로, 나무 상자가 회색으로 바뀌었습니다. 오른쪽은 Y 채널만 평활화한 결과로, 벽과 상자의 색 계열은 원본 그대로 두고 밝기만 펴졌습니다. 그림은 노란 불빛 아래의 과일 상자를 도형으로 그린 가상의 그림(ch05_fruit_dim.png)입니다.

컬러 평활화의 세 방법

방법순서색(H)쓰는 곳
채널마다split → 세 장 모두 equalizeHist → merge바뀐다쓰지 않는 것이 좋다
YCrCb 의 YBGR2YCrCb → 0번 채널만 → YCrCb2BGR거의 그대로밝기를 고르게 펼 때
HSV 의 VBGR2HSV → 2번 채널만 → HSV2BGR그대로색상을 꼭 지켜야 할 때

짧은 예시

Python
import cv2

img = cv2.imread("ch05_fruit_dim.png")

# BGR → YCrCb 로 바꾸고, 0번 채널(Y, 밝기)만 평활화한 뒤 다시 BGR 로
ycc = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)
ycc[:, :, 0] = cv2.equalizeHist(ycc[:, :, 0])
fixed = cv2.cvtColor(ycc, cv2.COLOR_YCrCb2BGR)

# 왼쪽 위 벽 칸(세로 10, 가로 10)의 색상 H 를 견준다
def hue(im):
    return int(cv2.cvtColor(im, cv2.COLOR_BGR2HSV)[10, 10, 0])

each = cv2.merge([cv2.equalizeHist(c) for c in cv2.split(img)])
print(hue(img), hue(each), hue(fixed))   # 결과: 13 91 19

벽의 색상 H 는 원본 13(주황 계열)입니다. 채널마다 평활화하면 91(청록 계열)로 크게 바뀌고, Y 만 평활화하면 19 로 같은 주황 계열에 머뭅니다.

주의할 점

  • cv2.COLOR_YCrCb2BGR 처럼 되돌리는 변환을 잊으면, YCrCb 숫자를 BGR 로 알고 띄워 색이 엉뚱하게 나옵니다.
  • Y 만 펴도 아주 어둡던 곳은 더 어두워질 수 있습니다. 평활화는 순서대로 자리를 다시 매기므로, 밝은 칸이 많은 사진에서는 어두운 칸이 앞자리로 밀려납니다.
← 이전 절5장 · 히스토그램 평활화다음 절 →5장 · CLAHE