아래 내용은 파이썬으로 만드는 OpenCV 프로젝트(이세우 저) 를 공부하며 정리한 내용들입니다.
모든 소스 코드를 확인하고 싶으시다면 제일 하단의 저자 GitHub 주소를 참고하시기 바랍니다.
영상에서 경계(edge)를 검출하는 것은 배경과 전경을 분리하는 데 가장 기본적인 작업이다. 경계 검출은 객체 인식과 추적에서 아주 중요한 작업이다.
영상의 경계를 검출해서 경계에 있는 픽셀만을 골라서 강조하면 경계를 선명하게 만들 수 있다.
14.1 기본 미분 필터
경계를 검출하려면 픽셀 값의 변화가 갑자기 크게 일어나는 지점을 찾아내야 한다. 연속된 픽셀값에 미분 연산을 통해 알 수 있다.
1차 미분 연산의 x축과 y축 방향에 대한 기본적인 커널은 다음과 같다.
$$ G_x = \begin{bmatrix} -1 & 1 \end{bmatrix} \\ G_y = \begin{bmatrix} -1 \\ 1 \end{bmatrix} $$
미분으로 얻은 엣지 정보는 각각 x축과 y축에 대한 값의 변화를 나타내는 것이고 이것을 기울기, 그래디언트(gradient)라고 한다.
$G_x, G_y$ 두 값을 이용하면 엣지의 강도(magnitude)와 방향(direction)이라는 정보도 추가로 얻을 수 있다. 그래디언트의 방향과 엣지의 방향은 서로 수직이다.
$$ magnitude = \sqrt {G_x^2 + G_y^2} \\ direction(\theta) = arctan({G_y \over G_x}) $$
이 값들은 영상의 특징을 묘사하는 중요한 단서가 되고 이를 이용해 영상끼리 얼마나 비슷한지도 알아낼 수 있다.
14.2 로버츠 교차 필터
1963년 로렌스 로버츠(Lawrence Robers)가 제안한 기본 미분 커널을 개선한 커널이다.
$$ G_x = \begin{bmatrix} +1 & 0 \\ 0 & -1 \end{bmatrix} \\ G_y = \begin{bmatrix} 0 & +1 \\ -1 & 0 \end{bmatrix} $$
이 커널은 대각선 방향으로 1과 -1을 배치해서 사선 경계 검출 효과를 높였지만 노이즈에 민감하고 엣지 강도가 약한 단점이 있다.
14.3 프리윗 필터
주디스 프리윗(Judith M. S. Prewitt)이 개발한 프리윗 마스크는 각 방향으로 차분을 세 번 계산하도록 배치해서 엣지 강도가 강하고 수직과 수평 엣지를 동등하게 찾는 장점이 있지만 대각선 검출이 약하다. 프리윗 필터는 다음과 같은 커널을 사용한다.
$$ G_x = \begin{bmatrix} -1 & 0 & +1 \\ -1 & 0 & +1 \\ -1 & 0 & +1 \end{bmatrix} \\ G_y = \begin{bmatrix} -1 & -1 & -1 \\ 0 & 0 & 0 \\ +1 & +1 & +1 \end{bmatrix} $$
14.4 소벨 필터
1968년 어윈 소벨(Irwin Sobel)이 제안한 중심 픽셀의 차분 비중을 두 배로 주어 수평, 수직, 대각선 경계 검출에 모두 강한 마스크이다.
$$ G_x = \begin{bmatrix} -1 & 0 & +1 \\ -2 & 0 & +2 \\ -1 & 0 & +1 \end{bmatrix} \\ G_y = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ +1 & +2 & +1 \end{bmatrix} $$
소벨 마스크는 가장 대표적인 1차 미분 마스크로 OpenCV에서는 전용 함수를 제공한다.
로버츠, 프리윗 등의 필터는 실무에서는 거의 사용하지 않고 역사적인 의미와 교육적인 의미만 있다.
- dst = cv2.Sobel(src, ddepth, dx, dy[, dst, ksize, scale, delta, borderType])
- src : 입력 영상, Numpy 배열
- ddepth : 출력 영상의 dtype(-1 : 입력 영상과 동일)
- dx, dy : 미분 차수(0, 1, 2 중 선택, 둘 다 0일수는 없음)
- ksize : 커널의 크기(1, 3, 5, 7 중 선택)
- scale : 미분에 사용할 계수
- delta : 연산 결과에 가산할 값
14.5 샤르 필터
소벨 필터는 커널의 크기가 작은 경우, 또는 커널의 크기가 크더라도 그 중심에서 멀어질수록 엣지 방향성의 정확도가 떨어지는 단점이 있다. 이를 개선한 필터가 샤르(Scharr) 필터이다.
$$ G_x = \begin{bmatrix} -3 & 0 & +3 \\ -10 & 0 & +10 \\ -3 & 0 & +3 \end{bmatrix} \\ G_y = \begin{bmatrix} -3 & -10 & -3 \\ 0 & 0 & 0 \\ +3 & +10 & +3 \end{bmatrix} $$
- dst = cv2.Scharr(src, ddepth, dx, dy[, dst, scale, delta, borderType]) :
- 함수의 인자는 ksize가 없다는 것을 제외하면 cv2.Sobel()과 동일하다.
14.6 라플라시안 필터
미분 결과를 다시 미분하는 2차 미분을 적용하면 경계를 좀 더 확실히 검출할 수 있다. 라플라시안(Laplacian) 필터는 대표적인 2차 미분 마스크이다.
$$ \begin{align*} {d^2f \over dy^2} & = {df(x, y+1) \over dy} - {df(x, y+1) \over dy} \\ & = [f(x, y+1) - f(x, y)] - [f(x, y) - f(x, y-1)] \\ & = f(x, y+1) - 2f(x, y) + f(x, y-1) \end{align*} $$
$$ kernel = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix} $$
- dst = cv2.Laplacian(src, ddepth[, dst, ksize, scale, delta, borderType) :
- 함수의 인자는 cv2.Sobel()과 동일하다.
라플라시안 필터는 노이즈에 민감하므로 사전에 가우시안 필터로 노이즈를 제거하고 사용하는 것이 좋다.
14.7 캐니 엣지
1986년 존 캐니(John F. Canny)가 제안한 캐니 엣지 알고리즘은 한 가지 필터를 사용하는 것이 아니라 4단계의 알고리즘을 적용한 잡음에 강한 엣지 검출기이다.
- 노이즈 제거(Noise Reduction) : 5 x 5 가우시안 블러링 필터로 노이즈를 제거
- 엣지 그래디언트 방향 계산 : 소벨 마스크로 엣지 및 그래디언트 방향을 검출
- 비최대체 억제(Non-Maximum Suppression) : 그래디언트 방향에서 검출된 엣지 중에 가장 큰 값만 선택하고 나머지는 제거
- 이력 스레시홀딩(Hysteresis Thresholding) : 두 개의 경계값(Max, Min)을 지정해서 경계 영역에 있는 픽셀들 중 큰 경계값 밖의 픽셀과 연결성이 없는 픽셀을 제거
OpenCV는 이 알고리즘을 구현한 함수를 제공한다.
- edges = cv2.Canny(img, threshold1, threshold2 [, edges, apertureSize, L2gradient])
- img : 입력 영상, Numpy 배열
- threshold1, threshold2 : 이력 스레시홀딩에 사용할 최소, 최대값
- apertureSize : 소벨 마스크에 사용할 커널 크기
- L2gradient : 그래디언트 강도를 구할 방식 지정 플래그
- True : $\sqrt {G_x^2 + G_y^2}$
- False : $|G_x| + |G_y|$
- edges : 엣지 결과값을 갖는 2차원 배열
캐니 엣지는 경계 검출 결과가 뛰어나고 스레시홀드 값의 지정에 따라 경계 검출 대상을 조정할 수 있어서 가장 많이 사용되는 함수이다.
REFERENCE
- 소스 코드 참고(저자 GitHub 주소)
GitHub - dltpdn/insightbook.opencv_project_python
Contribute to dltpdn/insightbook.opencv_project_python development by creating an account on GitHub.
github.com
- OpenCV 공식문서
OpenCV: OpenCV modules
OpenCV 4.7.0 Open Source Computer Vision
docs.opencv.org
'ML & DL > OpenCV' 카테고리의 다른 글
[OpenCV] 16. 이미지 피라미드 (0) | 2023.03.21 |
---|---|
[OpenCV] 15. 모폴로지 (0) | 2023.03.17 |
[OpenCV] 13. 컨볼루션과 블러링 (0) | 2023.03.13 |
[OpenCV] 12. 렌즈 왜곡 (0) | 2023.03.09 |
[OpenCV] 11. 뒤틀기 (0) | 2023.03.06 |
댓글