메뉴 건너뛰기

XEDITION

project2018

[검색] 강좌 7 OpenCV를 이용한 자율 주행 소개

proin 2018.06.14 00:51 조회 수 : 1

https://github.com/HyOsori/Osori-SelfDrivingWithGTA5/wiki/%EA%B0%95%EC%A2%8C-7----OpenCV%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9E%90%EC%9C%A8-%EC%A3%BC%ED%96%89-%EC%86%8C%EA%B0%9C


강좌 7 OpenCV를 이용한 자율 주행 소개

import numpy as np
from PIL import ImageGrab
import cv2
import time
from numpy import ones,vstack
from numpy.linalg import lstsq
from directkeys import PressKey, W, A, S, D
from statistics import mean

def roi(img, vertices):
    
    #blank mask:
    mask = np.zeros_like(img)   
    
    #filling pixels inside the polygon defined by "vertices" with the fill color    
    cv2.fillPoly(mask, vertices, 255)
    
    #returning the image only where mask pixels are nonzero
    masked = cv2.bitwise_and(img, mask)
    return masked

차선 그리기

선들 중 유사한 기울기의 행 개수를 이용해, 가장 유사한 상위 2개의 기울기를 갖는 직선을 차선에 가장 적합하다고 계산

def draw_lanes(img, lines, color=[0, 255, 255], thickness=3):

    try:
        ys = []  
        for i in lines:
            for ii in i:
                ys += [ii[1],ii[3]]
        min_y = min(ys)
        max_y = 600
        new_lines = []
        line_dict = {}

        for idx,i in enumerate(lines):
            for xyxy in i:
                x_coords = (xyxy[0],xyxy[2])
                y_coords = (xyxy[1],xyxy[3])
                A = vstack([x_coords,ones(len(x_coords))]).T
                m, b = lstsq(A, y_coords)[0]

                # Calculating our new, and improved, xs
                x1 = (min_y-b) / m
                x2 = (max_y-b) / m

                line_dict[idx] = [m,b,[int(x1), min_y, int(x2), max_y]]
                new_lines.append([int(x1), min_y, int(x2), max_y])

        final_lanes = {}

        for idx in line_dict:
            final_lanes_copy = final_lanes.copy()
            m = line_dict[idx][0]
            b = line_dict[idx][1]
            line = line_dict[idx][2]
            
            if len(final_lanes) == 0:
                final_lanes[m] = [ [m,b,line] ]
                
            else:
                found_copy = False

                for other_ms in final_lanes_copy:

                    if not found_copy:
                        if abs(other_ms*1.2) > abs(m) > abs(other_ms*0.8):
                            if abs(final_lanes_copy[other_ms][0][1]*1.2) > abs(b) > abs(final_lanes_copy[other_ms][0][1]*0.8):
                                final_lanes[other_ms].append([m,b,line])
                                found_copy = True
                                break
                        else:
                            final_lanes[m] = [ [m,b,line] ]

        line_counter = {}

        for lanes in final_lanes:
            line_counter[lanes] = len(final_lanes[lanes])

        top_lanes = sorted(line_counter.items(), key=lambda item: item[1])[::-1][:2]

        lane1_id = top_lanes[0][0]
        lane2_id = top_lanes[1][0]

        def average_lane(lane_data):
            x1s = []
            y1s = []
            x2s = []
            y2s = []
            for data in lane_data:
                x1s.append(data[2][0])
                y1s.append(data[2][1])
                x2s.append(data[2][2])
                y2s.append(data[2][3])
            return int(mean(x1s)), int(mean(y1s)), int(mean(x2s)), int(mean(y2s)) 

        l1_x1, l1_y1, l1_x2, l1_y2 = average_lane(final_lanes[lane1_id])
        l2_x1, l2_y1, l2_x2, l2_y2 = average_lane(final_lanes[lane2_id])

        return [l1_x1, l1_y1, l1_x2, l1_y2], [l2_x1, l2_y1, l2_x2, l2_y2], lane1_id, lane2_id
    except Exception as e:
        print(str(e))

이미지 처리

