허프변환(Hough transform)은 직선을 찾는 가장 유명하고 일반적인 알고리즘이다.
전에 자율주행 차를 제작했을때 (2018/08/09 - [아두이노/프로젝트] - 자율주행차량 만들기(아두이노+OpenCV) #3 - 계획수정) 차선인식과 관련해 개인적으로 많은 질문을 받았었다. 그래서 허프변환을 이용해 차선을 검출하는 방법을 소개해 볼까한다.
허프변환은 직선 차선을 검출하는 하나의 좋은 예가 될 수있지만 정밀한 검출은 어렵다는 것을 상기하길 바란다.
허프변환의 원리와 코드는 아래의 사이트를 참고했음을 밝힌다.
https://docs.opencv.org/3.4.0/d9/db0/tutorial_hough_lines.html
개발환경은 파이썬 3.6x, OpenCV, 파이참이다. OpenCV 설치는 2018/07/26 - [프로그래밍/OpenCV] - OpenCV 윈도우+파이썬+파이참 개발환경 (window+python+pycharm) 를 참고하자.
차선인식 코드는 아래와 같다.
import cv2
import sys
import math
import cv2 as cv
import numpy as np
cap = cv2.VideoCapture("your video file")
while (True):
ret, src = cap.read()
src = cv2.resize(src, (640, 360))
dst = cv.Canny(src, 50, 200, None, 3)
cdst = cv.cvtColor(dst, cv.COLOR_GRAY2BGR)
cdstP = np.copy(cdst)
lines = cv.HoughLines(dst, 1, np.pi / 180, 150, None, 0, 0)
if lines is not None:
for i in range(0, len(lines)):
rho = lines[i][0][0]
theta = lines[i][0][1]
a = math.cos(theta)
b = math.sin(theta)
x0 = a * rho
y0 = b * rho
pt1 = (int(x0 + 1000 * (-b)), int(y0 + 1000 * (a)))
pt2 = (int(x0 - 1000 * (-b)), int(y0 - 1000 * (a)))
cv.line(cdst, pt1, pt2, (0, 0, 255), 3, cv.LINE_AA)
linesP = cv.HoughLinesP(dst, 1, np.pi / 180, 50, None, 50, 10)
if linesP is not None:
for i in range(0, len(linesP)):
l = linesP[i][0]
cv.line(cdstP, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 3, cv.LINE_AA)
cv.imshow("Source", src)
cv.imshow("Detected Lines (in red) - Standard Hough Line Transform", cdst)
cv.imshow("Detected Lines (in red) - Probabilistic Line Transform", cdstP)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
테스트에 사용하기 좋은 동영상 파일도 같이 올린다. 아래 링크에서 다운이 가능하다.
https://drive.google.com/open?id=1SFsNTVjOIK10em0bphv95UinQs_MsSbw
코드에서 your video file에 사용할 동영상 파일을 추가하면 된다. 아래는 실행 결과이다.
차선은 2가지 방식으로 검출되는데 각각 cv2.HoughLines(image, rho, theta, threshold[, lines[, srn[, stn[, min_theta[, max_theta]]]]])와 cv2.HoughLinesP(image, rho, theta, threshold, minLineLength, maxLineGap)의 함수를 사용한 결과이다. 각각의 함수의 사용법은 https://opencv-python.readthedocs.io/en/latest/doc/25.imageHoughLineTransform/imageHoughLineTransform.html 을 참고하자.
영상에서도 알수있듯 허프변환의 단점은 명확하다. 곡선에서는 사용이 불가능하며 차선이 아닌 직선도 차선으로 인식한다는 것이다.
물론 HSV를 이용한 필터링과 ROI로 영역을 나누면 꽤 쓸만해진다. 아래는 그렇게 구현해본 차선인식 영상이다.
이렇게 ROI로 영역을 선택하고 HSV 필터링을 이용해 차선만 남기고 제거하면 꽤 정확한 차선인식이 가능하다. 그리고 대부분의 노이즈도 제거가 가능하고 곡선도 어느정도는 검출이 가능하다.
[추가]
아래와 같이 응용이 가능하다.
'컴퓨터비전' 카테고리의 다른 글
matplotlib, OpenCV로 데이터 clustering 하기 (cluster 개수 없이) (0) | 2019.02.10 |
---|---|
OpenCV 공 추적하기 (14) | 2018.08.30 |
스틱 PC에 OpenCV 설치하기 (OpenCV+Python) (0) | 2018.08.11 |
OpenCV edge 검출 (모서리 검출) (1) | 2018.08.03 |
OpenCV 웹캠 얼굴인식 (Python) (0) | 2018.07.29 |