서로 다른 조건에서 생성이 된 두 개의 영상을 비교하기 위해서는 먼저 영상을 정규화시키어야 한다. 쉽게 생각할 수 있는 정규화의 방법은 두 개의 영상이 동일한 히스토그램을 같도록 만들면 된다. 어떻게 동일한 히스토그램을 만들 수 있는가? 간단히 생각할 수 있는 방법은 주어진 영상의 히스토그램을 전 픽셀에 걸쳐서 균일한 빈도를 보이는 히스토그램이 되도록 변환을 하는 것이다. 즉, 히스토그램을 평탄화시키는 것이다. 이 변환을 $F(x)$라고 하면, 입력 영상의 픽셀 값 $x$는 새로운 픽셀 값 $y = F(x)$로 바뀐다. 영상의 히스토그램은 픽셀 값의 빈도를 나타내므로 확률 밀도 함수로 해석할 수 있고 (픽셀 값을 연속 변수로 볼 때) 주어진 영상의 확률 밀도 함수를 $P(x)$라고 하자. 그러면 $P(x) dx$는 픽셀 값이 $[x, x+dx]$인 픽셀이 영상에서 나타날 확률을 의미한다. 변환 후에서는 임의의 픽셀 값이 균일해야 하므로 확률 밀도 함수는 상수 $a$이고, 픽셀 값의 구간이 $[0,255]$ 이므로 $a = 1/ 255$로 주어진다. 따라서, 변환이 확률을 보존하기 위해서는 $$P(x) dx = a dy$$을 만족해야 하므로 변환 후 픽셀 값 y와 변환 전 픽셀 값 x사이의 관계를 알 수 있다. $$\frac {dy}{ dx} = \frac {1}{a}  P(x) $$ 이 식을 적분하면, $$y = F(x) = \frac {1}{a} \int_0^x P(x') dx' =  255\times  \text {cumulative sum of } P(x)$$ 즉, 히스토그램을 평탄화시키는 변환은 원래 영상 히스토그램의 누적합을 전체 픽셀 수로 나눈 값, $$k \rightarrow F(k)=255 \times \frac {\sum_{i=0}^{k} H [i]}{ \sum_{i=0}^{255} H [i]}$$으로 결정된다. 영상의 히스토그램은 이산적이기 때문에 실제로 모든 픽셀 값에서 균일하게 나타나지 않지만, 구간 변환은 거의 일정하게 나타난다. 이 변환을 거친 영상의 누적 히스토그램(cumulative histogram)을 $y$-축 픽셀 값을 $x$-축으로 해서 그리면 거의 일직선으로 증가하는 모양을 나타낸다.

이 히스토그램의 평탄화는 픽셀 값이 좁은 영역에 몰려있는 영상을 전 영역에 분포하도록 한다. 인간은 영상의 밝기에 의해서 보다는 밝고 어두움의 변화의 크기에 의해서 인지도가 증가하게 되는데, 평탄화된 영상은 보다 쉽게 인식이 될 수 있는 구조를 가진다.

void histogrm_eq(BYTE *src, int width, int height, BYTE *dst) {
    int hist[256] = {0};
    int cum[256];
    for (int k = width * height; k-- > 0; ) 
        hist[src[k]]++ ;
    cum[0] = hist[0];
    for (int k = 1; k < 256; k++) 
    	cum[k] = hist[k] + cum[k - 1];
    double a = 255. / cum[255];
    for (int k = width * height; k-- > 0; ) {
        int x = int(a * cum[src[k]] + 0.5);
        dst[k] = x > 255 ? 255: x;
    }
}

728x90

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

2차원 Gaussian 분포 생성  (0) 2020.12.10
PCA Line Fitting  (0) 2020.11.12
Least Squares Fitting of Circles  (0) 2020.11.11
Integer Sqrt  (0) 2020.11.11
Parabolic Interpolation in Peak Finding  (3) 2020.11.10
Posted by helloktk
,