반응형
Canny Edge Detection
1986년 J.Canny는 에지 검출을 최적화 문제 관점으로 접근함으로써 Sobel edge 검출 방법의 단점을 헤결 할 수 있는 방법을 제시(Canny86)
Canny는 자신의 논문에서 다음 세가지 항목을 좋은 Edge dectection의 조건으로 제시
- 정확한 검출(GOOD DETECTION) : 에지를 검출하지 못하거나 또는 에지가 아닌데 에지로 검출하는 확률을 최소화해야 한다.
- 정확한 위치(GOOD LOCALIZATION) : 실제 에지의 중심을 찾아야 한다.
- 단일 에지(SINGLE EDGE) : 하나의 에지는 하나의 점으로 표현되어야 한다.
케니는 이러한 조건을 만족하는 새로운 형태의 에지 검출 방법을 제시하였으며, 이를 케니 에지 검출기라고 함.
케니 에지 검출기는 그라디언트의 크기와 방향을 모두 고려하여 좀 더 정확한 에지 위치를 찾을 수 있음.
에지는 서로 연결되어 있는 가능성이 높다는 점을 고려하여 그라디언트 크기가 다소 약하게 나타나는 에지도 놓치지 않고 찾을 수 있음.
▶ cv2.Canny(IMG, Threshold1, Threshold2, Eeges = None, ApertureSize = None, L2gradient = None)
- IMG : 입력 이미지
- Threshold1 : 최소 값
- Threshold2 : 최대 값
- Edges : 파이썬에서는 필요 없음.
- ApertureSize : 소벨 마스크 크기 (Default : 3)
- L2Gradient : True/False (Default : False)
cv2.Canny()¶
먼저 magnitude로 실행후 차이점 확인
In [5]:
# Lena, sobel 적용 후 magnitude로 에지 추출
import cv2
import numpy as np
src = cv2.imread('./image/lena.jpg', 0)
gx = cv2.Sobel(src, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=3)
gy = cv2.Sobel(src, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=3)
gx1 = cv2.Sobel(src, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=9)
gy1 = cv2.Sobel(src, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=9)
mag = cv2.magnitude(gx, gy)
mag1 = cv2.magnitude(gx1, gy1)
dstM = cv2.normalize(mag, 0, 255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
dstM1 = cv2.normalize(mag1, 0, 255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
plt.style.use("grayscale")
plt.figure(figsize=(15,30)) #width, height
ax1 = plt.subplot(1,2,1)
ax2 = plt.subplot(1,2,2)
ax1.imshow(dstM)
ax2.imshow(dstM1)
ax1.axis('off')
ax2.axis('off')
ax1.set_title("")
ax2.set_title("")
# cv2.imshow('src', src)
# cv2.imshow('dstM', dstM)
# cv2.imshow('dstM1', dstM1)
# cv2.waitKey()
# cv2.destroyAllWindows()
# cv2.waitKey(1)
Out[5]:
Text(0.5, 1.0, '')
In [6]:
src = cv2.imread('./image/lena.jpg', 0)
dst1 = cv2.Canny(src, 90, 90)
dst2 = cv2.Canny(src, 120, 120)
dst3 = cv2.Canny(src, 150, 150)
dst4 = cv2.Canny(src, 170, 170)
dst5 = cv2.Canny(src, 190, 190)
dst6 = cv2.Canny(src, 210, 210)
dst7 = cv2.Canny(src, 250, 250)
dst8 = cv2.Canny(src, 360, 360)
plt.style.use("grayscale")
plt.figure(figsize=(15,30)) #width, height
ax1 = plt.subplot(4,2,1)
ax2 = plt.subplot(4,2,2)
ax3 = plt.subplot(4,2,3)
ax4 = plt.subplot(4,2,4)
ax5 = plt.subplot(4,2,5)
ax6 = plt.subplot(4,2,6)
ax7 = plt.subplot(4,2,7)
ax8 = plt.subplot(4,2,8)
ax1.imshow(dst1)
ax2.imshow(dst2)
ax3.imshow(dst3)
ax4.imshow(dst4)
ax5.imshow(dst5)
ax6.imshow(dst6)
ax7.imshow(dst7)
ax8.imshow(dst8)
ax1.axis('off')
ax2.axis('off')
ax3.axis('off')
ax4.axis('off')
ax5.axis('off')
ax6.axis('off')
ax7.axis('off')
ax8.axis('off')
ax1.set_title("(90, 90)")
ax2.set_title("(120, 120)")
ax3.set_title("(150, 150)")
ax4.set_title("(170, 170)")
ax5.set_title("(190, 190)")
ax6.set_title("(210, 210)")
ax7.set_title("(250, 250)")
ax8.set_title("(360, 360)")
# cv2.imshow('dst', dst)
# cv2.waitKey()
# cv2.destroyAllWindows()
# cv2.waitKey(1)
Out[6]:
Text(0.5, 1.0, '(360, 360)')
In [ ]:
# window 구동
import cv2
import numpy as np
def onChange(x) :
pass
def edge_detection2():
src = cv2.imread('./image/lena.jpg', cv2.IMREAD_GRAYSCALE)
cv2.namedWindow('edge detection')
cv2.createTrackbar('Low threshold', 'edge detection', 0, 255, onChange)
cv2.createTrackbar('High threshold', 'edge detection', 0, 255, onChange)
cv2.imshow("edge detection", src)
while True :
k = cv2.waitKey(0) & 0xFF
if k == 27 :
break
low = cv2.getTrackbarPos('Low threshold', "edge detection")
high = cv2.getTrackbarPos('High threshold', "edge detection")
if low > high :
print('Low threshold must be low than high threshold')
elif ((low == 0) and (high == 0)) :
cv2.imshow('edge detection', src)
else :
canny = cv2.Canny(src, low, high)
cv2.imshow('edge detection', canny)
cv2.destroyAllWindows()
edge_detection2()
반응형
'Python' 카테고리의 다른 글
[Python] openCV : Hough Transformation (0) | 2022.11.17 |
---|---|
[Python] openCV : Corner Detect (0) | 2022.11.17 |
[Python] openCV : Labeling (0) | 2022.11.17 |
[Python] openCV : Morphology (0) | 2022.11.17 |
[Python] openCV : Filltering (0) | 2022.11.17 |