Histogram Equalization(HE)은 누적 히스토그램(cumulative histogram)을 이용하여 픽셀의 명암값을 재분배함으로써 영상의 명암 대비(contrast)를 향상시키는 대표적인 영상처리 기법이다. 히스토그램을 계산하는 영역에 따라 전체 영상의 히스토그램을 사용하는 전역 히스토그램 평활화(Global HE)와, 각 픽셀 주변의 국소 윈도에서 계산한 히스토그램을 사용하는 국소 히스토그램 평활화(Local HE)로 구분된다.

여기서는 각 출력 픽셀에 대해 크기가 \(\text{wsize}\times \text{wsize}\)인 정사각형 국소 윈도를 선택하고, 이 윈도에서 계산한 히스토그램을 이용하여 해당 픽셀의 명암값을 변환한다. 윈도 내의 히스토그램이 \({h[i]}\)로 주어질 때, 현재 픽셀의 밝기값 \(j\)는 누적 히스토그램을 이용하여

\[j\quad\longrightarrow\quad\frac{255}{N}\sum_{k=0}^{j} h[k]\]

로 변환된다. 여기서 \(N=\text{wsize}\times \text{wsize}\)는 윈도에 포함된 전체 픽셀 수이다.

국소 히스토그램 \({h[i]}\)는 running histogram 알고리즘을 이용하면 매우 효율적으로 계산할 수 있다. 즉, 윈도가 한 칸 이동할 때 윈도에서 빠져나가는 열의 히스토그램을 빼고 새로 들어오는 열의 히스토그램을 더하는 방식으로 갱신하면, 매 위치에서 히스토그램을 처음부터 다시 계산할 필요가 없다. 따라서 국소 히스토그램 기반의 Histogram Equalization을 매우 빠르게 수행할 수 있다.

한편, 아래의 구현에서는 국소 윈도가 항상 영상 내부에 완전히 포함되도록 하였다. 따라서 영상의 경계에서는 윈도를 영상 내부로 이동시키며, 이 경우 현재 픽셀은 윈도의 중심에 위치하지 않을 수 있다. 즉, 경계 부근의 픽셀은 이동된 국소 윈도에서 계산한 히스토그램을 이용하여 명암값을 변환한다.

//

void localHistogramEqualization(BYTE *image, int width, int height, int wsize,/*window size*/
                                BYTE *out) 
{
    int hwsize = wsize >> 1;
    wsize = (hwsize << 1) + 1; //odd #;
    int topstop = height - wsize;
    int leftstop = width - wsize; 
    for (int y = 0, offset = 0; y < height; y++, offset += width) {
        int top = y - hwsize; 
        top = top < 0 ? 0 : top > topstop ? topstop : top; 
        BYTE *imgrow = &image[offset];
        BYTE *outrow = &out[offset];
        for (int x = 0; x < width; x++) {
            int left = x - hwsize;
            left = left < 0 ? 0 : left > leftstop ? leftstop : left;
            // make local histogram;
            int histo[256] = {0}; 
            int yy = 0, woffset = top * width + left;
            for (; yy < wsize; yy++, woffset += width) {
                BYTE *winrow = &image[woffset];
                for (int xx = 0; xx < wsize; xx++)
                    histo[winrow[xx]]++;
            }
            int level = imgrow[x];
            int csum = 0;  // 0-th cumulative sum up to level;
            for (int k = 0; k <= level; k++) csum += histo[k];
            // apply local histogram eq.
            int a = int((255.0 * csum)/(wsize * wsize)) ;
            outrow[x] = (a & ~255) == 0 ? a: a < 0 ? 0: 255;
        }
    }
}

원본:

 

 

 

*global: 

 

 

 

 

*local: wsize=51;

 

 

** CLAHE 적용: tile size = 20x 20

 

 

 

'Image Recognition' 카테고리의 다른 글

Autofocus Algorithm  (0) 2012.06.03
Statistical Region Merging  (3) 2012.03.25
Savitzky-Golay Filter의 주파수 특성  (0) 2012.03.03
2차원 Savitzky-Golay Filters 응용  (0) 2012.02.28
webcam용 QR code detector  (0) 2012.02.19
,