python+openCV (入门级)车道线检测 学习笔记

这篇具有很好参考价值的文章主要介绍了python+openCV (入门级)车道线检测 学习笔记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

本文使用python+openCV
用到的算法:
高斯滤波
Canny边缘检测
ROI和mask
霍夫变换
离群值过滤
最小二乘法拟合


一、openCV安装

win+x选择运行,然后输入cmd
输入pip install opencv-python等待安装
在IDLE中新建脚本.py文件,输入import cv2,如果无报错即为安装成功。
再输入print(cv2.__version__)可查看openCV版本。

二、尝试使用cv2中库函数

1.读取图片

cv2.imread(const String & filename, int flags = IMREAD_COLOR)	

第一个参数是窗口的名字,第二个参数是读取格式(彩色或灰度),函数返回值是图片转换格式后所对应的列表。

img = cv2.imread('img.jpg',cv2.IMREAD_GRAYSCALE)

2.图片显示

cv2.imshow(window_name, img)	

第一个参数是窗口的名字,可以创建多个窗口,但是必须给他们不同的名字。第二个参数是显示格式,可以是img图片格式,也可以是mat数组格式。

python+openCV (入门级)车道线检测 学习笔记

3.延时/暂停

cv2.waitKey(int x)

相当于程序延时,调整cv2.imshow()的显示时间。延时时间为x毫秒。返回值为在延时期间按下键盘上按键所对应的ASCII值。

x=0时,即cv2.waitKey(0)表示程序停在此处,直到手动关闭cv2.imshow()的窗口。
例如设计一个,无穷延时,当键盘按下q时退出。

if cv2.waitKey(1) & 0xFF == ord(‘q’): break  
#ord()是将字符转换为ASCII码

4.保存图片

cv2.imwrite(newfile_name, img)

第一个参数是保存的新图片的文件名,第二个参数是应保存的图片对应的列表。

5.清楚所有窗口

cv2.destroyAllWindows()

关闭所有openCV打开的窗口。

三、Canny边缘检测

CV2提供了提取图像边缘的函数canny。其算法思想如下:
1. 使用高斯模糊,去除噪音点(cv2.GaussianBlur)
2. 灰度转换(cv2.cvtColor)
3. 使用sobel算子,计算出每个点的梯度大小和梯度方向
4. 使用非极大值抑制(只有最大的保留),消除边缘检测带来的杂散效应
5. 应用双阈值,来确定真实和潜在的边缘
6. 通过抑制弱边缘来完成最终的边缘检测

1.高斯滤波

gaussian = cv2.GaussianBlur(color_img, (gaussian_ksize,gaussian_ksize), gaussian_sigmax)

color_img 输入图片
gaussian_ksize 高斯核大小,可以为方形矩阵,也可以为矩形
gaussian_sigmax X方向上的高斯核标准偏差
没看太懂这个函数,目前仅局限于搬来直接用,下次一定

2.图片转换

gray_img = cv2.cvtColor(input_image, flag)

用于颜色空间转换。input_image为需要转换的图片,flag为转换的类型,返回值为颜色空间转换后的图片矩阵。flag对应:
cv2.COLOR_BGR2GRAY BGR -> Gray
cv2.COLOR_BGR2RGB BGR -> RGB
cv2.COLOR_BGR2HSV BGR -> HSV
可以了解一下该函数和cv2.imread()的区别

python+openCV (入门级)车道线检测 学习笔记

3.边缘检测

edge_img = cv2.Canny(gray_img,canny_threshold1,canny_threshold2)

imag为所操作的图片,threshold1为下阈值,threshold2为上阈值,返回值为边缘图。

python+openCV (入门级)车道线检测 学习笔记

四、ROI and mask

