반응형


Sobel 함수를 사용하여 에지를 검출하는 방법을 설명합니다.



마지막 업데이트 - 2018. 10. 16




다음 OpenCV Python 튜토리얼을 참고하여 강좌를 비정기적로 포스팅하고 있습니다.


https://docs.opencv.org/3.4.3/d6/d00/tutorial_py_root.html





에지는 픽셀값이 급격히 변하는 지점입니다.

1차원 그래프로 그려보면 다음처럼 픽셀값이 갑자기 커집니다.




1차 미분해보면 픽셀값이 급격하게 증가한 부분에서 1차 미분값이 큰것을 알 수 있습니다.

주변보다 1차 미분값이 큰 부분을 에지로 검출하게 됩니다.





1차 미분의 근사값을 계산하기 위해 미리 정의한 커널과 이미지를 컨볼루션하여 에지를 검출합니다.

소벨에서는 X 방향 에지 검출과 Y 방향 에지 검출을 위해 별도의 커널을 사용합니다.

   




Sobel x는 수직선 방향의 에지를 검출합니다.  


convertScaleAbs 함수를 사용하여 sobel x 결과에 절대값을 적용하고 값 범위를 8비트 unsigned int로 변경해줘야합니다.

소벨의 커널 크기가 3인 경우에는 Sobel 함수 대신에 Scharr 함수를 사용하는 것이 더 좋은 결과를 얻을 수 있다고 합니다.


img_sobel_x = cv2.Sobel(img_gray, cv2.CV_64F, 1, 0, ksize=3)
img_sobel_x = cv2.convertScaleAbs(img_sobel_x)



  




Sobel y는 수평선 방향의 에지를 검출합니다.  


convertScaleAbs 함수를 사용하여 sobel y 결과에 절대값을 적용하고 값 범위를 8비트 unsigned int로 변경해줘야합니다.


img_sobel_y = cv2.Sobel(img_gray, cv2.CV_64F, 0, 1, ksize=3)
img_sobel_y = cv2.convertScaleAbs(img_sobel_y)



 




sobel x 결과와 sobel y 결과를 결합해야 이미지에 대한 에지 검출이 완료됩니다.


img_sobel = cv2.addWeighted(img_sobel_x, 1, img_sobel_y, 1, 0);


 




테스트에 사용한 이미지와 전체 소스 코드입니다.


  



import cv2


img_color = cv2.imread('box.png', cv2.IMREAD_COLOR)
img_gray = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)

img_sobel_x = cv2.Sobel(img_gray, cv2.CV_64F, 1, 0, ksize=3)
img_sobel_x = cv2.convertScaleAbs(img_sobel_x)

img_sobel_y = cv2.Sobel(img_gray, cv2.CV_64F, 0, 1, ksize=3)
img_sobel_y = cv2.convertScaleAbs(img_sobel_y)


img_sobel = cv2.addWeighted(img_sobel_x, 1, img_sobel_y, 1, 0);


cv2.imshow("Sobel X", img_sobel_x)
cv2.imshow("Sobel Y", img_sobel_y)
cv2.imshow("Sobel", img_sobel)

cv2.waitKey(0)
cv2.destroyAllWindows()




반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts