본문 바로가기
AI/컴퓨터비전

[Computer Vision] 엣지 검출(Edge Detection)

by 꼬바리 2021. 4. 2.

Edge란?

Edge pixels : 영상내 특정한 픽셀 주변의 밝기 값이 급격하게 변하는 픽셀

Edges : 엣지 픽셀들의 연속된 집합

1차원에서는 edge를 어떻게 감지할까?

1차 미분(변화량)을 구한다. = 주변 값과의 차이

미분을 수행했을 때 크기가 0이 아닌 특정한 값을 가지는 부분을 활용해 edge를 검출할 수 있다.

 

2차원에서는 edge를 어떻게 감지할까?

image gradient를 활용한다.

Gradient vector는 해당 픽셀의 변화량이 가장 급격한 방향을 가리킨다.

Gradient vector와 Edge direction은 수직관계에 있다.

→ Gradient의 방향을 구하면 Edge의 방향을 구할 수 있게 된다.

 

잡음(noise)의 영향

미분 값의 크기로 edge를 찾을 수 없다.

따라서, 엣지 검출 전에 gaussian bluring 이나 averaging filter를 통해 noise를 제거한다.

 

Sobel operators

왼쪽은 Spatial filter 활용 방법, 오른쪽은 Sobel mask 활용 방법

 

Result of applying gradient operators

좌상단부터 입력영상, x 미분, y 미분, M(x,y)

 

Result of applying gradient operators after 5X5 averaging filter

엣지 검출 전에 5x5 averaging filter를 통해 noise 제거

 

Thresholding on magnitude of gradient

thresholding 적용

int main() { 
	Mat image, blur, grad_x, grad_y, abs_grad_x, abs_grad_y, result; 
    image = imread("lena.png", 0); 
    GaussianBlur(image, blur, Size(5, 5), 5, 5, BORDER_DEFAULT);
    
    // performs Sobel operation which is a discrete differentiation 
    // blur : input Mat, grad_x : output Mat, CV_16S : depth of the output Mat 
    // 1 : order of derivative in x direction, 0 : order of derivative in y direction 
    // 3 : size of the extended Sobel kernel; it must be 1, 3, 5, or 7.
    
    Sobel(blur, grad_x, CV_16S, 1, 0, 3); 
    convertScaleAbs(grad_x, abs_grad_x); 
    
    Sobel(blur, grad_y, CV_16S, 0, 1, 3); 
    convertScaleAbs(grad_x, abs_grad_y); 
    
    addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, result); 
    
    imshow("X", abs_grad_x); 
    imshow("Y", abs_grad_y); 
    imshow("Input image", image); 
    imshow("Sobel Edge Detector", result);
	
    waitKey(0); 
}

Canny Edge Detector

1. Gaussian filter를 활용해 입력 영상의 잡음을 제거한다.

2. Sobel edge mask를 활용해 gradient의 크기와 각도를 계산한다.

3. gradient의 크기에 대해서 nonmaxima suppression을 수행한다.

nonmaxima suppression?

gradient 방향으로 𝛼(𝑥, 𝑦)와 인접한 픽셀들을 찾는다. (𝛼 : gradient direction)

𝛼(𝑥, 𝑦)가 인접한 픽셀들의 gradient 크기보다 작다면 제거한다.(값을 0으로 만든다. → 𝛼(𝑥, 𝑦)가 엣지가 될 가능성이 사라진다.)

따라서, 주변 픽셀들 중 최대치만 남기고 최대치가 아닌 nonmaxima 성분을 제거하는 것이다.

cf. Edge normal = gradient direction

Edge normal과 수직 = edge direction

 

4. double thresholding을 수행하고, connectivity analysis to detect and link edges
𝑀(𝑥, 𝑦) ≥ 𝑇𝐻 ← edge
𝑀(𝑥, 𝑦) < 𝑇𝐿  non-edge
𝑇𝐻와 𝑇𝐿 사이에 있는 값들  edge라고 판별된 픽셀과 연결되어 있다면 edge라고 간주하고, 그렇지 않은 경우에는 edge가 아닌 것으로 간주한다.

𝑇𝐻와 𝑇𝐿은 사용자가 정의한다.

int main() {
    Mat image, canny;
    image = imread("lena.png", 0);
    
    // performs canny edge detection
    // image : input Mat, canny: output Mat
    // 190 : Thresh_low of double thresholding
    // 200 : Thresh_high of double thresholding
    // 3 : aperture size of the Sobel operation
    Canny(image, canny, 190, 200, 3);
    
    imshow("Input image", image);
    imshow("canny", canny);
    
    waitKey(0);
}



출처: https://sss20-02.tistory.com/29 [초보개발자의 작은 끄적임]

728x90
반응형

댓글