OpenCV로 차선인식하기 [허프변환]
컴퓨터비전

OpenCV로 차선인식하기 [허프변환]

반응형

 

 

허프변환(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 필터링을 이용해 차선만 남기고 제거하면 꽤 정확한 차선인식이 가능하다. 그리고 대부분의 노이즈도 제거가 가능하고 곡선도 어느정도는 검출이 가능하다.

 

[추가]

아래와 같이 응용이 가능하다.

 

 

 

반응형
    # 테스트용