저번 시간에 Grayscale에 대해서 알아보았는데요


흔히 Grayscale 다음에 하는 작업인 Edge Detection에 대해 알아보겠습니다.


엣지 디텍션 즉 윤곽선 검출은 사진에서 원하는 정도의 윤곽선을 검출해 내는 작업입니다.


저는 대외활동에서 이 엣지 디텍션을 로봇이 길의 경계선을 보고 수평을 맞추는데에 사용했습니다.


윤곽선 검출을 통해서 길의 경계선을 보고 기울기를 판단하여 수평을 맞추는 작업을 했었습니다.


엣지 디텍션은 비교적 쉬운 기법으로 좋은 결과를 얻을 수 있습니다.


먼저 윤곽선 즉 에지에 대한 개념을 알고 가겠습니다.


윤곽선(Edge)이란?


다른 명암도를 가진 경계선, 픽셀의 밝기가 임계값(Threshold) 보다 크게 변하는 경우


그러면 영상에서 윤곽선은 어떻게 찾느냐!


밝기의 변화량 가지고 찾는데 변화량은 미분을 통해서 알 수 있습니다. 


1차 미분 값에서 기울기의 크기로, 2차 미분값에서 기울기의 부호로 밝고 어두움을 판단 할 수 있습니다.


그러면 영상에서는 미분을 어떻게 하느냐!!


바로 마스크로 합니다.


마스크란 미분 연산자와 동일한 효과를 갖는 일종의 필터입니다.


마스크엔 기본 조건이 있습니다.


- 마스크 크기의 가로 세로가 같고 홀수여야 함

- 중심을 기준으로 상하좌우가 대칭이어야 함

- 중심의 수는 항상 0 이상의 양수이다.

- 모든 수의 합은 0이어야 함



우선 대표적인 1차미분 연산인 소벨(Sobel) 마스크를 예로 들어보겠습니다.



대칭적이고 모든 수의 합은 0입니다. 왼쪽이 세로방향에 대한 마스크, 오른쪽이 가로방향에 대한 마스크입니다.


저기서 2가 1로 -2가 -1로 바뀌면 Prewitt마스크입니다. Sobel마스크가 개선된 마스크입니다.


잡음에 조금 강하고 연산속도가 느린 편입니다.


위의 그림은 3x3 크기의 마스크고 5x5 크기의 마스크도 있습니다.




로버츠(Roberts) 마스크입니다. 왼쪽이 수직 마스크고 오른쪽이 수평 마스크입니다.


위의 소벨, 프리윗 마스크에 비해 연산속도가 빠릅니다.


엣지를 확실하게 검출할 수 있지만 매우 얇은 엣지가 검출되며 잡음에 약하다는 단점이 있습니다.


위의 마스크들이 대표적인 1차미분에 관한 마스크고 이제 2차미분에 관한 마스크를 살펴보겠습니다.



2차미분인 라플라시안 마스크!



라플라시안 마스크는 다른 마스크에 비해 종류가 많습니다. 


라플라시안 마스크는 잡음에 약하기 때문에 잡음을 줄여주는 Gaussian Smoothing을 적용한 후 


라플라시안 마스크를 연산하는 LOG(Laplacian of Gaussian)을 사용하기도 합니다.



그리고 잡음에 강한 캐니(Canny) 마스크!


캐니 마스크는 다른 마스크의 응용이라고 볼 수 있습니다.


사용법은 먼저 가우시안 필터로 블러링(평활화)을 해서 잡음을 제거합니다.



위의 마스크가 가우시안 필터 마스크입니다.


그 후 소벨 마스크와 같은 마스크 연산으로 엣지를 검출합니다.


그리고 Non-Maximum Value 제거를 합니다. 이건 좀 고급과정인거 같은데 평활화를 하여서 잘못 검출된 Edge를 제거하는 과정입니다.


Local Maximum Value만 남기고 가짜 엣지는 제거하는 과정입니다. 따라서 엣지가 좀 Sharp해집니다.


최대치 판단은 주로 3x3크기에서 가운데 값을 기준으로 상하좌우값을 비교해서 가운데 값이 크면 값을 남기고 아니면 제거합니다.


다음 과정은 Double Thresholding 와 엣지 연결과정입니다.


Threshold 즉 임계값을 2개(low, high)를 잡고 높은 임계값에서 검출된 엣지를 우선적으로 최종적인 엣지로 판단합니다.


그리고 낮은 임계값에서만 검출된 엣지 중에서 최종적인 엣지와 연관된 엣지만을 최종적인 엣지로 판단하고 나머지 즉 연관성 없는, 


잡음에서 엣지로 판단된 쓰레기값들은 버립니다. 그러면 최종적인 깔끔한 엣지가 검출됩니다.  


잡음에 강하고 꽤 이상적인 엣지 검출이지만 캐니 엣지 검출은 구현이 복잡하고 연산 속도가 느리다는 단점이 있습니다.


캐니 엣지 검출은 아래의 블로그에 그림과 함께 자세하게 설명되어 있더라고요!


http://carstart.tistory.com/188



참고로 코딩에서 마스크는 주로


int mask[3][3] = { {-1, 0, 1}, 

                       {-2, 0, 2}, 

                       {-1, 0, 1} }; 로 표현합니다.


이상 여러종류의 윤곽선 검출에 대해서 알아보았습니다!


+ Recent posts