自动驾驶:车道线检测及车位线检测
发布时间
阅读量:
阅读量
本文介绍了基于颜色分割和边缘检测的车道检测方法。首先,在环境搭建部分使用了Anaconda进行技术配置,并详细描述了从视频获取每一帧的过程(如读取帧数、灰度化处理等)。接着,在边缘检测方法中使用了Canny算法(代码示例),并通过霍夫变换进一步优化车道检测效果(代码示例)。整个流程包括颜色分割(处理白色车道)、Canny边缘检测以及霍夫变换结合的结果显示(如中间结果图片)。最终实现了对原始视频的输出效果并提供了对应的代码实现(如linesedges = cv2.addWeighted(coloredges, 0.8, line_image, 1, 0))。
文章目录
-
环境搭建
-
- anaconda
-
步骤
-
- 使用颜色分割
-
边缘检测方法
-
霍夫变换 + canny
-
以下是部分源码
环境搭建
anaconda
步骤
从视频中提取出每一帧。
将所有帧转换为灰度图像。
通过Canny算法进行边缘检测。
利用霍夫变换识别车道线。
优化输出结果后生成新的视频文件。




基于车道检测生成的视频输出结果, 百度网盘存储
使用颜色分割
车道的颜色通常是白色的。当日光充足时,您可以轻松地检测到白色车道,但请考虑一下夜晚。几乎无法检测到车道。但这不是拒绝颜色分割算法的唯一原因。您可以想象在现实世界中有很多物体接近白色或完全白色。对象具有某些特征,例如颜色,形状,方向,位置等,这将有助于我们检测它们。
AI助手
- 红绿蓝的值范围是0(黑)到255(白)
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
image = mpimg.imread('./test_images/test.jpg')
print('This image is: ', type(image), ', and the size of image is: ', image.shape)
ysize = image.shape[0]
xsize = image.shape[1]
region_select = np.copy(image)
color_select= np.copy(image)
line_image = np.copy(image)
print(1)
red_threshold = 200
green_threshold = 200
blue_threshold = 200
rgb_threshold = [red_threshold, green_threshold, blue_threshold]
left_bottom = [0, 540]
right_bottom = [960, 540]
apex = [480, 320]
fit_left = np.polyfit((left_bottom[0], apex[0]), (left_bottom[1], apex[1]), 1)
fit_right = np.polyfit((right_bottom[0], apex[0]), (right_bottom[1], apex[1]), 1)
fit_bottom = np.polyfit((left_bottom[0], right_bottom[0]), (left_bottom[1], right_bottom[1]), 1)
color_thresholds = (image[:,:,0] < rgb_threshold[0]) | (image[:,:,1] < rgb_threshold[1]) | (image[:,:,2] < rgb_threshold[2])
XX, YY = np.meshgrid(np.arange(0, xsize), np.arange(0, ysize))
region_thresholds = (YY > (XX*fit_left[0] + fit_left[1])) & (YY > (XX*fit_right[0] + fit_right[1])) & (YY < (XX*fit_bottom[0] + fit_bottom[1]))
color_select[color_thresholds] = [0,0,0]
line_image[~color_thresholds & region_thresholds] = [255,0,0]
region_select[region_thresholds] = [255, 0, 0]
plt.imshow(region_select)
plt.imshow(color_select)
plt.imshow(line_image)
AI助手
边缘检测方法
Canny边缘检测器是一种用于图像处理的边界识别工具,在这一领域中具有重要地位。该方法源自John F. Canny于1986年提出的创新性算法。
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import cv2
import numpy as np
image = mpimg.imread('./test_images/exit-ramp.jpg')
plt.imshow(image)
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
plt.imshow(gray, cmap='gray')
kernel_size = 9
blur_gray = cv2.GaussianBlur(gray, (kernel_size, kernel_size), 0)
low_threshold = 30
high_threshold = 100
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
plt.imshow(edges)
AI助手
霍夫变换 + canny
- 霍夫变换是一种用于图像分析、计算机视觉以及数字图像处理中的特征提取技术。该方法旨在通过投票机制识别特定形状中对象的不完整实例,并在参数空间中执行这一过程。具体而言,在参数空间(即累加器空间)中寻找候选对象中的局部最大值点。经典的霍夫变换主要用于检测直线,在此基础上它已被扩展以识别圆形、椭圆形等其他形状的位置关系。在图像空间中的一条直线对应于参数空间中的一个点,在这种理论指导下我们得以检测图片中的线条特征。
- 霍夫算法包含一些关键参数设置这些参数对于算法性能至关重要
- 视频处理与图片处理具有相似性其共同点在于均需对连续的帧数进行图像数据的处理
- 从视频中逐帧读取图像数据
video = cv2.VideoCapture('test_videos\solidWhiteRight.mp4')
# This line extracts just one frame in each run.
frame = video.read()
AI助手
- 对于虚线,不是连续的,霍夫算法通过方程来计算
以下是部分源码
import cv2
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from IPython.display import HTML
from base64 import b64encode
from math import floor
# video = cv2.VideoCapture('test_videos\solidWhiteRight.mp4')
# video = cv2.VideoCapture('test_videos\solidYellowLeft.mp4')
video = cv2.VideoCapture('test_videos\challenge.mp4')
nFrames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
fps = video.get(cv2.CAP_PROP_FPS)
waitPerFrameInMillisec = int(1/fps * 1000/1)
frames_list = []
# video_name = 'test_videos_output\output_solidWhiteRight.avi'
# video_name = 'test_videos_output\output_solidYellowLeft.avi'
video_name = 'test_videos_output\output_challenge.avi'
success, image = video.read()
height, width, layers = image.shape
size = (width, height)
out = cv2.VideoWriter(video_name, cv2.VideoWriter_fourcc(*'DIVX'), fps, size)
def improve_lane(last_line, shape, top_line):
x1 = last_line[0]
y1 = last_line[1]
x2 = last_line[2]
y2 = last_line[3]
y_bottom, x, layer = shape
y_top = top_line + 10
m = ((y2 - y1)/(x2 - x1))
x_top = floor((1/m) * (y_top - y1) + x1)
x_bottom = floor((1/m) * (y_bottom - y1) + x1)
return [x_top, y_top, x_bottom, y_bottom]
def run():
success, image = video.read()
if(success == True):
line_image = np.copy(image)
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
blur_gray = cv2.GaussianBlur(gray, (kernel_size, kernel_size), 0)
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)
imshape = image.shape
mask = np.zeros_like(edges)
top_line = 320 #320
left_line = 460 #460
right_line = 500 #500
vertices = np.array([[(0, imshape[0]), (left_line, top_line), (right_line, top_line), (imshape[1], imshape[0])]], dtype=np.int32)
cv2.fillPoly(mask, vertices, ignore_mask_color)
masked_edges = cv2.bitwise_and(edges, mask)
lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap)
max_value_r = 0
min_value_r = 100000
max_value_l = 0
min_value_l = 100000
last_line_l_top = None
last_line_l_bottom = None
last_line_r_top = None
last_line_r_bottom = None
left_line_list = []
right_line_list = []
for line in lines:
left_l = (line[0][0] < left_line) * line
right_l = (line[0][0] > right_line) * line
print('right_l: ', right_l)
if left_l[0][0] != 0:
left_line_list.append(left_l)
if max_value_l < left_l[0][1]:
max_value_l = left_l[0][1]
last_line_l_bottom = left_l[0]
if max_value_l < left_l[0][3]:
max_value_l = left_l[0][3]
last_line_l_bottom = left_l[0]
if min_value_l > left_l[0][1]:
min_value_l = left_l[0][1]
last_line_l_top = left_l[0]
if min_value_l > left_l[0][3]:
min_value_l = left_l[0][3]
last_line_l_top = left_l[0]
if right_l[0][0] != 0:
right_line_list.append(right_l)
if max_value_r < right_l[0][1]:
max_value_r = right_l[0][1]
last_line_r_bottom = right_l[0]
if max_value_r < right_l[0][3]:
max_value_r = right_l[0][3]
last_line_r_bottom = right_l[0]
if min_value_r > right_l[0][1]:
min_value_r = right_l[0][1]
last_line_r_top = right_l[0]
if min_value_r > right_l[0][3]:
min_value_r = right_l[0][3]
last_line_r_top = right_l[0]
# for line in lines:
# for x1, y1, x2, y2 in line:
# cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 10)
x1_t, y1_t, x2_t, y2_t = improve_lane(last_line_l_top, image.shape, top_line)
x1_b, y1_b, x2_b, y2_b = improve_lane(last_line_l_bottom, image.shape, top_line)
x1 = floor((x1_t + x1_b) * 0.5)
y1 = floor((y1_t + y1_b) * 0.5)
x2 = floor((x2_t + x2_b) * 0.5)
y2 = floor((y2_t + y2_b) * 0.5)
cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 10)
if last_line_l_top is None:
print('last_line_l_top')
if last_line_l_bottom is None:
print('last_line_l_bottom')
f_valid = True
if last_line_r_top is None:
f_valid = False
if last_line_r_bottom is None:
f_valid = False
if f_valid == True:
x1 = last_line_r_top[0]
x2 = last_line_r_top[2]
if (x2 - x1) != 0:
x1 = last_line_r_bottom[0]
x2 = last_line_r_bottom[2]
if (x2 - x1) != 0:
x1_t, y1_t, x2_t, y2_t = improve_lane(last_line_r_top, image.shape, top_line)
x1_b, y1_b, x2_b, y2_b = improve_lane(last_line_r_bottom, image.shape, top_line)
x1 = floor((x1_t + x1_b) * 0.5)
y1 = floor((y1_t + y1_b) * 0.5)
x2 = floor((x2_t + x2_b) * 0.5)
y2 = floor((y2_t + y2_b) * 0.5)
cv2.line(line_image, (x1, y1), (x2, y2), (255, 0, 0), 10)
color_edges = np.dstack((edges, edges, edges))
lines_edges = cv2.addWeighted(color_edges, 0.8, line_image, 1, 0)
final_image = cv2.addWeighted(line_image, 0.8, image, 1, 0)
out.write(final_image)
image = None
line_image = None
# run()
for i in range(0, nFrames - 1):
run()
out.release()
print('Finished: ', len(frames_list))
AI助手
全部评论 (0)
还没有任何评论哟~
