OpenCV를 사용하던 중 edge detection을 위한 다양한 방법의 원리가 궁금해졌다.
기본적으로 이들은 high pass filter를 기반으로 edge를 검출하는 방식이다. 이를 위해 미분으로 각 pixel의 색상 변화율을 계산하고 급격한 변화를 보이는 부분을 검출하게되는데, OpenCV에서는 이러한 high pass filter에 Sobel, Laplacian gradient filter를 사용한다. 그래서 이 두 가지 방법을 먼저 공부해보았다.
1. Sobel gradient

이것은 위와 같은 3x3 filter를 사용하여 x방향과 y방향으로 각각 미분 값을 구하여 edge를 detect하는 방법이다. 각각의 kerenel을 Gx, Gy로 정의한다. 특히 위의 필터를 각 방향에 적용하였을 때, 미분 연산과 스무딩 효과를 동시에 얻을 수 있다는 장점이 있다. 어떻게 가능한 것일까?
예를 들어 x축의 kernel을 살펴보자.
- 미분 연산
x축 방향으로는 [-1, 0, 1], [-2, 0, 2]의 값을 사용한다. 비율은 동일하기 때문에 단순하게 [-1, 0, 1]로 대표해서 생각해보자. 우리는 미분이라는 것을 배울 때 아래와 같은 정의를 먼저 배우게 된다. 이러한 미분 방식을 forward difference라고 부른다.

하지만 해당 정의를 알고리즘으로 구현하면 한쪽으로 치우쳐진 차분으로 미분을 구하기 때문에 미분값의 근사 정확도가 떨어지게 된다. 이건은 backward difference에서도 마찬가지이다. 따라서 "중앙 차분"을 사용하여 그 오차율을 낮출 수 있다.

바로 이 centered difference에서 h=1로 가정하면, 우리가 사용한 필터의 행 방향 [-1, 0, 1]을 의미한다는 것을 알 수 있다.
필터에서 1은 I(x+1), 0은 I(x)를 제거하는 것을, -1은 I(x-1)을 빼는 것을 의미하는 것이다. 신호및시스템에서 filter들에 대해서 배웠지만 이렇게 kernel을 사용해 간단하지만 강력하게 구현하는 아이디어가 놀라웠다.
- 스무딩 효과
다음은 스무딩 효과의 이유를 알아보자. x방향 kerenel의 세로 방향으로는 [1,2,1]을 통해 가우시안 커널과 비슷하게 스무딩을 진행할 수 있다. 스무딩이라는 것은 결국 low pass filter를 사용하여 강한 고주파 신호들을 완화시켜주는 방법이다. 따라서 이 방법은 Gaussian blur와 유사하게 이뤄지기 때문에 먼저 Gaussian distribution을 살펴보자.

위와 같은 Gaussian distrubution에서 표준편차의 값이 1이 된다면 [1, 2, 1]로 분포가 근사될 수 있다.
식을 직관적으로 이해한다면, [a, b, c]라는 픽셀 값이 순서대로 올 때 [1, 2, 1] 커널을 적용시켜보자. (a + 2b + c) / 4 라는 값을 최종적으로 얻을 것이다. 즉 가운데 값에는 상대적으로 큰 가중을 유지하면서, 주변 값들을 반영시켜주어 평균을 얻는다. 이것으로 서로 강한 경계면을 가지는 경우 이것을 완화시켜줄 수 있는 것이다.
이러한 두가지 효과는 y방향 kernel에도 동일하게 이뤄지고, 따라서 Sobel gradient filter를 통해 미분과 스무딩을 동시에 얻을 수 있는 것이다.
- Sobel 필터의 특징
단순 미분으로 edge를 구하는 것이 아니라, 스무딩을 동시에 수행하여 노이즈에 강하다는 점이 특징이 된다. 스무딩 효과를 함께 사용하기 때문에, 미분 연산에서 민감하게 반응할 수 있는 미세한 고주파 성분들을 사전에 제거하여 edge 검출의 정확도를 향상시킬 수 있게된다.
한 가지 주의해야 하는 점은 sobel filter가 데이터를 처리하는 방식이다. 흰색 -> 검정색으로 변화하는 부분을 음수로, 검정색 -> 흰색으로 변화하는 부분을 양수로 변화하는 특징을 가진다. 그런데 np.uint8과 같이 음수가 존재하지 않는 데이터 타입을 가진다면 음수값을 모두 0으로 바꾸게 된다. 즉 흰색에서 검정색으로 변화하는 부분을 detect하지 못하는 것이다. Sobel 함수를 사용할 때 주의해야 할 것 같다.

