히스토그램 매칭
개요
- 히스토그램 매칭(Histogram Matching)은 한 영상의 히스토그램 분포를 다른 영상(혹은 지정한 분포)의 히스토그램과 유사하게 변환하는 기법.
- 특정한 사진의 톤을 다른 사진에 적용하는 등 영상의 색감 보정, 영상 합성 시 색조와 밝기를 맞춰 이질감 최소화 등에 활용할 수 있다.
기본 아이디어
- 원본 영상과 목표 영상 각각의 히스토그램 계산
- 두 영상의 히스토그램을 정규화하여 확률 분포(PDF)로 변환
- PDF를 누적하여 CDF 계산
- PDF만 쓰면 각 픽셀의 상대 빈도만 맞출 수 있지만, 누적 분포 전체를 고려하지 않기 때문에 제대로 된 매칭이 어려우며, 누적 확률을 이용하면 선형 매핑으로 분포를 맞출 수 있기 때문
- 원본 영상의 각 픽셀 값에 대해:
- 원본 CDF 값과 가장 근접하게 가지는 목표 CDF의 픽셀 값으로 매핑
히스토그램 매칭 방법
1. 히스토그램 계산
- 원본 영상과 목표 영상의 각 히스토그램 계산
Source | Reference |
---|---|
![]() | ![]() |
![]() | ![]() |
# 1. 히스토그램 계산 (Grayscale Image)
src_hist = cv2.calcHist([src], [0], None, [256], [0,256])
ref_hist = cv2.calcHist([ref], [0], None, [256], [0,256])
2. PDF 및 CDF 계산
-
정규화된 히스토그램 (확률 분포 함수, PDF)
-
누적 분포 함수 (CDF)
# 2. 정규화 (PDF 형태)
src_pdf = cv2.normalize(src_hist, None, alpha=1.0, norm_type=cv2.NORM_L1).flatten()
ref_pdf = cv2.normalize(ref_hist, None, alpha=1.0, norm_type=cv2.NORM_L1).flatten()
# 3. CDF 계산 (NumPy 누적합)
src_cdf = np.cumsum(src_pdf)
ref_cdf = np.cumsum(ref_pdf)
3. 픽셀 값 매핑
- 원본 영상과 목표 영상의 CDF 차이
- 픽셀 값 매핑 결과
Source | Reference | Matched |
---|---|---|
![]() | ![]() | ![]() |
# 4. 매핑 테이블 생성
mapping = np.zeros(256, dtype=np.uint8)
# 각 src 픽셀 값에 대해 가장 가까운 ref 픽셀 값을 찾음
for i in range(256):
diff = np.abs(ref_cdf - src_cdf[i])
mapping[i] = np.argmin(diff)
# 5. 매핑 적용 (NumPy 배열 인덱싱(Array indexing) 활용)
matched = mapping[src]