OpenCV / / 2022. 11. 14. 16:49

OpenCV - 허프 변환 직선 , 원 검출

'''
<허프 변환 직선 검출>

-직선 성분을 찾기 위해 에지를 찾아내고, 에지 픽셀들이 일직선상에 배열되어 있는지 확인
-영상에서 직선을 찾기 위한 용도로 허프 변환 기법이 널리 사용됨
-허프 변환은 2차원 XY 좌표에서 직선의 방정식을 파라미터 공간으로 변환하여 직선을 찾는 알고리즘
-2차원 평면에서 직선의 방정식은 다음과 같이 나타낼 수 있음

y= AX +B
A는 기울기, B는 Y절편

XY좌표 공간의 직선 방정식을 AB좌표 공간으로 변형

B = -XA + Y

허프 변환으로 직선의 방정식을 찾으려면 XY 공간에서 엣지로 판별된 모든 점을
이용하여 AB 파라미터 공간에 직선을 표현

직선이 많이 교차되는 좌표를 모두 찾아야 함

이때 직선이 많이 교차하는 점을 찾기 위해서 보통 축적 배열을 사용함

축적배열은 0 으로 초기화된 2차원 배열에서 직선이 지나가는 위치의 배열 원소 값을
1씩 증가시켜 생성함

cv2.HOUGHLINES(IMG,RHO,THETA,THERSHOLD,MIN_THETA,MAX_THETA)

cv2.HOUGHLINESP(IMG,RHO,THETA,THRESHOLD,MINLINELENGTH,MAXLINEGAP)


'''
#실습

src = cv2.imread('./rect.jpg')
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# 캐니 에지
edges = cv2.Canny(gray, 50, 210)
# xy 평면을 rho theta 평면 변환


lines = cv2.HoughLinesP(edges, rho=1, theta=np.pi/180.0, threshold=50)
print('lines.shape=', lines.shape)
for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(src, (x1, y1), (x2, y2), (0, 0, 255), 2)
   
cv2.imshow('canny', edges)
cv2.imshow('src', src)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.waitKey(1)
 
'''레나에 허프 변환 적용 하기 '''


src = cv2.imread('./lena.jpg')
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# 캐니 에지
edges = cv2.Canny(gray, 30, 70)
# xy 평면을 rho theta 평면 변환
lines = cv2.HoughLinesP(edges, rho=1, theta=np.pi/180.0, threshold=90)
print('lines.shape=', lines.shape)
for line in lines:
    x1, y1, x2, y2 = line[0]
    cv2.line(src, (x1, y1), (x2, y2), (0, 0, 255), 2)
    
cv2.imshow('canny', edges)
cv2.imshow('src', src)
cv2.waitKey()
cv2.destroyAllWindows()
cv2.waitKey(1)

<허프 변환 원 검출>
 
-원의 중심 좌표를 찾는 과정에서 축적 배열 사용
-허프 그래디언트 방법에서 사용하는 축적 배열은 파라미터 공간에서
만드는 것이 아니라 입력 영상과 동일한 XY 좌표 공간에서 2차원 배열로 만듦

-원의 중심을 찾기 위해 허프 그래디언트 방법은 입력 영상의 모든 엣지 픽셀에서 그래디언트를 구함

-그래디언트 방향을 따르는 직선상의 축적 배열 값을 1씩 증가시킴

-원주상의 모든 점에 대해 그래디언트 방향의 직선을 그림

-직선상의 축적 배열 값을 증가시키면 결과적으로 원의 중심 위치에서 축적 배열 값이 크게 나타나게 됨

-일단 원의 중심을 찾은 후에는 다양한 반지름의 원에 대해 원주상에 충분히 많은 엣지 픽셀이
존재하는지 확인하여 적절한 반지름을 선택함

cv2.HOUGHCIRCLES ( IMG, METHOD, DP ,,MINDIST , CIRCLES, PARAM1, PARAM2, MINRADIUS, MAXRADIUS)
-3개의 변수에 대해 계산하는 것은 비효율적 이므로 가장자리에서 기울기를 측정하여
원을 그리는데 관련이 있는 점인지를 확인할 수 있는 HOUGH GRADIENT METHOD를 사용

IMG : INPUT(CANNY EDGE 선 적용 후)
METHOD : 검출 방법, ex)HOUGH_GRADIENT
DP : 해상도
MINDIST : 검출한 원의 중심과의 최소거리, 값이 작으면 원이 아닌 것들도 검출이 되고,
너무 크면 원을 놓칠 수 있음
'''
src = cv2.imread('./circles.jpg')
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)

circles = cv2.HoughCircles(gray, method=cv2.HOUGH_GRADIENT, dp=1, minDist=50, param2=15)

for circle in circles[0]:
    cx, cy, r = circle
    cv2.circle(src, (np.uint32(cx), np.uint32(cy)), np.uint32(r), (0, 0, 255), 2)

cv2.imshow('src', src)
cv2.waitKey()
cv2.destroyAllWindows()
 

  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유