조금씩 꾸준히 완성을 향해

[OpenCV/Python] Edge 검출 - 캐니 엣지검출기(Canny Edge Detector), 허프 변환(Hough Transform) 본문

Python/OpenCV

[OpenCV/Python] Edge 검출 - 캐니 엣지검출기(Canny Edge Detector), 허프 변환(Hough Transform)

all_sound 2022. 11. 15. 11:29

CANNY Edge Detector

  • 정확한 검출(Good Detection), 정확한 위치(Good Localization), 단일 엣지(Single Edge)
  • gradient 크기와 방향을 모두 고려하여 좀 더 정확한 엣지 위치를 찾을 수 있음.
  • 총 4 딘계
    • 가우시안 필터링 > gradient 계산 > 비최대 억제(non-maximum suppression) > 이중 임계값을 이용한 히스테리시스 엣지 트래킹

 

 
  • Sobel vs Canny 
src = cv2.imread('./lena.jpg', cv2.IMREAD_GRAYSCALE)
dst = cv2.Canny(src, 100, 200) #Canny

gxo = cv2.Sobel(src, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=3) #Sobel
gyo = cv2.Sobel(src, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=3)
mag = cv2.magnitude(gxo, gyo)
dst2 = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)

cv2.imshow('src', src)
cv2.imshow('Canny', dst)
cv2.imshow('Sobel', dst2)
cv2.waitKey()
cv2.destroyAllWindows()

 

  • Canny threshold 값 조정
src = cv2.imread('./lena.jpg', cv2.IMREAD_GRAYSCALE)
src = cv2.resize(src, (300, 300))
dst = cv2.Canny(src, 10, 200)
dst1 = cv2.Canny(src, 60, 250)
dst2 = cv2.Canny(src, 180, 240)

img = np.hstack([dst, dst1, dst2])
cv2.imshow('canny1', img)
cv2.waitKey()
cv2.destroyAllWindows()
 

 

허프 변환 직선 검출

  • 직선 성분을 찾기 위해 엣지를 찾아내고, 엣지 픽셀들이 일직선상에 배열되어 있는지 확인
  • 영상에서 직선을 찾기 위한 용도
  • 2차원에서 xy 좌표에서 직선의 방정식을 파라미터 공간으로 변환하여 직선을 찾는 알고리즘
  • xy 좌표 공간의 직선 방정식을 AB좌표 공간으로 변형
    • B = -XA + Y
# 사각형으로 실습

src = cv2.imread('./rect.jpg')
dst = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
dst2 = cv2.Canny(dst, 50, 100)
lines= cv2.HoughLinesP(dst2, rho=1, theta=np.pi/180.0, threshold=50)
print(lines)
for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(src, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv2.imshow('src', src)
cv2.waitKey()
cv2.destroyAllWindows()
 
# lena 이미지로 실습

src = cv2.imread('./lena.jpg')
dst = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
dst2 = cv2.Canny(dst, 50, 100)
lines= cv2.HoughLinesP(dst2, rho=1, theta=np.pi/180.0, threshold=50)
for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(src, (x1, y1), (x2, y2), (0, 0, 0), 2)
cv2.imshow('src', src)
cv2.waitKey()
cv2.destroyAllWindows()
 

허프 변환 원 검출

# circles 이미지

src = cv2.imread('./circles.jpg')
dst = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

circles = cv2.HoughCircles(dst, method = cv2.HOUGH_GRADIENT, dp=1, minDist=50, param2=15)
print('circles:', circles)
print('circles shape:', circles.shape)
 
for i in circles[0, :]:
    cx, cy, r = i
    cv2.circle(dst, (int(cx), int(cy)), radius=int(r), color=(0,0,255), thickness=2)
cv2.imshow('src', src)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()
# lena 이미지

src = cv2.imread('./lena.jpg')
dst = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
dst2 = cv2.Canny(dst, 50, 100)
circles = cv2.HoughCircles(dst2, method = cv2.HOUGH_GRADIENT, dp=1, minDist=200, param2=15)
for i in circles[0, :]:
    cx, cy, r = i
    cv2.circle(src, (int(cx), int(cy)), radius=int(r), color=(0,0,255), thickness=2)
cv2.imshow('src', src)
cv2.waitKey()
cv2.destroyAllWindows()
# 검출이 잘 안됨