히스토그램 매칭

개요

  • 히스토그램 매칭(Histogram Matching)은 한 영상의 히스토그램 분포를 다른 영상(혹은 지정한 분포)의 히스토그램과 유사하게 변환하는 기법.
  • 특정한 사진의 톤을 다른 사진에 적용하는 등 영상의 색감 보정, 영상 합성 시 색조와 밝기를 맞춰 이질감 최소화 등에 활용할 수 있다.

기본 아이디어

  1. 원본 영상과 목표 영상 각각의 히스토그램 계산
  2. 두 영상의 히스토그램을 정규화하여 확률 분포(PDF)로 변환
  3. PDF를 누적하여 CDF 계산
    • PDF만 쓰면 각 픽셀의 상대 빈도만 맞출 수 있지만, 누적 분포 전체를 고려하지 않기 때문에 제대로 된 매칭이 어려우며, 누적 확률을 이용하면 선형 매핑으로 분포를 맞출 수 있기 때문
  4. 원본 영상의 각 픽셀 값에 대해:
    • 원본 CDF 값과 가장 근접하게 가지는 목표 CDF의 픽셀 값으로 매핑

히스토그램 매칭 방법

1. 히스토그램 계산

  • 원본 영상과 목표 영상의 각 히스토그램 계산
SourceReference
# 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) +full

  • 누적 분포 함수 (CDF) +full

# 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 차이
  • 픽셀 값 매핑 결과 +full
SourceReferenceMatched
# 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]