- 실습
아래는 직접 코드로 실습해본 결과이다.


Sobel X를 살펴보면 도로, 횡단보도의 세로선이 확연하게 강조되는 것을 알 수 있다. 반면 횡단보도의 가로선은 거의 검출되지 않은 것을 알 수 있다.
반면 Sobel Y를 살펴보면 도로의 세로선은 흐릿하게 검출되지만 횡단보도의 가로선이 상대적으로 강하게 검출되는 것을 알 수 있다.
즉 x 방향 미분과 스무딩을 통해 좌, 우의 미분값 변화를 계산하고 이 값이 크면 해당 부분의 세로선을 검출하는 것이고, y 방향도 마찬가지로 가로선을 검출하는 것을 확인할 수 있었다.
2. Laplacian gradient

나는 Laplacian gradient를 전자기학에서 위와 같이 vertor 미분을 배우며 제대로 접했던 기억이 있다. 이번에는 이미지를 처리하게 때문에 아래와 같은 2D 형태만을 사용하면 된다.

당시에 라플라스 연산을 divergence of gradient 형태로 배웠던 기억이 난다. Graident은 위에서도 보았듯이 변화율을 계산하는 것이고 divergence는 해당 방향으로 퍼져 나가는 정도의 의미로 이해하고있다. 여기서 divergence가 0이면 퍼져 나가는 정도에 변화가 없는 것이므로 균일한 흐름을 의미하게된다.
즉 라플라스 연산은 그러한 divergence에 대한 변화율을 의미하는 것으로 벡터 내에서 벡터의 흐름이 균일하지 못한 정도(변화)를 의미한다고 이해해할 수 있다.
수식에서는 2차 미분을 사용하다는 것으로 해석할 수 있다. 1차 미분이 급격한 변화를 나타내는 부분의 값을 큰 절댓값을 가지는 미분 값으로 검출할 수 있다면, 이차미분을 통해 이 부분을 변곡점으로 해석하여 0의 값으로 바꿔서 얻을 수 있다. 이것으로 픽셀 값의 변화가 급격한 곳을 강조하며 빠르게 검출할 수 있다.

기본적으로 위와 같이 4방향 kernel 혹은 8방향 kernel을 사용하여 계산한다. 예를 들어 4방향 kernel의 의미는 아래와 같은 식으로 풀어서 쓰게되면 라플라스 연산과 동일하다는 것을 알 수 있다.

- Laplacian 필터의 특징
Edge를 검출하는 과정이 빠르고 간단하다는 특징을 가진다. 하지만 노이즈에 민감하기 때문에 사전에 Gaussian blur와 같은 low pass filter를 통한 스무딩 과정을 사용하는 것이 도움이 될 수 있다.
- 실습
이것을 직접 코드로 실습해본 결과이다.


앞선 Sobel gradient를 사용했을 때와 비교해보면 edge detection의 정도가 강하지 않은 것을 알 수 있다. 하지만 x, y방향을 동시에 수행하기 때문에 균일하게 edge가 검출된 것을 알 수 있다.
또 한가지 차이점을 보자면, 노이즈에 약한 라플라시안 미분은 횡단보도 사이의 도로 흠집과 같은 노이즈가 edge와 균일한 강도로 출력된 것을 확인할 수 있다. 따라서 스무딩의 필요성을 보여주는 부분이라고 생각했다.
참고: https://m.blog.naver.com/samsjang/220506567638?recommendTrackingCode=2
'딥러닝 > 기타 공부' 카테고리의 다른 글
| [기타 공부] Hough Transform (6) | 2025.01.20 |
|---|---|
| [기타 공부] Canny Detection (0) | 2025.01.18 |