OpenCV에서 edge를 detect 할 때 자주 사용했던 알고리즘이다. 이제는 그 원리를 알아보려고 한다.
이전 게시글에서 설명한 Sobel filter는 두꺼운 edge를 검출해서 보여주기 때문에 edge를 정확히 검출하는데 한계가 존재한다. 따라서 다양한 환경의 영향을 덜 받을 수 있는 정확한 edge 검출 알고리즘이 필요해졌다.
Canny Detection의 단계를 살펴보자.
- 단계
1. 노이즈 제거 (Gaussian Blur)
첫 번째는 edge의 정확도 향상을 위해, 고주파 노이즈들을 없애주는 Gaussian Blur를 적용한다. 이후 적용하는 Sobel filter에도 기본적으로 내재되어 있지만 더욱 확실하게 노이즈 제거를 수행하게 된다.

2. Edge 검출 (Sobel gradient 사용)

이전에 살펴본 Sobel filter를 통해 미분과 스무딩을 동시에 수행하며 픽셀값의 변화가 급격한 부분을 찾아낸다. 이는 x방향에 대해서는 Gx kernel을, y방향에 대해서는 Gy kernel을 사용하여 수행했다. 따라서 여기서는 그 방향과 크기를 정의하기 위해서 아래와 같은 식을 사용한다.

이를 통해 edge의 크기와 방향을 계산해낼 수 있다.
3. Non-Maximum Suppression (비최대 억제)
이 부분은 Sobel filter를 사용했을 때 나오는 edge가 두꺼워서 정확한 edge를 검출할 수 없다는 점을 보완하기 위한 단계이다. 먼저 앞서 구한 gradient의 방향을 0, 45, 90, 135도로 단순화 시킨다. 아래와 같이 각 각도가 의미하는 바는 해당 각도에 대해서 대칭인 각도를 하나의 방향으로 따진다는 의미이다.

Sobel filter 게시글에서 x와 y filter에 대한 결과를 각각 생각해보면 gradient의 변화에 대해서 edge는 수직으로 검출된다는 특징을 가진다. 즉 gradient 방향이 구해지면, 해당 부분에서 local maximum을 가지는 부분 (변화가 가장 크게 일어난 부분)이 edge로 선택되는 것이다. Gradient의 maximum을 선택하는 이유는 픽셀 값의 미분을 아래와 같이 이해하면 된다.

한 픽셀만 선택하기 때문에 edge가 두꺼운 것이 아니라 하나의 픽셀이 연속된 얇은 형태로 특정할 수 있는 것이다. 전체 과정은 그림을 보면 이해가 쉽다.

4. Hysteresis Thresholding
마지막으로 thresholding을 통해 정확도를 높이는 과정을 거친다. 여기서 min Th와 max Th 2가지의 임계값을 사용한다. max Th를 넘어가는 pixel들은 모두 strong edge로 간주한다. min Th보다 작은 pixel들은 edge가 아닌 것으로 간주한다. 두 임계값 사이에 존재하는 점들을 weak edge로 분류하는데, 만약 strong edge와 연결된 weak edge라면 최종적으로 edge로 분류하고 strong edge와 연결되지 않았다면 최종적으로 edge에서 제외한다. 이것으로 스무딩에서 제거되지 않은 노이즈를 제거하고 서로 상호 연결되어있는 edge들만을 추출할 수 있다.

위의 예시 그림에서 A는 strong edge이고 B와 C는 weak edge이다. C는 A와 연결되어 최종적으로 edge로 분류되는 반면 B는 연결되어 있지 않기 때문에 edge에서 제외된다.
- Canny Detection의 특징
먼저 여러 방법을 단계적으로 조합하여 edge detection의 성능을 높였다는 특징을 가진다. 이로써 높은 정확도를 가질 수 있다. 또한 다중 임계값을 통해, 강한 edge와 약한 edge를 구분하고 연결 관계로 최종 판단을 내림으로써 신뢰도를 높인다. 마지막으로 gradient의 방향성을 직접 반영하여 정확도를 높였다는 특징이 있다.
- 실습
아래는 직접 실습한 코드이다.


사실 기본적으로 Gaussian blur가 포함된 알고리즘 치고는 횡단보도 페인트 사이사이의 노이즈가 잘 출력된 것을 알 수 있다. Threshold를 극단적으로 조절하여보았지만 첨부한 사진 정도가 최선이었다. 어떻게 보면 Sobel graident 혹은 Laplacian gradient보다 정말 정교하고 정확하게 edge를 출력한다는 의미로 해석할 수 있을 것 같다. 하지만 사용 목적에 따라서는 노이즈를 더욱 지우고 싶을수도 있을 것 같았다.
따라서 Gaussian blur를 추가로 수행하여 원하는 만큼의 스무딩을 진행한 후 다시 Canny detection을 적용하여보았다.


결과적으로 (5,5) 커널 사이즈 정도만 사용해서 blur를 추가적으로 진행해주면 최종 Canny detection에서 노이즈가 많이 감소하는 것을 알 수 있다.
Canny detection이 다양한 단계를 추가하여 성능을 높이려고 노력하였으나, 이미지에 따라 학습하는 알고리즘이 아니라 사전에 정해진 값으로 blur를 수행하기 때문에 대량의 이미지의 edge 검출을 원한다면 이미지마다 위와 같이 추가적은 처리가 필요하다는 단점이 존재하는 것 같다고 생각하였다.
'딥러닝 > 기타 공부' 카테고리의 다른 글
| [기타 공부] Hough Transform (6) | 2025.01.20 |
|---|---|
| [기타 공부] Sobel gradient, Laplacian gradient (2) | 2025.01.18 |