Edge Detection

Development - Software/Image Processing | Febuary 28th, 2010 00:00 | BackpackHolic

 

Edge Detection

 

1. 윤곽(edge)

  [윤곽]을 사전적으로 설명하면 "물체의 외곽을 나타내는 선"이라고 정의하며, 이러한 윤곽은 영상처리의 차원에서는 "영상을 특징짓는 선요소"라고 말할 수 있다.

  흔히 영상의 많은 부분에서 우리는 단순한 윤곽선만으로도 무엇을 표현하려는가를 충분히 이해할 수 있다. 따라서, 영상처리에 있어서도 윤곽을 추출하는 것(윤곽 추출, 또는 edge  추출)은 중요한 개념의 하나이다. 이 윤곽추출 방법을 이용하여 우리도 특정의 물체를 추출한다든지 또는 면적과 주위의 크기를 측정한다든지 하는 영상 데이터를 처리를 할 수 있다.

  그러면, 윤곽과 영상과는 어떤 관계가 있을까? 영상 중의 물체와 물체, 어떤 것은 물체와 배경의 경계가 윤곽이기 때문에 "영상의 농담과 색에 급격한 변화가 있는 경우"가 윤곽이라고 우리는 예상할 수 있다.

2. 미분에 의한 영상 처리

 윤곽은 농담치가 급격하게 변화하는 부분이기 때문에 함수의 변화분을 취하는 미분 연산이 윤곽 추출에 이용될 수 있다. 미분에는 1차 미분(gradient)과 2차 미분(Laplacian)이 있다.

   2-1. 1차 미분(gradient)

  좌표 (x, y)의 경우 농담 분포를 나타내는 1차 미분값(gradient)은 크기와 방향을 가진 벡터량

G(x, y) = (fx, fy)

  로서 표현된다. 여기에서 fx는 x 방향의 미분, fy는 y 방향의 미분을 나타내며, fx, fy의 digital 영상은,

 

x 방향의 미분 fx = f(x+1, y) - f(x, y)
y 방향의 미분 fy = f(x, y+1) - f(x, y)

 

 

  으로 계산한다. 미분값 fx, fy를 구하면, 아래의 식으로부터 윤곽의 강도와 방향을 계산할 수 있다.

강도 또는,  (| |)는 절대 값

수평방향 미분

   윤곽을 추출함에 있어서 수평 방향의 미분을 취하려면 다음과 같은 알고리즘으로 처리를 하게 된다.

F(X, Y) = | F(X, Y-1) - F(X, Y+1)

  즉, 수평방향으로의 미분은 어느 한 점 (F(X, Y))을 기준으로 할 때 X좌표는 같고, Y좌표만 중심 화소의 상하에 해당하는 화소들의 차이값을 구하는 관계로 얻을 수 있다.

// 수평 방향으로 미분을 취하는 함수(이미지의 크기는 256x256)
void Horizontal()
{
    int i, j;
    int gr_h[256];
    for(i=0; i<256; i++){
        for(j=0; j<266; j++){
            gr_h[j] = (int)m_OpeningImg[i][j] - m_OpeningImg[i][j+2];
            m_ResultingImg[i][j] = (unsigned char)abs(gr_h[j]);
        }
    }
}

수직방향 미분

  수직 방향의 미분은 다음의 관계식으로 구할 수 있다.

F(X, Y) = | F(X+1, Y) - F(X-1, Y)

  즉, 수직방향으로의 미분은 어느 한 점 (F(X, Y))을 기준으로 할 때 Y좌표는 같고, X좌표만 중심 화소의 상하에 해당하는 화소들의 차이값을 구하는 관계로 얻을 수 있다.

// 수직 방향으로 미분을 취하는 함수(이미지의 크기는 256x256)
void Vertical()
{
    int i, j;
    int gr_v[256];
    for(i=0; i<256; i++){
        for(j=0; j<266; j++){
            gr_v[j] = (int)m_OpeningImg[i][j] - m_OpeningImg[i+2][j];
            m_ResultingImg[i][j] = (unsigned char)abs(gr_v[j]);
        }
    }
}

