无人驾驶 OpenCV (F) 识别车道线
图
接下来进入代码环节,这里详细给大家解释一下 HoughLinesP 参数的含义以及如何使用。
lines = cv2.HoughLinesP(cropped_image,2,np.pi/180,100,np.array([]),minLineLength=40,maxLineGap=5)第一参数是我们要检查的图片
Hough accumulator 数组
第二个和第三个参数用于定义我们 Hough 坐标如何划分 bin,也就是小格的精度。我们通过曲线穿过 bin 格子来进行投票,我们根据投票数量来决定 p 和 theta 的值。2 表示我们小格宽度以像素为单位 。
图
我们可以通过下图划分小格,只需曲线穿过就会对小格进行投票,我们记录投票数量,记录最多的作为参数
图
图
假如定义尺寸过大也就失去精度,假如定义格子尺寸过小尽管精度上来了,这样也会打来增长计算时间。
接下来参数 100 表示我们投票为 100 以上的线才是符合要求是我们要找的线。也就是在 bin 小格子需要有 100 以上线相交于此才是我们要找的参数。
minLineLength 给 40 表示我们检查线长度不能小于 40 pixel
maxLineGap=5 作为线间断不能大于 5 pixel
定义显示车道线方法
def disply_lines(image,lines): pass通过定义函数将找到的车道线显示出来。
line_image = disply_lines(lane_image,lines)查看探测车道线数据结构
def disply_lines(image,lines): line_image = np.zeros_like(image) if lines is not None: for line in lines: print(line)先定义一个尺寸大小和原图一样的矩阵用于绘制查找到车道线,我们先判断一下能否已经找到车道线,lines 返回值应该不为 None 是一个矩阵,我们可以简单地打印一下看一下效果
[[704 418 927 641]][[704 426 791 516]][[320 703 445 494]][[585 301 663 381]][[630 341 670 383]]探测车道线
看数据结构[[x1,y1,x2,y2]] 的二维数组,这就需要我们转换一下为一维数据[x1,y1,x2,y2]
def disply_lines(image,lines): line_image = np.zeros_like(image) if lines is not None: for line in lines: x1,y1,x2,y2 = line.reshape(4) cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10) return line_imageline_image = disply_lines(lane_image,lines)cv2.imshow('result',line_image)
探测线
合成影响
combo_image = cv2.addWeighted(lane_image,0.8, line_image, 1, 1,1)有关合成图片我们是将两张图片通过给肯定权重进行叠加合成。
图
优化
我们通过学习霍夫变换探测到的车道线还是不够平滑,我们需要优化,基本思路就是对这些直线的斜率和截距取平均值而后将所有探测出点绘制到一条直线上。
averaged_lines = average_slope_intercept(lane_image,lines);首先定义我们的函数,接收道路图片和探测点做为参数。
def average_slope_intercept(image,lines): left_fit = [] right_fit = [] for line in lines: x1, y1, x2, y2 = line.reshape(4) parameters = np.polyfit((x1,x2),(y1,y2),1) print(parameters)这里定义两个数组 left_fit 和 right_fit 分别用于存放左右两侧车道线的点,我们打印一下 lines 的斜率和截距,通过 numpy 提供 polyfit 方法输入两个点我们即可以得到通过这些点的直线的斜率和截距。
[ 1. -286.][ 1.03448276 -302.27586207][ -1.672 1238.04 ][ 1.02564103 -299.def average_slope_intercept(image,lines): left_fit = [] right_fit = [] for line in lines: x1, y1, x2, y2 = line.reshape(4) parameters = np.polyfit((x1,x2),(y1,y2),1) # print(parameters) slope = parameters[0] intercept = parameters[1] if slope < 0: left_fit.append((slope,intercept)) else: right_fit.append((slope,intercept)) print(left_fit) print(right_fit)因为左侧和右侧线的斜率不同,我们根据斜率可以划分点到左右两侧的直线矩阵上。
left_fit_average = np.average(left_fit,axis=0) right_fit_average = np.average(right_fit,axis=0)而后通过取平局值来得到他们平均斜率和截距。
[ -1.61019355 1201.00387097][ 1.0243751 -298.80648538]def make_coordinates(image, line_parameters): slope, intercept = line_parameters print(image.shape) return 我们输出一下图片大小,我们图片是以其左上角作为原点 0 ,0 来开始计算的,所以我们直线从图片底部 700 多向上绘制我们无需绘制一律可以截距一部分就可。
![图(https://upload-images.jianshu.io/upload_images/8207483-367e149bfb5a5165.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
图
(704, 1279, 3)(704, 1279, 3) left_line = make_coordinates(image, left_fit_average) right_line = make_coordinates(image, right_fit_average)def make_coordinates(image, line_parameters): slope, intercept = line_parameters y1 = image.shape[0] y2 = int(y1*(3/5)) x1 = int((y1 - intercept)/slope) x2 = int((y2 - intercept)/slope) # print(image.shape) return np.array([x1,y1,x2,y2])所以直线开始和终止我们给定 y1,y2 而后通过方程的斜率和截距根据y 算出 x。
averaged_lines = average_slope_intercept(lane_image,lines);line_image = disply_lines(lane_image,averaged_lines)combo_image = cv2.addWeighted(lane_image,0.8, line_image, 1, 1,1)cv2.imshow('result',combo_image)
result_optimize.png
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 无人驾驶 OpenCV (F) 识别车道线