영상에는 일반적으로 관심 대상인 물체와 배경이 함께 포함되어 있다. 그러나 영상의 전체 픽셀 값이 표현할 수 있는 밝기 범위(dynamic range)가 매우 넓더라도, 실제 영상의 히스토그램이 특정한 좁은 구간에만 집중되어 있으면 물체와 배경의 명암 차이가 작아져 구분하기 어려운 영상이 된다. 이러한 경우에는 영상 처리 기법을 이용하여 명암 대비(contrast)를 향상시킬 수 있다.
Histogram Equalization(HE)은 이러한 기법 중 하나로, 좁은 범위에 분포한 픽셀 값을 가능한 한 전체 그레이 레벨(gray level) 범위에 고르게 재분배하여 영상의 명암 대비를 향상시키는 방법이다. 이를 위해서는 입력 영상의 각 픽셀 값을 새로운 그레이 레벨로 변환하는 매핑(mapping)을 정의해야 한다. 이 매핑은 다음 두 조건을 만족해야 한다.
- 출력 영상의 픽셀 값은 기존 그레이 레벨이어야 한다.
- 출력 영상의 히스토그램은 가능한 한 균일한 분포를 가져야 한다.
두 번째 조건은 픽셀 값이 이산적이므로 모든 그레이 레벨에서 정확히 동일한 개수의 픽셀을 갖는 것은 불가능하다. 따라서 보다 정확하게는 출력 영상의 누적 히스토그램(cumulative histogram)이 그레이 레벨에 대해 선형적으로 증가해야 한다는 조건으로 표현할 수 있다.
이제 입력 영상에서 그레이 값이 인 픽셀은 출력 영상에서 어떤 그레이 값 $j\,$로 변환되어야 하는지 생각해 보자. 출력 영상의 히스토그램이 균일하다고 가정하면, 그레이 레벨 $0$부터 $j$까지의 누적 픽셀 수는
$$\frac{j}{255} \times \text{총 픽셀 수}$$가 된다.
한편, 입력 영상에서 그레이 레벨 $0$부터 $k\,$까지 누적 픽셀 수는
$$\sum _{i=0}^k \text{histogram}[i] = \text{cumulative histogram}[k]$$이다.
히스토그램 평탄화에서는 입력 영상과 출력 영상의 누적 픽셀 수가 같도록 대응시키므로
$$\frac{j}{255} \times{\text{총 픽셀 수}} = \text{cumulative histogram}[k]$$를 만족해야 한다. 총 픽셀 수가 $\text{cumulative histogram}[255]$이므로 원하는 mapping은
$$ k \longrightarrow j = T[k] = \frac{255\times\text{cumulative histogram}[k]}{\text{cumulative histogram}[255]}$$로 주어진다.
이 변환을 적용하면 입력 영상에서 가장 큰 그레이 값은 출력 영상에서 255에 대응하며, 출력 영상의 누적 히스토그램은 정의에 의해 거의 직선적으로 증가하는 형태를 갖는다. 실제 구현에서는 이 매핑을 미리 Lookup Table(LUT)로 저장해 두면 각 픽셀에 대해 테이블 조만 수행하면 되므로 연산량을 크게 줄일 수 있다.
note)
1. 0차 cumulative histogram을 이용하면 0부터 k까지의 histogram의 합은 한 번의 호출로 얻어진다.
2. 0차 cumulative histogram의 마지막 bin의 값은 전체 픽셀 수의 합이 된다.
// histogram의 합은 cumulative histogram을 구성하면 된다;
void HistogramEqualize(BYTE *src, int width, int height, BYTE* dst) {
int histogram[256] = {0}, cumhist[256];
for (int k = width * height; k-->0;) ++histogram[src[k]];
// make 0-st order cumulative histogram;
cumhist[0] = histogram[0];
for (int k = 1; k < 256; k++) cumhist[k] = cumhist[k-1] + histogram[k] ;
int map[256];
double v = 255.0 / cumhist[255]; // cumhist[255] = number of pixels;
for (int k = 0; k < 256; k++) {
int v = int(v * cumhist[k]);
map[k] = v > 255 ? 255: v;
}
for (int k = width * height; k-->0;) dst[k] = map[src[k]];
};
평탄화 전의 히스토그램(붉은색) 및 누적 히스토그램(연두색)
평탄화 후의 히스토그램(붉은색) 및 누적 히스토그램(연두색)
'Image Recognition > Fundamental' 카테고리의 다른 글
| Bright Preserving Histogram Equalization with Maximum Entropy (0) | 2008.07.31 |
|---|---|
| Adaptive Binarization (2) | 2008.07.14 |
| FFT2D (0) | 2008.06.10 |
| Otsu Algorithm (6) | 2008.05.30 |
| Hough Transform (3) | 2008.05.22 |

