본문 바로가기

Computer Vision by OpenCV

Histogram Equalization의 원리

반응형






ㅇ Contrast Enhancement
  - 이미지에서 너무 밝은 부분이나, 어두운 부분은 자세한 내용을 보기가 어렵다.
  - 비슷한 intensity를 갖는 픽셀들이 한 곳에 모여있기 때문이다.
    . intensity란, 예를 들어, gray image에서 픽셀은 0(검정색)부터 255(흰색) 값을 갖는데, 이 값을 의미하는 것이다.
    . color image는 RGB, 3개의 채널을 갖는다면, 하나의 픽셀은 각 채널별로 intensity를 갖게 된다.
    . 여기서는 gray image만 생각하자.
  - 이를 개선하는 것을 contrast enhancement라고 한다.
  - 차이 또는 대조 (contrast)를 개선 (enhance)한다는 뜻으로,
  - 차이가 안 나던 픽셀들의 intensity를 바꿔서 차이가 나도록 한다는 것이다.
  - 이것을 위해서 사용되는 방법이 histogram equalization인데, 이에 대해서 살펴보면,,,

ㅇ 히스토그램 (Histogram)
  - 이것은 intensity별로 픽셀들의 개수를 나타내는 그래프이다.

ㅇ Histogram modeling, Histogram transfer
  - 픽셀들의 intensity를 변경하게 되면,
  - 이에 따라 히스토그램도 변경되는데, 이를 histogram modeling 또는 histogram transfer라고 한다.
  - 이러한 변경은 앞에서 설명했듯이, 잘 안 보이는 부분을 잘 보이게 한다든지 하는 contrast enhancement를 하기 위해서이다.

ㅇ Histogram equalization
  - histogram modeling (tranfer)는 intensity를 변경하는 것이기 때문에,
  - 여러 가지 방법들을 생각해 볼 수 있는데,
  - 그 중에서도 contrast enhancement를 목적으로 하는 대표적인 방법이 histogram equalization이다.
  
ㅇUniform histogram 
  - histogram equalization의 목적은 intensity들이 골고루 사용되도록 하는데 있다.
  - 비슷한 intensity들만 많이 사용되면, 이미지에서 그 부분은 잘 안보이기 때문이다.
  - 그래서, 궁극적인 목적이자, 가장 바람직인 equalization은
  - intensity들이 모두 동일한 빈도수로 사용되는 것이다. (하지만 이것은 목표일 뿐이고, 실제는 그렇지 않다.)

ㅇ Histogram Equalization의 효과

- 아래와 같은 히스토그램이 있다고 하자.
- x축은 intensity이고, y축은 값들의 빈도수이다.
- 예를 들어, intensity 2는 빈도수가 30이고,
- 최대 빈도수를 갖는 intensity는 4인 것을 알 수 있다.
- 그런데,
- intensity들이 2 ~ 4에 몰려있는 것을 볼 수 있다. (1번으로 표시)
- Histogram equalization은 이러한 집중을 완화시키는 것으로, 다음 그림을 보자.


- 위의 히스토그램을 완벽하게 equalization하면, 
- 아래와 같이 모든 intensity들이 동일한 빈도수를 갖게된다.
- 하지만, 실제에서는 이러한 것을 달성하기가 어렵고,
- OpenCV에서는 CDF (cumulative distribution function)을 이용한 방법을 이용한다.


ㅇ OpenCV의 histogram equalization 지원
  - equalizeHist( )라는 함수를 제공하는데,
  - 이 함수에 이미지를 인수로 주면, equalized된 이미지를 돌려준다.

void equalizeHist( InputArray src, OutputArray dst): gray image, src 8 bit single channel image
  - 함수 링크
 - src: 입력이미지, dst: equalized된 출력이미지

  - 이 함수는 Cumulative Distribution Function (CDF)를 이용해서 equalization을 수행한다.


ㅇ CDF를 이용한 Histogram Equalization 원리
  - 단계별 수행내용을 그림으로 나타냈다.

- 1 단계
- Histogram에 대해 cumulative sum을 계산한다.
- 좌측에서 우측으로 가면서,
- 각 값들에 대해, 자신과 이전값들의 빈도수 합을 구하는 것이다.
- 값이 커지면서, 빈도수가 점차 증가하는데,
- 이는 이전값들의 빈도수에 자신의 빈도수를 더해 나가기 때문이다.


- 2단계
- 위의 결과에 대해 y축의 값을 normalize한 것으로,
- 빈도수들을 0 ~ 10까지로 rescaling한 것이다.
- 예를 들어, 위의 그램에서 값3에 해당하는 빈도수가 80정도 였는데,
- 이는 4로 normalize된다.
- 이렇게 하는 이유는.... 다음 그림을 보면


- 3단계
- 위에서 normalization을 하면
- 값에 대한 맵핑(mapping)을 얻을 수 있는데,
- 무슨 의미냐 하면,
- 아래 그림과 같이, 
- 값 2를 mapping해서 2로, (번호 1)
- 값 3은 4로 (번호 2)
- 값 4는 10으로 (번호 3)으로 바꾸는 대응을 알 수 있다는 것이다.
- 이 mapping을 이용해서,
- 기존 값을 새로운 값으로 변경시키는 것이다.
- 왜, 이런 mapping을 수행하냐면,,,, 다음 그림에서


- 새로운 값으로 바꾸고 난 후에,
- 히스토그램을 다시 그리면, 아래 그림과 같다.
- 기존에는 값 2 ~ 4에 모두 몰려있었는데,
- 새로운 그림에서는 2 ~ 10까지 펼쳐져 있게 된다.
- 즉, 완벽한 equalization은 아니지만, 
- 그래도, 히스토그램이 전체적으로 퍼지는 효과를 얻게 되는 것이다.



ㅇ MATLAB 소스코드
  - 위의 결과들을 얻기 위한 프로그램
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
%
% 히스토그램 equalization
%
clear all;
close all;

% 테스트 데이터
% intensity - value
% data = [0 1;
%     1 2;
%     2 30;
%     3 50;
%     4 2;
%     5 2;
%     6 2;
%     7 30;
%     8 50;
%     9 2;
%     10 1;
%     ];

data = [0 1;
    1 2;
    2 30;
    3 50;
    4 100;
    5 2;
    6 2;
    7 1;
    8 1;
    9 2;
    10 1;
    ];

max_intensity = size(data,1)-1;

% 바그래프로 데이터를 출력
figure;
bar(data(:,1), data(:,2));
title('Original Histogram');
ylim([0, max(data(:,2)+10)]);

disp(sum(data(:,2)))

% cumulative 합을 계산
% intensity - cumulative 합
data_temp = data;
data_temp(:,2) = cumsum(data(:,2));
data1 = data;
data1(:,2) = round(max_intensity*cumsum(data(:,2))/sum(data(:,2)));

figure;
bar(data_temp(:,1), data_temp(:,2));
title('Cumulative Sum');
ylim([0, max(data_temp(:,2)+10)]);

% 바그래프로 cumulative합을 출력
figure;
bar(data1(:,1), data1(:,2));
title('Normalized Cumulative Sum');
ylim([0,max_intensity+1]);

% equalized data
equData = data;
equData(:,2) = zeros(max_intensity+1, 1);

for k=1:max_intensity+1
    newIntensity = data1(k,2);
    newIntensityIdx = newIntensity+1;
    equData(newIntensityIdx, 2) = equData(newIntensityIdx,2)+ data(k,2); 
end

figure;
bar(equData(:,1), equData(:,2));
title('Equalized Histogram');

disp(sum(equData(:,2)))






반응형