본문 바로가기

PyImageSearch

OpenCV - Histogram Equalization

 

 Histogram Equalization 이란?

 

이미지의 히스토그램이 특정영역에 너무 집중되어 있으면 contrast가 낮아 좋은 이미지라고 할 수 없음

따라서 좌측 히스토그램 처럼 특정 영역에 집중되어 있는 분포를 오른쪽 처럼 골고루 분포하도록 하는 작업

 

 

1. Numpy로 CDF값을 이용해서 균일화 작업 하기

import cv2
import numpy as np
from matplotlib import pyplot as plt


img = cv2.imread('images/hist_unequ.jpg');

hist, bins = np.histogram(img.flatten(), 256,[0,256])

cdf = hist.cumsum()

# cdf의 값이 0인 경우는 mask처리를 하여 계산에서 제외
# mask처리가 되면 Numpy 계산에서 제외가 됨
# 아래는 cdf array에서 값이 0인 부분을 mask처리함
cdf_m = np.ma.masked_equal(cdf,0)

#History Equalization 공식
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())

# Mask처리를 했던 부분을 다시 0으로 변환
cdf = np.ma.filled(cdf_m,0).astype('uint8')

img2 = cdf[img]
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.subplot(122),plt.imshow(img2),plt.title('Equalization')
plt.show()

출처 : https://opencv-python.readthedocs.io/en/latest/doc/20.imageHistogramEqualization/imageHistogramEqualization.html

 

2. OpenCV cv2.equalizeHist 함수 사용하기

equalized = cv2.equalizeHist(gray)

전체적으로 밝아지면서 인물들 디테일은 살아났지만 이미 밝은 부분은 데이터가 많이 소실됨

 

  • 정의: 특정 밝기(Intensity)에 치중된 픽셀 분포를 고르게 펼쳐 어두운 부분은 더 어둡게, 밝은 부분은 더 밝게 만들어 이미지 전체의 대비를 높임
  • 장점: 간단하고 빠르게 이미지의 대비를 개선할 수 있음
  • 단점:
    • 전역적인 적용: 이미지 전체에 동일한 변환을 적용하기 때문에, 이미지의 특정 영역에서는 오히려 대비가 감소하거나 노이즈가 증폭될 수 있음.
    • 과도한 밝기 증가: 이미지의 밝은 영역이 너무 밝아져 정보가 손실될 수 있다

 

 

2. CLAHE - Contrast Limited Adaptive Histogram Equalization

밝아져야 할 부분만 적절히 밝아진 것 확인가

  • 정의: 입력 영상을 M×N 크기의 타일(grid)로 분할한 뒤, 각 타일마다 평준화를 적용하고 경계에서 부드럽게 이어붙이는 방식으로 동작
  • 장점 : 이미지 각 영역의 특성에 맞게 대비를 향상시켜 더 자연스러운 결과 출력, 노이즈 증폭 제한

 

2-1. cv2.createCLAHE 함수

clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
equalized = clahe.apply(gray)

 

  • clipLimit(대비 제한 임계값) :  값이 클수록 국소 대비가 크게 증폭되어 노이즈가 늘어날 수 있음,  2–5 범위 권장

clip 값이 커질수록 대비가 커짐

 

  • tileGridSize : 타일 크기를 지정. 예를 들어 (8,8)이면 영상을 8×8 격자로 나누어 각 타일별 평준화를 수행

 

tile 크기가 커질수록 세밀해짐 = 노이즈가 많아짐

 

 

3. Multi-channel (color) Image Equalization

3-1. RGB 채널을 분리하여 equalization 후 합치기

구현이 훨씬 직관적이지만 색조가 변할 수 있음 (아래 예시 참조)

# B, G, R 채널 분리
(b, g, r) = cv2.split(image)

# 각 채널에 히스토그램 평준화 적용
b_eq = cv2.equalizeHist(b)
g_eq = cv2.equalizeHist(g)
r_eq = cv2.equalizeHist(r)

# 평준화된 채널 병합
equalized = cv2.merge([b_eq, g_eq, r_eq])

결과 사진을 보면 대비가 극대화 되었지만, 색조가 변함

 

3-2. YCrCb 색공간을 사용

  • BGR/RGB처럼 R-G-B 3가지 채널이 모두 밝기와 색 정보를 섞어 담고 있는 것과 달리
    밝기 정보와 색차 정보(chrominance)를 분리해 표현하는 컬러 모델.
  • 장점
    • 밝기채널(Y)만 조작하면 색조에 영향 없이 이미지 전반의 대비를 개선 가능 : 영상 컬러 보정에서 많이 쓰임
    • 사람 눈이 색 정보보다는 밝기 정보에 민감하므로 Cr/Cb 채널의 해상도를 낮춰 품질저하를 최소하하면서 압축률 향상 가능
    • 색차 채널만 선택적으로 조절해 색상 강조나 톤 매핑을 할 수 있음
  • 채널구성
    • Y (Luma)
      • 픽셀의 밝기(명암) 정보만 담고 있음
      • 인간 눈이 밝기 변화에는 민감하지만 색 변화에는 덜 민감하다는 점을 활용해, 밝기만 별도로 다루면 압축 효율이나 대비 조정 시 장점이 큼
    • Cr (Chroma-Red)
      • “빨강 성분 – 밝기” 차이 값을 저장합니다.
      • 기본적으로 Cr = R – Y 형태로 계산되며, 양(+)일수록 붉은 기운이 강함
    • Cb (Chroma-Blue)
      • “파랑 성분 – 밝기” 차이 값을 저장합니다.
      • Cb = B – Y 형태로 계산되며, 양(+)일수록 푸른 기운이 강함
# 1) BGR → YCrCb 변환
ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)

# 2) Y 채널만 히스토그램 평준화
y_channel, cr, cb = cv2.split(ycrcb)
y_eq = cv2.equalizeHist(y_channel)
ycrcb_eq = cv2.merge([y_eq, cr, cb])

# 3) YCrCb → BGR 재변환
equalized = cv2.cvtColor(ycrcb_eq, cv2.COLOR_YCrCb2BGR)
  1.  

색조의 변화 없이 대비만 증가됨

 


 

**참고

*OpenCV의 컬러채널 순서는 (B,G,R)

 matplotlib의 컬러채널 순서는 (R,G,B) 이므로 결과 출력할 때 cv2.COLOR_BGR2RGB로 변환하기

orig_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
eq_rgb   = cv2.cvtColor(equalized, cv2.COLOR_BGR2RGB

# matplotlib으로 나란히 출력
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].imshow(orig_rgb)
axes[0].set_title("Original")
axes[0].axis("off")

axes[1].imshow(eq_rgb)
axes[1].set_title("Equalized")
axes[1].axis("off")

plt.tight_layout()
plt.show()

 

 

 


출처

https://pyimagesearch.com/2021/02/01/opencv-histogram-equalization-and-adaptive-histogram-equalization-clahe/?_ga=2.205267347.2009553045.1749964459-254784589.1749433426

 

OpenCV Histogram Equalization and Adaptive Histogram Equalization (CLAHE) - PyImageSearch

In this tutorial, you will learn to perform both histogram equalization and adaptive histogram equalization with OpenCV.

pyimagesearch.com

 

참고자료

https://opencv-python.readthedocs.io/en/latest/doc/20.imageHistogramEqualization/imageHistogramEqualization.html

 

 

 

'PyImageSearch' 카테고리의 다른 글

CDF(누적 분포 함수)  (0) 2025.06.16
OpenCV - Histogram Matching  (0) 2025.06.16
OpenCV - Image Histograms  (0) 2025.06.15
OpenCV - Edge detection  (0) 2025.06.14
OpenCV - Image Gradients(엣지검출)  (0) 2025.06.13