[computer-vision] 도형 검출
직선 검출
src = cv.imread("road.webp")
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
# 윤곽선 추출
canny = cv.Canny(gray, 5000, 1500, apertureSize = 5, L2gradient = True)
허프 변환
- 윤곽선을 이루는 점들을 지나는 직선의 방정식을 찾음
- 여러 개의 직선들 중에 가장 조건에 맞는 직선들만 골라냄
멀티 스케일 허프 변환 Multi-Scale Hough Transform
lines = cv.HoughLines(
canny,
0.8, # 거리 측정 해상도, 0~1
np.pi / 180, # 각도의 해상도(라디안)
150, # 임계값(키울 수록 정확도 증가하고 검출되는 직선의 수는 감소)
srn = 100, # 거리의 약수(≥0), 허프 변환을 좀 더 정확하게 하기 위한 값
stn = 200, # 각도의 약수(≥0), 허프 변환을 좀 더 정확하게 하기 위한 값
min_theta = 0, # 최소 각도
max_theta = np.pi) # 최대 각도
시각화
dst = src.copy()
for i in lines:
rho, theta = i[0][0], i[0][1]
a, b = np.cos(theta), np.sin(theta)
x0, y0 = int(a*rho), int(b*rho)
scale = src.shape[0] + src.shape[1]
x1 = int(x0 + scale * -b)
y1 = int(y0 + scale * a)
x2 = int(x0 - scale * -b)
y2 = int(y0 - scale * a)
cv.line(dst, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv.circle(dst, (x0, y0), 3, (255, 0, 0), 5, cv.FILLED)
점진성 확률적 허프 변환 Progressive Probabilistic Hough Transform
# 속도는 빠르지만 정확성은 떨어지는 방식
lines = cv.HoughLinesP(
canny,
0.8, # 거리 측정 해상도, 0~1
np.pi / 180, # 각도의 해상도(라디안)
90, # 임계값(키울 수록 정확도 증가하고 검출되는 직선의 수는 감소)
minLineLength = 10, # 검출할 직선의 최소 길이
maxLineGap = 100) # 최대 허용 간격(이 간격 내에 있는 직선은 검출 안함)
시각화
dst = src.copy()
lines = lines.astype(int, copy=False)
for i in lines:
cv.line(
dst,
(i[0][0], i[0][1]), # 시작
(i[0][2], i[0][3]), # 끝
(0, 255, 0), # 색깔
2) # 굵기
원 검출
src = cv.imread("balls.webp") # 예제 이미지
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
circles = cv.HoughCircles(# 허프 변환
gray,
cv.HOUGH_GRADIENT, # 검출 방법, HOUGH_GRADIENT_ALT도 있음
1, # 해상도 비율
100, # 원의 중심 간 최소 거리
param1 = 250, # 검출 방법의 매개 변수
param2 = 10, # 검출 방법의 매개 변수
minRadius = 80, # 최소 반지름
maxRadius = 120) # 최대 반지름
시각화
dst = src.copy()
circles = circles.astype(int)
for i in circles[0]:
cv.circle(dst, (i[0], i[1]), i[2], (255, 255, 255), 5)