def process_img(image):
    original_image = image

    # RGB to GRAY
    processed_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Canny 외곽선 검출
    processed_img =  cv2.Canny(processed_img, threshold1 = 200, threshold2=300)
    
    # 이미지 가우시안 정규화
    processed_img = cv2.GaussianBlur(processed_img,(5,5),0)
    
    # 관심영역만 필터링, 4강 참고
    vertices = np.array([[10,500],[10,300],[300,200],[500,200],[800,300],[800,500],], np.int32)
    processed_img = roi(processed_img, [vertices])

    # Hough 알고리즘, 5강 참고
    lines = cv2.HoughLinesP(processed_img, 1,  np.pi/180, 180,   20,         15)

    m1 = 0 # 차선 1의 기울기
    m2 = 0 # 차선 2의 기울기

    # 차선 그리기
    try:
        l1, l2, m1, m2 = draw_lanes(original_image, lines)
        cv2.line(original_image, (l1[0], l1[1]), (l1[2], l1[3]), [0,255,0], 30)
        cv2.line(original_image, (l2[0], l2[1]), (l2[2], l2[3]), [0,255,0], 30)

    except Exception as e:
        print(str(e))
        pass

    # 외곽선 그리기(For Debug)
    try:
        for coords in lines:
            coords = coords[0]
            try:
                cv2.line(processed_img, (coords[0], coords[1]), (coords[2], coords[3]), [255,0,0], 3)     
                
            except Exception as e:
                print(str(e))
    except Exception as e:
        pass

    return processed_img, original_image, m1, m2

차량 운전

def straight():
    PressKey(W)
    ReleaseKey(A)
    ReleaseKey(D)

def left():
    PressKey(A)
    ReleaseKey(W)
    ReleaseKey(D)
    ReleaseKey(A)

def right():
    PressKey(D)
    ReleaseKey(A)
    ReleaseKey(W)
    ReleaseKey(D)

def slow_ya_roll():
    ReleaseKey(W)
    ReleaseKey(A)
    ReleaseKey(D)

두 차선의 기울기를 이용한 차량 운전 방향 결정(right, left, straight)

def main():
    last_time = time.time()
    while True:
        screen =  np.array(ImageGrab.grab(bbox=(0,40,800,640)))
        print('Frame took {} seconds'.format(time.time()-last_time))
        last_time = time.time()
        new_screen,original_image, m1, m2 = process_img(screen)
        #cv2.imshow('window', new_screen)
        cv2.imshow('window2',cv2.cvtColor(original_image, cv2.COLOR_BGR2RGB))

        if m1 < 0 and m2 < 0:     # / /
            right()
        elif m1 > 0  and m2 > 0:  #  
            left()
        else:                     # / 
            straight()

        #cv2.imshow('window',cv2.cvtColor(screen, cv2.COLOR_BGR2RGB))
        if cv2.waitKey(25) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

 

번호 제목 글쓴이 날짜 조회 수
91 [검색] [Udacity] SelfDrivingCar- 2-4. 차선 인식(응용) proin 2018.06.20 5
90 [검색] 자율 주행 프로젝트 (opencv, stereo camera , 차선인식 , 장애물 감지 및 회피) proin 2018.06.20 3
89 [검색] [자율주행장난감] Hough Transform을 통한 차선 검출 proin 2018.06.20 2
88 [검색] 강좌 6 OpenCV를 이용한 차선 검출 proin 2018.06.20 4
87 [Open CV] Visual Studio 2015에서 OpenCV 3.2 연동하기 proin 2018.06.19 2
86 [OpenCV] Visual Studio 2017에서 OpenCV 3.4.1를 사용하는 방법 proin 2018.06.19 1
85 ubuntu 16.04에서 iptables설정 save하기 proin 2018.06.18 1
84 PHP 서버 timezone 설정 방법 proin 2018.06.18 2
83 Ubuntu 서버 16.04에 LEMP 스택 설치하기 (Nginx, MySQL, PHP) proin 2018.06.17 5
82 [자율주행] 뭔가 참고하기 괜찮을 듯한 것 proin 2018.06.14 1
81 [YouTube] OpenCV를 이용한 자율주행 자동차 proin 2018.06.14 1
» [검색] 강좌 7 OpenCV를 이용한 자율 주행 소개 proin 2018.06.14 1
79 Layer 화면 중앙정렬 방법 proin 2018.06.10 4
78 [Ubuntu] MySQL 외부접속 설정하기 proin 2018.06.10 2
77 한번에 끝내는 Ubuntu 웹서버세팅 (우분투 서버세팅) proin 2018.06.07 9
76 [linux] 리눅스 링크 폴더 만들기 proin 2018.06.07 2
75 [기본] 리눅스의 퍼미션(권한)을 조정하기 (chmod, chown) proin 2018.06.07 2
74 우분투 - FTP 서버의 설치와 이용법 - vsftpd proin 2018.06.07 1
73 DNSZi에서 Dynamic DNS (리눅스 DDNS 자동 업데이트 설정)관리 하는 법 proin 2018.06.05 1
72 iptables를 사용한 방화벽 설정 proin 2018.06.05 3
위로