利用数组选取ROI(region of interest,感性趣的区域,然后与原图进行布尔运算(与运算)。
python+openCV (入门级)车道线检测 学习笔记

poly_pts = numpy.array([[[0,368],[300,210],[340,210],[640,368]]])

四个数组创建后保存在变量poly_pts中。

mask = np.zeros_like(gray_img)

构建一个与gray_img同维度的数组,并初始化所有变量为零。

cv2.fillPoly(mask, pts, color)

绘制多边形函数。mask为绘制对像,pts为绘制范围,color为绘制颜色。

img_mask = cv2.bitwise_and(gray_img, mask)

与运算

python+openCV (入门级)车道线检测 学习笔记

五、霍夫变换

得到一系列的直线

lines = cv2.HoughLinesP(edge_img,  1, np.pi / 180, 15, minLineLength=40, maxLineGap=20)

edge_img: 要检测的图片矩阵
参数2: 距离r的精度,值越大,考虑越多的线
参数3: 距离theta的精度,值越大,考虑越多的线
参数4: 累加数阈值,值越小,考虑越多的线
minLineLength: 最短长度阈值,短于这个长度的线会被排除
maxLineGap:同一直线两点之间的最大距离
返回值::
[np.array([[x_1,y_1, x_2, y_2]]),
np.array([[x_1, y_1, x_2, y_2]]),
…,
np.array([[x_1, y_1, x_2, y_2]])]

六、离群值过滤

循环查找超出设定范围的斜率,并去除。

idx = np.argmax(diff)

当diff中存放的是一维时,找到diff中最大的数值,并返回该值所在位置。

示例:
one_dim_array = np.array([1, 4, 5, 3, 7, 2, 6])
print(np.argmax(one_dim_array))

打印结果为	4
lines.pop(idx)

从列表lines中把第idx数去除

七、最小二乘法拟合

获得左车道线和右车道线的理想直线

x_coords = np.ravel([[line[0][0], line[0][2]] for line in lines])

将多维数组降为一维
还未想明白转换关系,下次一定

poly = np.polyfit(x, y, deg)

x, y为各个点的横纵坐标,deg为拟合曲线的次数

y_e = np.polyval(poly, x)

拟合曲线之后,x在曲线上对应的y值

八、车道线标注

cv2.line(img, tuple(line[0]), tuple(line[1]), color,thickness)

在图片上画线,img为所标注的目标图片,ine[0]为起点坐标,line[1]为终点坐标,thickness为线宽。
注意两个坐标需要为tuple元组格式,即tuple(line[0])

python+openCV (入门级)车道线检测 学习笔记

九、视频读写

1.打开视频

capture = cv2.VideoCapture('video.mp4')

如果为cv2.VideoCapture(0),表示打开笔记本的内置摄像头。

2.按帧读取视频

ret, frame = capture.read()

其中ret是布尔值,如果读取帧是正确的则返回True,如果文件读取到结尾,它的返回值就为False。
frame就是每一帧的图像,是个三维矩阵。

3.视频编码格式设置

fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')

fourcc意为四字符代码(Four-Character Codes),顾名思义,该编码由四个字符组成,下面是VideoWriter_fourcc对象一些常用的参数,注意:字符顺序不能弄混
cv2.VideoWriter_fourcc(‘I’, ‘4’, ‘2’, ‘0’),该参数是YUV编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc(‘P’, ‘I’, ‘M’, ‘I’),该参数是MPEG-1编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc(‘X’, ‘V’, ‘I’, ‘D’),该参数是MPEG-4编码类型,文件名后缀为.avi
cv2.VideoWriter_fourcc(‘T’, ‘H’, ‘E’, ‘O’),该参数是Ogg Vorbis,文件名后缀为.ogv
cv2.VideoWriter_fourcc(‘F’, ‘L’, ‘V’, ‘1’),该参数是Flash视频,文件名后缀为.flv

4.写视频参数设置

outfile = cv2.VideoWriter(filename, fourcc, 25, (1280,368))

filename为写入视频的文件名,fourcc为视频编码格式cv2.VideoWriter_fourcc()的返回值,25为帧率,(1280,368)为视频大小。

ret, frame = capture.read() 

第一个参数ret 为布尔值即True 或者False,代表有没有读取到图片,第二个参数frame表示截取到一帧的图片

output = np.concatenate((origin, frame), axis=1)

能够一次完成多个数组的拼接
不写axis参数的话,默认为按列拼接;若axis = 1的话,即为按行拼接;
axis参数意义没搞太明白,下次一定

python+openCV (入门级)车道线检测 学习笔记

十、其他

程序存在小bug但不影响检测视频生成,如果哪位大佬知道bug怎么解决记得踢我一脚。
cv2.imshow()总是卡住无响应,无法自己关闭窗口,使用cv2.destroyAllWindows()也还是卡住;
而且报告错误:

error: OpenCV(4.5.5) D:\a\opencv-python\opencv-python\opencv\modules\imgproc\src\smooth.dispatch.cpp:617: error: (-215:Assertion failed) !_src.empty() in function 'cv::GaussianBlur'
> 卡住的问题有人说是openCV对一部分硬件的适配不好,我比较在赞成这种观点。 报错  cv2.error  error:
> (-215:Assertion failed) dst.data == (uchar*)dst_ptr in function
> 'cvShowImage'
> 
> 同样的代码,我发现在公司电脑1060上,cv2.imshow()就可以显示,但在自己2080ti上就总是报错如上。于是锁定在cv2版本问题,果然卸掉最新的4.0版本,换上3.4.4.19就好了。
> 
> 可能是4.0版本与2080ti的卡还不兼容。
> 来源:https://blog.csdn.net/qq_39938666/article/details/88179966

报错的问题目前未解决,也修改不掉。

总结

完全实现对视频形式的单车道直线行驶时对车道线检测和标注。

附视频检测完整程序

import cv2
import numpy as np

#高斯滤波+canny边缘检测
def get_edge_img(color_img, gaussian_ksize=5, gaussian_sigmax=1,
                 canny_threshold1=50, canny_threshold2=100):
    #param intoduction
    #color_img 输入图片    gaussian_ksize 高斯核大小
    #gaussian_sigmax X方向上的高斯核标准偏差
    gaussian = cv2.GaussianBlur(color_img, (gaussian_ksize, gaussian_ksize),
                                gaussian_sigmax)
    gray_img = cv2.cvtColor(gaussian,cv2.IMREAD_GRAYSCALE)
    edge_img = cv2.Canny(gray_img,canny_threshold1,canny_threshold2);
    return edge_img

def roi_mask(gray_img):
    poly_pts = np.array([[[0,368],[300,210],[340,210],[640,368]]])
    mask = np.zeros_like(gray_img)
    cv2.fillPoly(mask, pts=poly_pts, color=255)
    img_mask = cv2.bitwise_and(gray_img, mask)
    return img_mask

def get_lines(edge_img):
    
    #斜率计算
    def calculate_slope(line):
        x_1, y_1, x_2, y_2 = line[0]
        slope = (y_2-y_1)/(x_2-x_1)
        return slope

    #离群值过滤
    def reject_abnormal_lines(lines, threshold):
        slopes = [calculate_slope(line) for line in lines]
        while len(lines)>0:
            mean = np.mean(slopes)
            diff = [abs(s-mean) for s in slopes]
            idx = np.argmax(diff)
            if diff[idx]>threshold:
                slopes.pop(idx)
                lines.pop(idx)
            else:
                break
        return lines
    
    #最小二乘拟合
    def least_squares_fit(lines):
    
        x_coords = np.ravel([[line[0][0], line[0][2]] for line in lines])
        y_coords = np.ravel([[line[0][1], line[0][3]] for line in lines])
        # 2. 进行直线拟合.得到多项式系数
        poly = np.polyfit(x_coords, y_coords, deg=1)
        # 3. 根据多项式系数,计算两个直线上的点,用于唯一确定这条直线
        point_min = (np.min(x_coords), np.polyval(poly, np.min(x_coords)))
        point_max = (np.max(x_coords), np.polyval(poly, np.max(x_coords)))
        return np.array([point_min, point_max],dtype=np.int0)

    lines = cv2.HoughLinesP(edge_img, 1, np.pi/180, 15, minLineLength=40, maxLineGap=20)

    left_lines = [line for line in lines if calculate_slope(line)<0]
    right_lines = [line for line in lines if calculate_slope(line)>0]
    
    left_lines = reject_abnormal_lines(left_lines, threshold=0.2)
    right_lines = reject_abnormal_lines(right_lines, threshold=0.2)

    return least_squares_fit(left_lines),least_squares_fit(right_lines)

def draw_line(img, lines):
    left_line, right_line = lines
    cv2.line(img, tuple(left_line[0]), tuple(left_line[1]), color=(0,255,255),thickness=5)
    cv2.line(img, tuple(right_line[0]), tuple(right_line[1]), color=(0,255,255),thickness=5)

def show_lane(color_img):
    edge_img = get_edge_img(color_img)
    mask_gray_img = roi_mask(edge_img)
    lines = get_lines(mask_gray_img)
    draw_line(color_img, lines)
    return color_img

if __name__ == '__main__':
    capture = cv2.VideoCapture('video.mp4')
    fourcc = cv2.VideoWriter_fourcc('X', 'V', 'I', 'D')
    outfile = cv2.VideoWriter('output.avi', fourcc, 25, (1280,368))

    while True:
        ret, frame = capture.read() 
        origin = np.copy(frame)
        frame = show_lane(frame)
        output = np.concatenate((origin, frame), axis=1)
        outfile.write(output)
        cv2.imshow('video', output)
        cv2.waitKey(10)

分步操作检测图片和检测视频的源码、测试图片和测试视频连接:https://download.csdn.net/download/qq_27839923/75831347文章来源地址https://www.toymoban.com/news/detail-409770.html

到了这里,关于python+openCV (入门级)车道线检测 学习笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度学习毕设项目 深度学习+opencv+python实现车道线检测 - 自动驾驶

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月04日
    浏览(69)
  • 竞赛项目 车位识别车道线检测 - python opencv

    🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分 工作量:3分 创新点:4分 🧿 更多资料, 项目分享: https://gitee.com

    2024年02月13日
    浏览(38)
  • 竞赛保研 车位识别车道线检测 - python opencv

    🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分 工作量:3分 创新点:4分 🧿 更多资料, 项目分享: https://gitee.com

    2024年01月24日
    浏览(46)
  • python基于opencv的车道线检测左右转弯原理详解

    给定一组棋盘图像计算相机校准矩阵和畸变系数。 对原始图像应用失真校正。 使用颜色变换、渐变等来创建阈值二值图像。 应用透视变换来校正二进制图像(“鸟瞰图”)。 检测车道像素并拟合以找到车道边界。 确认检测到的线与现实和之前的线一致,即它们具有相似的

    2024年02月03日
    浏览(42)
  • Python基于OpenCV的视频车道线检测系统[源码&部署教程]

    Python基于OpenCV的视频车道线检测系统[源码&部署教程] 参考该博客方案,其算法思想如下: 使用高斯模糊,去除噪音点(cv2.GaussianBlur) 灰度转换(cv2.cvtColor) 使用sobel算子,计算出每个点的梯度大小和梯度方向 使用非极大值抑制(只有最大的保留),消除边缘检测带来的杂散

    2023年04月08日
    浏览(34)
  • 基于Opencv和Python的车道线检测系统(带UI界面),附演示视频和下载链接

    在自动驾驶中,让汽车保持在车道线内是非常重要的,所以这次我们来说说车道线的检测。我们主要用到的是openCV, numpy, matplotlib几个库。主要包括下面这么几个步骤: 图像加载; 图像预处理:图片灰度化,高斯滤波; Cany边缘检测; 感兴趣区域检测; 霍夫直线检测 ; .直线

    2024年02月04日
    浏览(43)
  • OpenCV—自动驾驶实时道路车道检测(完整代码)

    自动驾驶汽车是人工智能领域最具颠覆性的创新之一。在深度学习算法的推动下,它们不断推动我们的社会向前发展,并在移动领域创造新的机遇。自动驾驶汽车可以去传统汽车可以去的任何地方,并且可以完成经验丰富的人类驾驶员所做的一切。但正确地训练它是非常重要

    2024年02月06日
    浏览(41)
  • OpenCV | 霍夫变换:以车道线检测为例

    霍夫变换 霍夫变换只能灰度图,彩色图会报错 lines = cv2.HoughLinesP(edge_img,1,np.pi/180,15,minLineLength=40,maxLineGap=20) 参数1:要检测的图片矩阵 参数2:距离r的精度,值越大,考虑越多的线 参数3:距离theta的精度,值越大,考虑越多的线 参数4:累加数阈值,值越小,考虑越多的线

    2024年02月04日
    浏览(39)
  • opencv-python学习笔记(十一):HOG+SVM进行行人检测全过程

    本次是接着python-opencv学习笔记(七):滑动窗口与图像金字塔 一起在实验楼所做实验,为啥中间隔了四篇才接着发出来,主因是我发文比较随意(懒),当时这部分并没有总结完,至少我感觉我看的相关资料还不够多,整体理解不深,另外就是项目需求,在做很多其它的东

    2024年02月05日
    浏览(55)
  • 基于OpenCV的车道线实时检测系统(源码&教程)

    随着无人车驾驶技术的飞速发展,对车道线检测技术的实时性也提出了更高的要求.基于OpenCV对车道线进行检测,首先对车载系统采集的图像进行裁剪随、灰度化、然后对灰度化的图像进行滤波,增强图像质量,接着对增强后的图像进行膨胀处理并对其进行边缘检测,最后选取感兴趣

    2024年02月06日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包