[컴퓨터 비전] 15 Edge Detection

이찬영·2024년 2월 29일
0

컴퓨터 비전

목록 보기
14/20

[컴퓨터비전 STUDY / KOCW 한동대학교 황성수 교수님 강의 Review]

Introduction

Edge pixels : Edge pixel이란, 밝기 값이 급격하게 변하는 부분을 말한다.

Edges : Edge pixels 들의 집합을 의미한다.

아래 그림은 빨강색 사각형 영역 내에서의 그림의 밝기 변화를 그래프로 표시한 것이다.


How to detect edges? (1차원)

엣지 검출에는 1차 미분(주변 값과의 차이)이 먼저 쓰일 수 있다.

Horizontal Intensity profile은 밝기 값 변화, First derivative는 그것을 1차 미분한 것이다.

미분 값의 변화로 edge를 검출해 낼 수 있다.


How to detect edges? (2차원)

Image gradient를 활용할 수 있다.

1차 미분을 2차 미분 (x, y)으로 확장한 것이다.

다음은 edge의 크기이다.

edge의 방향은 다음과 같다.

Gradient vector는 해당 픽셀로부터 변화가 가장 급격하게 변하는 방향을 가리킨다.

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

뿐만 아니라, edge 검출을 하는데 있어 noise가 굉장히 큰 방해가 된다.

그림에서 맨 위는 noise가 없는 경우, 그 밑에 것들은 다 noise가 존재하는 것들이다.
noise가 많아지면 값이 복잡해진다.

따라서 noise 제거가 필요하다.


Edge detection을 수행하는 방법에는 크게 2가지가 있다.
Sobel operators와 Canny Edge Detector이다.

Sobel operators

위에서 설명했던 것처럼 2차 미분 (x, y)은 다음과 같이 표현될 수 있다.

다음은 Spatial filter을 활용한 예시이다.

그 다음은 Sobel mask를 활용한 예시이다. 보통 확장/개선해서 많이 사용한다. 그림의 첫번째 mat가 y축 방향을 수행하고, 두 번째 mat는 x축 방향으로 수행한다.

이후 미분의 절댓값을 합해 최종 영상을 만들어낸다.

아래 그림들은 각각의 수행 결과에 따른 예시이다.
대각선의 그림들을 합해서 우측 하단에 있는 결과 그림으로 출력된다.

다음은 Sobel edge detector를 실행하는 코드이다.

 int main() {
 	Mat image, blur, grad_x, grad_y, abs_grad_x, abs_grad_y, result;
 	image = imread("lena.png", 0);		# 이미지를 흑백으로 로드함
    # 가우시안 블러 적용, size(5, 5)는 블러 커널의 크기를 의미, 5, 5는 x, y축의 표준편차를 의미
 	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);	# x축 방향의 엣지를 검출함
 	convertScaleAbs(grad_x, abs_grad_x);	# sobel 연산의 결과를 절댓값으로 변환함	
 	
    Sobel(blur, grad_y, CV_16S, 0, 1, 3);	# y축 방향의 엣지를 검출함
 	convertScaleAbs(grad_x, abs_grad_y);	# sobel 연산의 결과를 절댓값으로 변환함
 
 	# x축과 y축의 edge를 결합함
 	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);
}

결과는 다음과 같다.

Input Image

X, Y, Sovel Edge Detector 순이다.


Canny Edge Detector

Canny Edge Detector은 다음 단계들을 거친다.

  1. 가우시안 필터를 통해 noise(잡음)들을 제거해서 이미지를 부드럽게 만든다.

  2. 가우시안 필터로 noise가 제거된 이미지를 바탕으로 위에서 배웠던 Sobel 커널을 수평방향과 수직방향으로 적용하여 각 방향의 gradient를 계산한다.

  3. gradient 방향으로 인접한 두 픽셀들을 찾는다. 이후, 두 픽셀들보다 값이 더 크면 그냥 넘어가고, 만약 그렇지 않으면 해당 값을 0으로 만든다.

  1. double thresholding을 적용한다. low threshold와 high threshold를 정해 high threshold보다 크면 엣지로, low threshold보다 작으면 엣지가 아닌 것으로 판별한다. 만약 둘 다 아니면 중간값으로 할당하고, 연결되어 있으면 edge로 간주한다.

canny edge operator를 수행하는 코드는 다음과 같다.

 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 edge 검출 적용, 190은 low threshold, 200은 high threshold
 	Canny(image, canny, 190, 200, 3);	 	
 
 	imshow("Input image", image);
 	imshow("canny", canny);
 
 	waitKey(0);
 }

결과는 다음과 같다.

profile
자율주행, AI, 클라우드

0개의 댓글