오늘은 Edge Detection 을 하는 방법에 대해서 정리해보겠다.
우선 이미지의 엣지를 어떻게 정의할 수 있을까? 바로 이미지에서 픽셀들의 Intensity가 급격하게 변화하는 부분이다. 픽셀값이 이미지의 어떤 부분에서 급격하게 변하는지는 인접한 픽셀들의 값을 비교해보면 구할 수 있다.
만약 픽셀값들이 연속적이라고 가정한다면 미분을 통해 각 픽셀에서의 Intensity 변화량을 계산할 수 있을 것이다. 이미지는 2D로 x, y 성분이 있으므로 Gradient 를 계산하면 된다.

엣지의 강도는 Gradient의 크기로 생각할 수 있다.

마지막으로 엣지의 방향은 다음과 같다.

하지만 이미지 픽셀값들은 연속적이지 않기 때문에 실제로 미분 계산을 할 수는 없고(실제 이미지의 Intensity 값은 Discrete Grid 형태이기 때문에), 대신 미분값을 근사해야 한다.

왼쪽 그림과 같이 픽셀들의 Intensity 값을 알고 있을 때 미분값 근사는 다음과 같이 계산할 수 있다. (이때, 각 픽셀의 중심점 간 거리를 ε 으로 정의한다)



위 계산은 Convolution을 통해서도 진행할 수 있다.

실제로 이미지에서 Intensity 변화량을 계산하기 위해 나온 다양한 Gradient Operator (커널) 들이 있다. 몇가지 예시들을 살펴보겠다.
- Roberts Cross Operator

- Prewitt Operator

- Sobel Operator (3x3)

- Sobel Operator (5x5)

Gradient Operator 크기가 작으면 Localization이 뛰어나지만 작은 영역 안에서만 계산하기 때문에 노이즈에 취약해진다. 반면 Gradient Operator 크기가 클수록 Localization은 저하되지만 노이즈에 덜 민감해지고 엣지를 잘 찾아낼 수 있다.
이렇게 픽셀에서의 Gradient를 계산했으니 Gradient의 크기(S)를 통해 엣지인지 아닌지 판단을 해야한다. 다음과 같은 두가지 방법이 있다.
- Single Threshold T를 정해 S > T 일때 Edge로 판단하는 방법
- Two Threshold A, B 를 정해 S < A 이면 Not an Edge, S > B 이면 Edge, A < S < B 이면 이웃한 픽셀이 Edge 인 경우에만 Edge로 판단하는 방법
픽셀들의 Intensity 값을 미분해서 극대가 되는 부분을 엣지로 판단했으니(실제로는 Threshold 값을 정했지만, 극대가 되는경우 웬만하면 엣지로 볼 수 있을 것이다) 라플라시안을 통해서도 엣지를 찾을 수 있다. 라플라시안 값이 0을 강하게 크로스 하는 부분을 엣지로 판단할 수 있다.

이 계산 역시 Gradient를 계산했을 때와 같이 근사를 해야 한다. 픽셀값들의 변화량의 변화량을 계산하는 것이다. 그리고 위에서와 마찬가지로 Convolution을 통해 계산을 해낼 수 있다.




이 커널을 통한 계산도 효과적이지만, 대각선 정보를 반영하지 못한다. Edge 는 x축 y축과 평행하게만 나타나지 않고 대각 방향으로도 나타날 수 있기 때문에 더 효과적인 커널로 다음을 사용하기도 한다.

실제 이미지에서 Edge Detection을 수행할 경우, 영상에 포함된 노이즈로 인해 엣지가 아닌 영역이 엣지로 검출되는 문제가 발생하기 쉽다. 이를 완화하기 위해 Gaussian smoothing을 convolution과 함께 적용하는 방법이 널리 사용되며, 노이즈 억제와 엣지 안정성 측면에서 매우 효과적이다.
First Derivative 기반의 엣지 검출과 Laplacian 기반 엣지 검출은 각각 서로 다른 장단점을 가진다. First Derivative을 사용하는 경우, 엣지의 강도뿐만 아니라 방향 정보까지 계산할 수 있다는 장점이 있다. 반면, Laplacian은 엣지의 방향 정보를 제공하지는 않지만, x축과 y축 방향의 미분을 각각 계산할 필요 없이 단일 convolution 연산으로 처리할 수 있어 계산량이 상대적으로 적다. 이러한 장단점을 종합적으로 고려하여 설계된 대표적인 엣지 검출 기법이 Canny Edge Detection이다.
Canny Edge Detection의 과정은 다음과 같다.
- 노이즈의 영향을 줄이기 위해 이미지에 2D Gaussian Smoothing을 적용한다.
- Sobel Operator을 사용해 Gradient 계산한다.
- 각 픽셀에서의 Gradient Magnitude를 계산한다.
- 각 픽셀에서의 Gradient Orientation을 계산한다. (엣지의 방향을 찾기 위해서)
- 각 픽셀에서 Gradient의 방향을 따라 국소 최대값만 남기고 나머지는 0으로 만든다. 이렇게 하면 Smoothing에 의해서 두꺼워진 엣지를 얇게 만들 수 있다.

6. 위에서 설명한 방법처럼 Two Threshold 를 정해 Strong Edge와 연결되지 않은 Weak Edge들을 제거한다.
openCV를 통해 이미지에 Canny Edge Dectection 적용을 해보자.
img = cv2.imread("/content/drive/MyDrive/Dataset/opencv/Rabbit.jpg")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
edges1 = cv2.Canny(img_rgb, 100, 200) # Edge 검출 하단 임계값, 상단 임계값
edges2 = cv2.Canny(img_rgb, 100, 500)
edges3 = cv2.Canny(img_rgb, 100, 700)
# 상단 임계값이 커질수록 검출되는 엣지가 적어지는 것을 확인할 수 있음
fig, axs = plt.subplots(1, 3, figsize=(12, 6))
axs[0].imshow(edges1)
axs[0].set_title("Canny Edge Image 1")
axs[1].imshow(edges2)
axs[1].set_title("Canny Edge Image 2")
axs[2].imshow(edges3)
axs[2].set_title("Canny Edge Image 3")
plt.show()

같은 이미지에 세번 Canny Edge Detection을 적용했고 Strong Edge 판단 기준인 상단 임계값만 다르게 조정했다. Threshold 값이 커질수록 검출된 엣지의 양이 적어지는 것을 확인할 수 있다.
공부에 도움이 된 자료들:
https://www.youtube.com/watch?v=lOEBsQodtEQ
https://www.youtube.com/watch?v=uNP6ZwQ3r6A
https://he-kate1130.tistory.com/148
'컴퓨터 비전' 카테고리의 다른 글
| AlexNet 구현, CIFAR-10 이미지 분류하기 (0) | 2026.01.14 |
|---|---|
| AlexNet의 구조와 구현 (0) | 2026.01.10 |
| openCV 활용한 문서 스캐너 프로그램 만들기(2) (0) | 2025.12.28 |
| openCV 활용한 문서 스캐너 프로그램 만들기 (0) | 2025.12.16 |
| PCA(주성분 분석)를 통해 이미지에서 특성 추출하기 - (2) (0) | 2025.11.14 |