Edge detection

정승균·2021년 1월 24일
0

OpenCV

목록 보기
6/7
post-thumbnail

1. Sobel


  • 가우시안 필터 + 미분연산

  • dx=1, dy=0, ksize=3 인 경우 커널은 다음과 같음

kernel=[101202101]kernel = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix}
  • dst = cv.Sobel(src, ddepth, dx, dy, ksize=ksize)
    • src : input image
    • ddepth : output image 깊이. uint8인 경우 음수가 0으로 처리되어 결과가 다 나오지 않을 수 있음
    • dx : x 축 미분 차수 (0,1,2)
    • dy : x 축 미분 차수 (0,1,2), dx dy 중 하나는 보통 0으로 놓음
    • ksize : Sobel kernel 크기 (1,3,5,7). -1 인 경우 Scharr 3*3 커널 사용

2. Laplacian


  • Sobel의 2차 미분값을 가지고 계산
dst=Δsrc=2srcx2+2srcy2\texttt{dst} = \Delta \texttt{src} = \frac{\partial^2 \texttt{src}}{\partial x^2} + \frac{\partial^2 \texttt{src}}{\partial y^2}
  • ksize가 1 일때 다음과 같음
kernel=[010141010]kernel = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix}
  • dst = cv.Laplacian(src, ddepth, ksize=ksize)
    • src : source image
    • ddepth : output image 깊이. uint8인 경우 음수가 0으로 처리되어 결과가 다 나오지 않을 수 있음
    • ksize : 2차 미분값을 계산할 Sobel의 커널 사이즈, 양의 홀수

3. Canny


  • 궁극의 에지 검출 알고리즘

    1. 5x5 가우시안 필터로 노이즈 제거

    2. Sobel 커널로 edge gradient의 방향과 크기 계산

      Edge_Gradient  (G)=Gx2+Gy2Angle  (θ)=tan1(GyGx)Edge\_Gradient \; (G) = \sqrt{G_x^2 + G_y^2} \\ Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg)
    3. 각 픽셀에 대해서 gradient 방향의 neigbor중에 최대값이 아니라면 0으로 놓음

    4. gradient 값이 maxVal 이상이면 edge로 판단, minVal 이하이면 egde가 아니라고 판단. 그 사이의 값이면 이미 판단된 edge와 연결되있는지 여부로 판단

  • edges = cv.Canny(image, threshold1, threshold2, apertureSize=3, L2gradient=false)

    • image : 8-bit input image
    • threshold1, threshold2 : 알고리즘에 사용할 minVal과 maxVal
    • apertureSize : 알고리즘에 사용할 Sobel 커널 사이즈
    • L2gradient : bool, gradient 크기를 L2 norm 으로 쓸지 L1 norm으로 쓸지

코드 예시


import cv2

src = cv2.imread("src/ex_codes/person.jpeg", cv2.IMREAD_COLOR)
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

canny = cv2.Canny(src, 100, 255)
sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, 3)
laplacian = cv2.Laplacian(gray, cv2.CV_8U, ksize=3)

img = cv2.hconcat((sobel,canny,laplacian))

cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

0개의 댓글