수직, 수평 방향의 미분

  수직, 수평 방향의 미분은 앞에서 설명한 두가지 미분방법을 이용하여 구할 수 있다.

// 수직 방향으로 미분을 취하는 함수(이미지의 크기는 256x256)
void Vert_Horz()
{
    int i, j;
    int gr_v[256], gr_h[256];
    for(i=0; i<256; i++){
        for(j=0; j<266; j++){
            gr_v[j] = (int)m_OpeningImg[i][j] - m_OpeningImg[i+2][j];
            m_ResultingImg[i][j] = (unsigned char)abs(gr_v[j]);

           gr_h[j] = (int)m_OpeningImg[i][j] - m_OpeningImg[i][j+2];
            m_ResultingImg[i][j] = (unsigned char)abs(gr_h[j]);
        }
    }
}

  이러한 1차 미분 방식은 행렬의 형태로 테이블이 주어지는데, 흔히 이용하는 방법에 대하여 정리하면 다음과 같다.

연산자

fx

fy

Roberts

0   0   0
0   1   0
0   0  -1

0   0   0
0   0   1
0 -1   0

Prewitt

-1   0   1
-1   0   1
-1   0   1

1    1    1
0    0    0
-1  -1  -1

Sobel

-1   0   1
-2   0   2
-1   0   1

1    2    1
 0    0    0
-1   -2  -1

Frei-Chen

-1   0   1
-  0

-1   0   1

1      1
0      0     0
-1  -
 -1

   Roberts 연산자는 다른 마스크보다 크기는 작지만 효과적으로 사용할 수 있다. 이 연산자는 잡음에 매우 민감하다. 다른 연산자들은 돌출된 영상의 값들을 잘 평균화 시킨다. Sobel 연산자는 수평과 수직 윤곽보다는 대각선 방향에 놓여진 윤곽에 더 민감하며, Prewitt 연산자는 대각 방향의 윤곽보다는 수평, 수직 윤곽에 더 민감하다. 위의 방법중 몇가지 예를 보면 다음과 같다.


원 이미지 
 


Roberts
 


Prewitt


Sobel

 

  2-2. 2차 미분(gradient)

  2차 미분은 1차 미분(gradient)를 다시 한번 미분 하는 방법으로, 윤곽의 강도만(방향은 구하지 않는다)을 검출하는데 사용된다. 1차 미분 연산자는 에지가 존재하는 영역을 지날 때 반응하는 부분이 많이 나타난다. 이것은 특히 완만한 경사를 이루는 에지일 경우에 더욱 반응이 두드러 진다. 이상적인 에지 검출기는 에지의 중심에 위치한 임의의 에지만을 검출할 수 있어야 한다.
  2차 미분 연산자의 장점은 검출된 에지의 윤곽선들이 폐곡선을 이룬다는 것이다. 이것은 영상 분할에 있어 중요한 사항이다. 또한 2차 미분은 밝기값이 점차적으로 변화되는 영역에 대해서는 반응을 보이지 않는다.
  2차미분 연산자의 좋은 예로 라플라시안(Laplacian) 연산자를 들 수 있다. 라플라시안 연산자는 다른 연산자들 보다 더욱 뚜렷한 에지를 검출한다. 라플라시안 연산자에 의한 에지 검출은 다음과 같은 마스크를 회선함으로써 찾을 수 있다.


<Laplacian 계산에 이용하는 연산자>

 

Laplacian 1 Laplacian 2 Laplacian 3
fx를 구하는 연산자

0   -1    0
-1   4    -1
0    -1    0

-1   -1   -1
-1   8    -1
-1   -1   -1

 1    -2    1
-2     4   -2
1    -2    1

 

Copyright(저작권)
Creative Commons License
Trackback address :: http://blog.backpackholic.tv/trackback/165