5장. 영상 향상과 학습용 전처리
밝기 조정
컵에 물을 붓는다고 해 봅시다. 컵이 가득 차면 더 부어도 물은 넘쳐흐를 뿐 컵 안의 양은 그대로입니다. cv2.add 는 이 컵처럼 255 에서 멈춥니다. 그런데 NumPy 의 덧셈은 시계 바늘과 같습니다. 12시를 지나면 1시로 돌아가듯, 255 를 넘으면 0 부터 다시 셉니다. 1장 본문에서 맛본 그 차이입니다.
왼쪽 상자가 NumPy 의 덧셈입니다. uint8 은 0~255 만 담으므로 200 + 100 = 300 에서 256 을 뺀 44 가 남습니다. 오른쪽 상자의 cv2.add 는 255 에서 멈춥니다. 여기서 시계 바늘이 NumPy 의 넘침이고, 가득 찬 컵이 OpenCV 의 포화 연산입니다. 빼기도 같습니다. NumPy 로 30 - 50 을 하면 -20 대신 236 이 되고, cv2.subtract 는 0 에서 멈춥니다.
가운데 그림은 NumPy 로 100 을 더한 결과입니다. 원래 밝던 하늘과 구름이 255 를 넘어 0 근처로 되돌아가 거꾸로 검게 되었습니다. 오른쪽의 cv2.add 는 막대가 통째로 오른쪽으로 밀리고, 255 를 넘은 칸이 맨 오른쪽 막대에 쌓였습니다. 밝기를 더하면 히스토그램이 옆으로 밀린다는 것을 눈으로 확인할 수 있습니다.
두 가지 계산 견주기
| 계산 | 쓰는 법 | 200 + 100 | 30 - 50 | 쓰는 곳 |
|---|---|---|---|---|
| NumPy | g + 100, g - 50 | 44 (되돌아감) | 236 (되돌아감) | 넘칠 일이 없을 때 |
| OpenCV | cv2.add(g, 100), cv2.subtract(g, 50) | 255 (멈춤) | 0 (멈춤) | 밝기를 더하고 뺄 때 |
짧은 예시
import cv2
import numpy as np
x = np.array([[200, 100, 30]], dtype=np.uint8)
print(x + 100) # 결과: [[ 44 200 130]] → 200 이 44 로 되돌아갔다
print(cv2.add(x, 100)) # 결과: [[255 200 130]] → 255 에서 멈춘다
print(x - 50) # 결과: [[150 50 236]] → 30 이 236 으로 되돌아갔다
print(cv2.subtract(x, 50)) # 결과: [[150 50 0]] → 0 에서 멈춘다주의할 점
- 밝기를 더하면 원래 밝던 곳은 255 에 몰려 하얗게 날아갑니다. 그 칸들은 모두 255 라 서로 구별할 수 없게 되고, 다시 빼도 되살아나지 않습니다.
- 밝기 조정은 막대를 옮길 뿐 넓히지 않습니다. 대비가 낮은 사진은 밝기를 더해도 여전히 뿌옇습니다.