관리 메뉴

Bull

[Image Processing] Histogram Equalization (by MATLAB) 본문

Computer Science/Image Processing

[Image Processing] Histogram Equalization (by MATLAB)

Bull_ 2024. 3. 23. 03:25

개념


히스토그램 평활화는 이미지의 히스토그램에서 너무 치우쳐진 부분을 평활하게 만들어 주는 기법이다.

 

출처: https://en.wikipedia.org/wiki/Histogram_equalization#See_also

 

즉, 위의 그림과 같이 빈도 수가 높은 부분은 낮게, 낮은 부분은 높게 하여 동등하게 만들어준다.

 

방법은 다 알고나면 간단해 보일지 모르겠지만 나름 고민을 많이 했던 주제였다.

 

과정


① 우선 흑백으로 만든 후 사진의 gray level의 개수를 담을 배열을 잡아준다.

난 교재에서 level이 0~7이 길래 255크기를 log_scale로 나누는 건가.. 아니면

 

그냥 임의의 숫자로 나누는 건가 싶어서 몇 시간을 고민했는데,

 

임의로 나눠도 되고, 아무렇게나 기준을 잡아 단계를 나누면된다.

 

빽빽한 히스토그램이 보고싶으면 0~255로 배열을 만들면 된다. [0,1,2,3,4,....255]

 

② 배열에 담긴 숫자를 PDF(Probability Density Function) 과정을 거친다.

확률 밀도 함수, 쉽게 말해서 (해당부분 개수 / 전체 개수)라고 보면된다.

 

③ 배열에 담긴 숫자를 CDF(Cumulative Distribution Function) 과정을 거친다.

 

누적 분포 함수, 배열을 하나 거칠때마다 전단계있는 걸 계속 누적해 나가는 것이다.

 

④ 계산된 수들은 확률로 분포되어 있으니 다시 x255(grayscale 개수)를 해준다.

 

⑤ pixcel은 소수점으로 나타낼 수 없으니 round를 해준다.

 

코드구현


histeq.m

clear
clc
img = imread('dog.jpg'); % 이미지 읽기
img = uint8(mean(img, 3)); % 그레이스케일 변환

y = zeros(1, 256); % 그레이 레벨 0부터 255까지의 빈도수를 저장할 배열 초기화

% 각 그레이 레벨의 픽셀 수 계산
for i = 0:255
    y(i+1) = sum(sum(img == i));
end

x = 0:255; % x축 값 설정

total_n = sum(y); % 전체 픽셀 수
pdf = y / total_n; % 확률 밀도 함수(PDF) 계산

% 누적 분포 함수(CDF) 계산
cdf = zeros(1, 256);
for i = 1:256
    if i == 1
        cdf(i) = pdf(i);
    else
        cdf(i) = cdf(i-1) + pdf(i);
    end
end

scale = cdf * 255; % 새로운 스케일로 매핑된 CDF 값 계산
new_gray = round(scale); % 결과를 반올림하여 새로운 그레이 레벨 값 얻기

newhist = zeros(1, max(new_gray)+1); % 새 히스토그램 초기화

% 새로운 히스토그램 계산
for i = 1:length(new_gray)
    newhist(new_gray(i)+1) = newhist(new_gray(i)+1) + y(i);
end

% 원본 히스토그램과 평활화된 히스토그램 표시
subplot(2,1,1)
bar(x, y)
title('Original Histogram')
subplot(2,1,2)
bar(0:max(new_gray), newhist)
title('Equalized Histogram')

 

 

결과


직접짠 코드

히스토그램의 결과는 다음과 같다.

10과 250 근처에는 픽셀이 많이 없었는데 확실히 평탄화 된 것이 눈에보인다.

 

MATLAB: histeq()로 적용해보기

다음은 매트랩에 있는 histeq() 함수를 써서 비교해보았다.

강아지 사진출처: https://mypetlife.co.kr/150519/

 

histeq()를 통해 Histogram Equalization을 적용한 사진은 어떤 느낌을 주는지 알 수 있었다.

 

하지만 내가 짠 코드와 달리 평탄화된 pixel의 분포가 약간 다르다는 것을 알 수 있었다.

 

MALAB의 histeq()의 소스코드를 내부적으로 볼 수 있는 지는 모르지만, 공식 문서에 따르면

 

grayscale을 64개로 나눈다는 설명을 볼 수 있었다.

 

아마도 최적화된 scale leveling이기 때문에 그러한 값을 넣은 게 아닌 가 추측해본다.

 

또한 인자를 통해 몇개의 level로 나눌 수 있는 지 커스텀도 가능하다.

 

https://kr.mathworks.com/help/images/ref/histeq.html#bvhelue-1-newmap

 

히스토그램 평활화를 사용하여 대비 향상 - MATLAB histeq - MathWorks 한국

이제 histeq 함수는 최적화된 CUDA® 코드 생성을 지원합니다(GPU Coder™가 필요함).

kr.mathworks.com