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