< Hough Line Transform >
이번 장에서는
- Hough Transform에 대해서 이해하고
- 이미지내의 선을 어떻게 탐지하는지 배우고
- cv2.HoughLines(), cv2.HoughLinesP() 함수
에 대해 알아볼 것이다.
Theory
Hough Transform은 그 모양을 수학적 형태로 나타낼 수 있다면 어떤 형태든 감지하는 인기있는 기법이다. 형체가 조금 부러지거나 일그러져도 감지할 수 있다. 우리는 그것이 어떤 선에 어떻게 작용하는지 볼 것이다!
선은
만약 선이 원점 아래로 통과하고 있다면, 이는 양의
이제 Hough Transform이 선에 어떻게 작용하는지 보자. 어떤 선이든 이 두 가지 용어로 나타낼 수 있다. (
가운데 수평선이 있는 100x100 이미지를 생각해보자. 줄의 첫 점을 잡아보자. (x,y)가 될 것이다. 이제 선 방정식에,
이제 두 번째 점을 선위에 짚어보자. 위와 같이,
이는 선에 대해 Hough Transform이 어떻게 작동하는지를 보여준다. 이는 간단한데, Numpy를 사용하여 구현할 수도 있다. 아래 이미지는 축압기를 보여준다. 밝은 지역들은 이미지내에서 선이 있을 가능성의 파라미터를 나타낸다.
Hough Transform in OpenCV
위에 설명된 모든 것은 OpenCV에 내장된 cv2.HoughLines()에 대한 것이다. 이는 단순하게
import cv2
import numpy as np
img = cv2.imread('./images/sdoku.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize=3)
lines = cv2.HoughLines(edges,1,np.pi/180,200)
for line in lines:
rho,theta = line[0]
a = np.cos(theta)
b = np.sin(theta)
x0 = a*rho
y0 = b*rho
x1 = int(x0+1000*(-b))
y1 = int(y0+1000*(a))
x2 = int(x0-1000*(-b))
y2 = int(y0-1000*(a))
cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)
cv2.imwrite("HoughLine-0.jpg",img)
아래 결과를 보자
Probabilistic Hough Transform
Hough Transform 내에서, 두 개의 인자가 있는 선에 대해 많은 계산이 필요하다는 것을 알 수 있다. 확률론적 Hough Transform은 우리가 본 Hough Transform의 최적화된 버전이다. 이는 모든 점을 고려하지 않고, 임의의 점 하위 집합만을 취한다. 이는 선 탐지에 충분하다. 그리고 임계값을 낮춘다. hough 공간에서 Hough Transform과 Probabilistic Hough Transform을 비교하는 아래 이미지를 참조하자.
OpenCV 구현은 Matas, J. 및 Galambos, C. 및 Kittler, J.V.의 점진적 확률론적 Hough Transform을 사용하여 Robust Detection of Lines에 기초한다. 사용된 함수는 cv2.HoughLinesP()이다. 여기는 두 개의 새로운 인자가 등장한다.
- minLineLength - 선의 최소 길이이다. 이보다 짧은 선분은 버려진다.
- maxLineLength - 단일 선으로 처리하기 위해 선분 간에 허용되는 최대 간격이다.
가장 좋은 것은, 두 개의 선 끝점을 직접적으로 반환한다는 것이다. 이전의 경우에는 선의 매개변수를 얻었을 뿐, 모든 점을 찾아야 했다. 여기서는 모든 것이 직접적이고 간단하다.
import cv2
import numpy as np
img = cv2.imread('./images/sdoku.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize=3)
minLineLength = 100
maxLineGap = 10
lines = cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength,maxLineGap)
for line in lines:
x1,y1,x2,y2 = line[0]
cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)
cv2.imwrite('HoughLine-1.jpg',img)