반응형


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()




반응형

진행해본 결과물을 기록 및 공유하는 공간입니다.
잘못된 부분이나 개선점을 알려주시면 반영하겠습니다.


소스코드 복사시 하단에 있는 앵커 광고의 왼쪽 위를 클릭하여 닫은 후 해야 합니다.


문제가 생기면 포스트와 바뀐 환경이 있나 먼저 확인해보세요.
질문을 남겨주면 가능한 빨리 답변드립니다.


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

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기

댓글을 달아 주세요

TistoryWhaleSkin3.4">