본문 바로가기
Lecture/Image Information Processing

히스토그램 평활화(Histogram Equalization)

by YUNZEE 2023. 11. 6.
728x90

 

히스토그램 평활화 기법(좁혀있는 범위를 넓혀서 고르게 해 줌)

- 어두운 환경에서 촬영된 이미지의 히스토그램을 조정하여 빈약한 분포의 주어진 이미지의 히스토그램의 분포를 균일하게 만들어 줌

- 원 이미지의 히스토그램과 유사하게 하면서 명암의 분포를 좀 더 균일화하는 작업

= 이미지의 밝기 분포를 재분배하여 명암 대비를 최대화

특징

1. 명암 대비 조정을 자동으로 수행

2. 각 명암의 빈도는 변경하지 않음(항상 좋은 결과만 나오는 것은 아님)

3. 검출 특성이 좋은 이미지만 출력하지는 않지만 이미지의 검출 특성을 증가시킴

 

좁혀있는 그래프를 Equalization을 통해 고르게 분포해

히스토그램 평활화 기법

이상적인 상황(ideal)

- 이미지 모든 밝기의 픽셀들의 분포와 빈도수가 0부터 L까지 고르게 나타남

pdf(probability density function): 확률밀도함수(0~1)

cdf(cumulative distribution function): 누적분포함수(0~1)

 

pdf와 cdf의 값을 확인할 수 있음(확률적으로 표현하기 때문에 0~1까지 나옴)

 

1단계: 히스토그램 생성

빈도수 hist [i]에서의 히스토그램 생성

hist[0]이라 하면 표를 한바퀴 돌면서 0을 찾아 다니면 0이 두개인 것을 확인할 수 있다.

가장 큰 밝기 값이 4이므로 전체적으로 왼쪽으로 치우침

 

2단계: 누적분포함수 cdf생성

cdf [0]: {hist [0]} / 16(h*w 하면 16 나옴)

cdf [1]: {hist [0] + hist [1]} -> [2+5]/16

.

.

cdf [4]: {hist [0] + hist [1] + hist [2] + hist [3] + hist [4]} -> {2+5+4+3+2}/16 

 

3단계: 맵(map) 생성

map [i] = cdf [i] * (L-1)

map [0]: cdf [0]*(L-1) -> 2/16*7=0.875 -> round(0.875) = 1

map [1]: cdf [1]*(L-1) -> 7/16*7=3.0625-> round(3.0625)= 3

.

.

.

4단계: 픽셀값 매핑(mapping)

g(x, y) = map(f(x, y))

f(0,0)에 있는 값 2는 intensity에 있는 자리에 map 값이 5인 것을 확인하고

g 값에 5를 넣어준다. 그런 식으로 f에서 g의 값으로 변환하는 걸 볼 수 있다.

 

히스토그램 평활화 기법은 값을 넓고 고르게 분포해 주는 것

 

jupyter를 이용한 히스토그램 평활화 기법

# 기본 라이브러리 불러오기
import cv2
import numpy as np
import matplotlib.pyplot as plt

 

# CalcHistogram(f,num_bin) 정의하기
def CalcHistogram(f,num_bin):
    h,w = f.shape
    hist = np.zeros(num_bin)
    for x in range(h):
        for y in range(w):
            #hist[f[x,y]] = hist[f[x,y]] + 1
            hist[f[x,y]] += 1
    return hist
User parameter 정의하기
bit = 3 #주어진 이미지의 비트 수
num_bin = 2 ** bit # 성적의 분포, 사용자 결정
L = 2 ** bit #밝기의 단계, 비트 수에 따라 무조건 결정

3비트(3bit) 이미지 생성하기
f = np.array([[2,4,4,3],[2,1,3,3],[1,0,1,2],[0,1,1,2]])
h,w = f.shape
print(f)

 

(1단계) f에 대한 히스토그램 생성하기
hist_f = CalcHistogram(f, num_bin)
print(hist_f)

(2단계) 히스토그램에 대한 누적분포함수 생성하기(cdf_f)
cdf_f = np.zeros(num_bin)
N = h*w
for i in range(L):
    cdf_f[i] = np.sum(hist_f[0:i+1])/N
#     print(hist_f[0:i+1])
print(cdf_f)

(3단계) 맵 생성하기(map_f)
map_f = np.zeros(num_bin)
for i in range(L):
    map_f[i] = np.round(cdf_f[i]*(L-1))
print(map_f)

(4단계) 반복문을 이용하여 mapping 하기(g)
g = np.zeros((h, w))
for x in range(h):
    for y in range(w):
        g[x,y] = map_f[f[x, y]]
g = np.uint8(g)        
print(g)

 

결과 이미지(g)에 대한 히스토그램 생성하기(hist_g)
hist_g = CalcHistogram(g, num_bin)
print(hist_g)

matplotlib.pyplot을 이용하여 결과 히스토그램 출력하기

plt.figure(figsize=(5,6))
plt.subplot(2,2,1); plt.imshow(f, cmap='gray');plt.axis('off')
plt.subplot(2,2,2); plt.imshow(g, cmap='gray');plt.axis('off')
plt.subplot(2,2,3); plt.bar(np.arange(L), hist_f)
plt.subplot(2,2,4); plt.bar(np.arange(L), hist_g)
728x90

'Lecture > Image Information Processing' 카테고리의 다른 글

영역 처리의 개념  (0) 2023.11.13
히스토그램 명세화  (2) 2023.11.13
히스토그램 스트레칭  (0) 2023.11.02
이미지의 히스토그램  (0) 2023.10.30
다양한 포인트 처리 기법  (2) 2023.10.16