5장. 영상 향상과 학습용 전처리
영상 향상이란
사진관의 보정을 떠올려 봅시다. 사진사는 같은 사진을 두고 "조금 밝게", "또렷하게", "어두운 얼굴만 살짝 밝게"처럼 여러 손질 가운데 하나를 고릅니다. 무엇을 할지는 사진이 어떤 상태인지에 따라 정합니다. 영상 향상도 같습니다. 4장의 진단 결과를 보고 알맞은 손질을 고릅니다.
그림의 네 상자가 이 장에서 배울 네 가지 손질입니다. 밝기는 모든 칸에 같은 값을 더하고, 대비는 곱해서 차이를 넓히고, 감마는 어두운 쪽을 더 많이 올리고, 평활화는 막대를 고르게 폅니다. 여기서 사진사의 손질 하나하나가 이 상자 하나하나이고, "사진의 상태"가 4장의 평균과 표준편차입니다. 비유와 다른 점이 하나 있습니다. 사진사는 눈으로 보고 정하지만, 우리는 숫자로 진단하고 숫자로 고칩니다.
4장의 어두운 거리 장면(ch04_exposure/dark.png)을 세 가지로 고쳐 보았습니다. 아래 줄은 각 그림의 히스토그램입니다. 밝기를 더하면 막대 묶음이 모양 그대로 오른쪽으로 옮겨 가서 평균은 42 에서 122 로 오르지만 표준편차는 24 그대로입니다. 감마 0.5 는 막대를 옮기면서 조금 벌려 놓고, 평활화는 막대를 0~255 전체로 흩어 표준편차가 76 이 됩니다. 손질마다 히스토그램이 바뀌는 모양이 다릅니다.
손질과 히스토그램의 변화
| 손질 | 하는 일 | 히스토그램의 변화 | 이 장의 함수 |
|---|---|---|---|
| 밝기 | 모든 칸에 같은 값을 더한다 | 모양 그대로 옆으로 옮겨 간다 | cv2.add, cv2.subtract |
| 대비 | 모든 칸에 같은 값을 곱한다 | 넓어지거나 좁아진다 | cv2.convertScaleAbs, cv2.normalize |
| 감마 | 어두운 쪽과 밝은 쪽을 다르게 바꾼다 | 한쪽이 더 많이 벌어진다 | cv2.LUT |
| 평활화 | 누적 비율로 다시 매긴다 | 0~255 에 고르게 퍼진다 | cv2.equalizeHist, cv2.createCLAHE |
짧은 예시
import cv2
# 4차시의 어두운 거리 장면을 흑백으로 읽는다(연습용 가상 그림)
gray = cv2.imread("ch04_exposure/dark.png", cv2.IMREAD_GRAYSCALE)
print(round(float(gray.mean()), 1), round(float(gray.std()), 1)) # 결과: 41.9 23.8
# 모든 칸에 80 을 더한다. cv2.add 는 255 를 넘으면 255 에서 멈춘다
brighter = cv2.add(gray, 80)
print(round(float(brighter.mean()), 1), round(float(brighter.std()), 1)) # 결과: 121.9 23.8평균은 80 만큼 올랐고 표준편차는 그대로입니다. 막대 묶음이 통째로 옆으로 옮겨 갔을 뿐, 퍼진 너비는 바뀌지 않았다는 뜻입니다.
주의할 점
- 손질은 진단에 맞춰 고릅니다. 이미 정상인 사진에 평활화를 하면 오히려 너무 진해질 수 있습니다.
- 손질한 뒤에는 4장의 숫자(평균, 표준편차, 양끝 비율)를 다시 재어 정말 나아졌는지 확인합니다.