进一步优化的检测通道

时间:2019-02-21 12:18:08

标签: python opencv

我编写了一个程序来检测道路上的车道,以便以后可以对其进行培训以将其转变为自动驾驶汽车。从某种意义上说,该游戏具有怪异的地图,其中包含从狭窄道路到较宽道路的各种道路。在狭窄的道路上检测车道的性能很好,但是在较宽的道路上,汽车离一个车道的距离越远,检测到该线的难度就越大。这是使我的观点更加清楚的两张图片:

enter image description here

enter image description here

import cv2
from preparation.preprocess import createScreen, preprocess_image



while(True):
    #PressKey(W)
    screen = createScreen(0, 60, 850, 530)
    preprocessed_screen = preprocess_image(screen,[[0,245], [0, 140], [440,130], [850,140], [850,245]])
    cv2.imshow('Console',preprocessed_screen)
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break



import numpy as np
import cv2
from PIL import ImageGrab



# Given vertices and the image whose reason of interest is taken, returns an image whose pixels are black but the reason of interest.
# param | image : The image whose reason of interest is taken
# param | vertices : The boundraies that designate the reason of interest
# return |imagesize_roi : The image of reason of interest
def getReasonInterest(image, vertices):
    mask = np.zeros_like(image) # Creates a matrice with 0s of size image. (If the dimension is larger than 32, use zeros_like instead of zeros
    cv2.fillPoly(mask, vertices, 255) # Code every pixel as 255(11111111) in the area designated by vertices
    imagesize_roi = cv2.bitwise_and(image, mask) # Since the area that is out of reason of interest consists of 0s, those pixels
    # arent going to change. Since the rest of the pixels are 1, simply what image contains is assigned to imagesize_roi.
    # Remember! 0 is black, 255 is white.
    return imagesize_roi



# Given coordinates on the diagonal, create a screen to be captures into python.
# param | top_left_x : X value of top left diagonal
# param | top_left_y : Y value of top left diagonal
# param | bottom_right_x : X value of bottom right diagonal
# param | bottom_right_y : Y value of bottom right diagonal
# return | RGB_img : The designated image of the given coordinates
# NOTE: Remember to scroll the real game screen where it belongs to.
def createScreen(top_left_x, top_left_y, bottom_right_x, bottom_right_y):
    printscreen_pil = ImageGrab.grab(bbox=(top_left_x, top_left_y, bottom_right_x, bottom_right_y))
    printscreen_numpy = np.array(printscreen_pil).reshape((printscreen_pil.size[1], printscreen_pil.size[0], 3))
    RGB_img = cv2.cvtColor(printscreen_numpy, cv2.COLOR_BGR2RGB) # Convert the colors what they really are
    return RGB_img



# Transform the given image into black and white image, then get the reason of interest that is designated by vertices and returns it.
# param | original_image : The image that the operations mentioned above are applied
# param | vertices : The boundraies that designate the reason of interest
# return | roi_image : The image that the operations mentioned above are applied
def preprocess_image(original_image, vertices):
    gray_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY) # color image : [255,255,255], gray image : [255] - MORE EFFICIENT
    processed_image = cv2.Canny(gray_image,300,400)
    vertices = np.array(vertices, np.int32)
    blurred_image = cv2.GaussianBlur(processed_image, (5,5), 0) # (5,5) probably the kernel filter size. Idk what the 0 is
    roi_image = getReasonInterest(blurred_image, [vertices])
    # second and third parameters are accuracies. fourth parameter is threshold : # of votes that needs to be considered as a line
    # five parameter is minimum length of a line. sixth parameter is the gap between two lines that can be considered as two different lines
    lines = cv2.HoughLinesP(roi_image, rho=6, theta=np.pi / 60, threshold=160, lines=np.array([]), minLineLength=40, maxLineGap=25) # returns two elements : lines as pixel, lines as radians.return roi_image
    line_image = findLanes(original_image, lines)
    if line_image == None:
        return original_image
    original_image_with_lanes = drawLanes(original_image,[[[line_image[0], line_image[1], line_image[2], line_image[3]],[line_image[4], line_image[5], line_image[6], line_image[7]],]],thickness=5)
    return original_image_with_lanes



# Draw the given lanes onto the given image so that the lanes can be followed.
# param | img : The image that lanes are drawn
# param | lines : Lanes that are drawn onto the given image
# param | color : Color of the lanes
# param | thickness : Thickness of the lanes
def drawLanes(img, lines, color=[0, 0, 255], thickness=3):
    if lines is None: # If there are no lines to draw, exit.
        return
    img = np.copy(img)
    line_img = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
    for line in lines:
        for x1, y1, x2, y2 in line:
            cv2.line(line_img, (x1, y1), (x2, y2), color, thickness)
    img = cv2.addWeighted(img, 0.8, line_img, 1.0, 0.0)
    return img



# Collects all edges on the screen, creates two lanes that can be followed.
# param | image : image the lanes that are drawn onto
# param | lines : edges that are detected on roi_image
# return | coordinates of the lanes if no exception is thrown, None otherwise
def findLanes(image, lines):
    left_line_x = []
    left_line_y = []
    right_line_x = []
    right_line_y = []
    try:
        for line in lines:
            for x1, y1, x2, y2 in line:
                if (y2 - y1 == 0) or (x2 - x1 == 0): # preventing from divided by zero excpetion and from slope == 0 etc
                    continue
                slope = (y2 - y1) / (x2 - x1)
                if np.math.fabs(slope) < 0.5: # eliminating horizontal lines
                    continue
                if slope <= 0:
                    left_line_x.extend([x1, x2])
                    left_line_y.extend([y1, y2])
                else:
                    right_line_x.extend([x1, x2])
                    right_line_y.extend([y1, y2])
        min_y = int(image.shape[0] * (2 / 5))
        max_y = int(image.shape[0])
        poly_left = np.poly1d(np.polyfit(left_line_y, left_line_x, deg=1))
        left_x_start = int(poly_left(max_y))
        left_x_end = int(poly_left(min_y))
        poly_right = np.poly1d(np.polyfit(right_line_y, right_line_x, deg=1))
        right_x_start = int(poly_right(max_y))
        right_x_end = int(poly_right(min_y))
        return [left_x_start, max_y, left_x_end, min_y,right_x_start, max_y, right_x_end, min_y]
    except:
        return None

我该如何即兴创作呢?预先谢谢你。

0 个答案:

没有答案