본문 바로가기

Lab/Basic Algorithms

Gaussian Blur - 1


Gaussian sigma = 5


Gaussian sigma = 10

원본


Gaussian Blurring 이란?  많은 블러링 알고리즘의 하나이다. 여기서 주목할것이 있는데 사진에서의 블러링의 의미이다. 보통 이렇게 설명한다. 


높은 주파수는 통과시키지 않고 낮은 주파수만 통과시키는것이 블러링이다.  말이 너무 어렵다. 그러나 잘 의미를 생각해보면 높은 주파수가 이미지에서 의미하는 것은 갑자기 변화는 부분이다. 즉, Edge영역을 의미하며 이를 순화시키면 시킬수록 블러링이된다. 


그래서 보통 블러링을 low pass filter 라 부른다. 


가우시안은 

g(x,y) = \frac{1}{2\pi \sigma^2} \cdot e^{-\frac{x^2 + y^2}{2 \sigma^2}}


의 식으로 표현되면 이는 2D Gaussian filter이다. 

가우시안 필터는 보통 다음과 같은 성격을 지니며 위의 식은 정규 분포  (μ = 0과 σ^2 = 1)을 나타낸다. 이때 시그마는 분포 즉, 표준 편차라한다. 

위의 2D Gaussian Filter는 1D로 분해 가능하다.


이유는 Convolution 개념으로 계산할때 중복을 피하기 위함이다.

(참고 - 다음 포스트에서는 2D Gaussian filter로 구현한 결과를 보일 예정이다.)


구현은 다음과 같고 결과는 위의 이미지와 같다.


 double temp_sigma1 = 1.f/(sigma*sqrtf(CV_PI*2.f));

 double temp_sigma2 =  -1.f/(2.f*sigma*sigma);

 int mask_size      = sigma*2+1;

        int half_mask_size = mask_size/2;

        double mask[mask_size];


        float kernel_sum = 0;


        for( int i=half_mask_size-mask_size+1; i<mask_size-half_mask_size; i++){

                float r = (float) i;

                mask[half_mask_size+i] = temp_sigma1*exp(r*r*temp_sigma2);

                kernel_sum+= mask[half_mask_size+i];

     

        }


 for( int i=0; i<h; i++){

                for( int j=0; j<w; j++){

                        float sum_r =0.f, sum_g = 0.f, sum_b = 0.f;


                        int n = 0, k = 0;

                        for(int k=-(mask_size>>1); k<=(mask_size>>1); k++, n++){

                                int x = j+k;

                                //if(x<0 || x>=w) continue;

                                if(x<0) x = 0;

                                if(x>=w) x = w-1;


                                sum_r+=((float)_image[i][x].r*mask[n]);

                                sum_g+=((float)_image[i][x].g*mask[n]);

                                sum_b+=((float)_image[i][x].b*mask[n]);

                        }


                        int r = (int)(sum_r/kernel_sum);

                        int g = (int)(sum_g/kernel_sum);

                        int b = (int)(sum_b/kernel_sum);


                        _output[i][j].r = r;

                        _output[i][j].g = g;

                        _output[i][j].b = b;

                }

        }


        for( int i=0; i<h; i++){

                for( int j=0; j<w; j++){

                        float sum_r =0.f, sum_g = 0.f, sum_b = 0.f;

                        int n = 0, k = 0;

                        for(int k=-(mask_size>>1); k<=(mask_size>>1); k++, n++){

                                int y= i+k;

                                //if(y<0 || y>=h) continue;

                                if(y<0)  y = 0;

                                if(y>=h) y = h-1;


                                sum_r+=((float)_output[y][j].r*mask[n]);

                                sum_g+=((float)_output[y][j].g*mask[n]);

                                sum_b+=((float)_output[y][j].b*mask[n]);

                        }


                        int r = (int)(sum_r/kernel_sum);

                        int g = (int)(sum_g/kernel_sum);

                        int b = (int)(sum_b/kernel_sum);

                        _output[i][j].r = r;

                        _output[i][j].g = g;

                        _output[i][j].b = b;

                }

        }

'Lab > Basic Algorithms' 카테고리의 다른 글

Edge Detection - Sobel  (2) 2013.01.11
bilinear interpolation  (0) 2012.10.15