이 글의 원문은 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_gradients/py_gradients.html 와 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_canny/py_canny.html#canny 입니다.
이 글에서는 이미지의 변화도(Gradients)에 따른 가장자리를 추출하는 내용에 대해 정리합니다.
이미지의 변화도에 따른 가장자리 추출 방법은 Sobel 방법, Scharr 방법, Laplacian 방법이 있습니다. 먼저 Sobel과 Scharr은 변화도를 추출할 방향을 x와 y축으로 지정할 수 있습니다. 그리고 Sobel의 경우 커널 행렬의 크기를 지정할 수 있는 인자가 있지만 Scharr는 필터 행렬의 크기를 지정하는 인자가 없습니다. Laplacian은 변화도의 추출 방향을 지정하는 방식이 아니고 전체 방향으로의 가장자리를 추출하며 커널 행렬의 크기를 지정할 수 있는데 이 행렬 크기를 1로 지정하면 아래의 행렬이 사용됩니다.
코드의 예는 아래와 같습니다.
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('./data/sudoku-original.jpg', 0) laplacian = cv2.Laplacian(img,cv2.CV_8U,ksize=5) sobelx = cv2.Sobel(img,cv2.CV_8U,1,0,ksize=5) sobely = cv2.Sobel(img,cv2.CV_8U,0,1,ksize=5) plt.subplot(2,2,1),plt.imshow(img,cmap = 'gray') plt.title('Original'), plt.xticks([]), plt.yticks([]) plt.subplot(2,2,2),plt.imshow(laplacian,cmap = 'gray') plt.title('Laplacian'), plt.xticks([]), plt.yticks([]) plt.subplot(2,2,3),plt.imshow(sobelx,cmap = 'gray') plt.title('Sobel X'), plt.xticks([]), plt.yticks([]) plt.subplot(2,2,4),plt.imshow(sobely,cmap = 'gray') plt.title('Sobel Y'), plt.xticks([]), plt.yticks([]) plt.show()
결과는 다음과 같습니다.
위의 코드에서 cv2.Laplacian과 cv2.Sobel 함수의 2번째 인자에 결과 데이터의 타입을 cv2.CV_8U로 지정하고 있습니다. 이 데이터 타입의 문제는 정보의 소실이 발생한다는 것인데, 검정색에서 하얀색으로 변화도는 음수값이므로 음의 경사라고 하고 하얀색에서 검정색으로 변화도는 양의 값이므로 양의 경사라고 합니다. cv2.CV_8U로 지정하면 음의 값은 모두 0으로 변환되어 버리게 되는데, 이처럼 음의 변화도에 대한 정보도 유지하기 위해서는 결과 데이터 타입을 정밀도가 더 높으면서 부호값을 가지는 cv2.CV_16S, cv2.CV_64F로 지정한 뒤에 다시 cv2.CV_8U로 변환하는 것을 추천합니다. 이에 대한 예제 코드가 다음과 같습니다.
지금까지 살펴본 이미지에 대한 Gradients(변화도)는 가장자리(Edge) 검출을 위한 인자로 활용되는데, 가장 유명한 가장자리 검출을 위한 방법은 Canny Egde Detection이며 예제 코드는 다음과 같습니다.
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('./data/messi5.jpg', 0) edges = cv2.Canny(img, 200, 255) plt.subplot(121),plt.imshow(img,cmap = 'gray') plt.title('Original Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(edges,cmap = 'gray') plt.title('Edge Image'), plt.xticks([]), plt.yticks([]) plt.show()
실행 결과는 다음과 같습니다.
6번 코드의 cv2.Canny 함수의 2번째와 3번째 각 픽셀이 가장자리 인지의 여부에 대한 기준값이 되는 minThresholdingValue, maxThresholdingValue입니다. 이값을 조정하여 원하는 수준의 가장자리를 검출을 조정할 수 있습니다.
잘 보았어요,
수학적 영상처리는 역시 입력 이미지가 중요하다는 ~
캐니에지는 생성형AI 에서도 중요하게 쓰입니다.
https://brunch.co.kr/@f6cf51e0a3154dc/123
이렇게요.