python进阶——自动驾驶寻找车道
大家好,我是csdn的博主:lqj_本人
这是我的个人博客主页:
lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识
https://blog.csdn.net/lbcyllqj?spm=1011.2415.3001.5343哔哩哔哩欢迎关注:小淼前端
小淼前端的个人空间_哔哩哔哩_bilibili
本篇文章主要讲述python的人工智能视觉模块自动驾驶原理,本篇文章已经成功收录到我们python专栏中:
https://blog.csdn.net/lbcyllqj/category_12089557.html
https://blog.csdn.net/lbcyllqj/category_12089557.html
前言
本程序主要讲述python的AI视觉方面的应用:自动驾驶寻找车道。
推荐博客好文章
(上过csdn热榜top5的优质好文!)
1.若不知道怎么安装opencv或者使用的请看我的这篇文章(曾上过csdn综合热榜的top1):
python进阶——人工智能视觉识别_lqj_本人的博客-CSDN博客
2.基于opencv的人工智能视觉实现的目标实时跟踪功能(曾上过csdn综合热榜的top5):
python进阶——人工智能实时目标跟踪_lqj_本人的博客-CSDN博客
3.基于PaddlenHub模块以及playsound模块实现口罩检测并实时语音报警(曾上过csdn综合热榜的top1):
python进阶——AI视觉实现口罩检测实时语音报警系统_lqj_本人的博客-CSDN博客
项目前须知
1.opencv的图像灰度转化方法
gray = cv2.cvtColor("图像", cv2.COLOR_RGB2GRAY)
2.opencv检测图像边缘
高斯模糊图像
cv2.GaussianBlur(gray, (5, 5), 0)
获取精明图像
canny = cv2.Canny(blur, 50, 150)
3.matplotlib绘制图像库的使用
项目详情
我们先拿到实时摄像的某一帧的图像
导入库
import cv2
import numpy as np
import matplotlib.pyplot as plt
边缘检测
进行图像的灰度转化以及图像的边缘检测
def canny(image):"""1.图像的灰度转化"""#把某一帧的图片转换成灰度图像gray = cv2.cvtColor(lane_image, cv2.COLOR_RGB2GRAY)"""2.检测图像边缘"""#高斯模糊图像blur = cv2.GaussianBlur(gray, (5, 5), 0)#获取精明的图片canny = cv2.Canny(blur, 50, 150)return canny
image = cv2.imread('1.jpg')
lane_image = np.copy(image)
canny = canny(lane_image)
plt.imshow(canny)
plt.show()
得到绘图结果

因为中国的车道时沿右边行驶的,所以我们可以在绘图的图像中清楚的看见X轴与Y轴的数码,由X轴的(400,0)位置到X轴的大约(1100,0)位置是右车道的宽度,然后我们再来看Y轴的数码,大约在150的位置是我们可视范围内的右车道的尽头点,又因为(400,0)到(1100,0)的距离为700px,所以我们可以得到可视范围内的右车道的尽头点为(700,150)。
根据上述位置的计算,我们可以得出一个右车道中的三角形
def region_of_interest(image):height = image.shape[0]polygons = np.array([[(400,height),(1100,height),(700,150)]])mask = np.zeros_like(image)cv2.fillPoly(mask,polygons,255)return maskimage = cv2.imread('1.jpg')
lane_image = np.copy(image)
canny = canny(lane_image)
cv2.imshow('result',region_of_interest(canny))
cv2.waitKey(0)
得出检测三角形

生成蒙版
将检测到的图像由255(白色)表示,周围区域用0(黑色表示)

有时候三角形不是正好与我们看到的进到点到左右两侧点的形状正好相似,所以我们需要自己微调一下
polygons = np.array([[(400,height),(1200,height),(800,200)]])
然后,我们可以对我们的图像进行右车道三角形的裁剪
masked_image = cv2.bitwise_and(image,mask)
cropped_image = region_of_interest(canny)
cv2.imshow('result',cropped_image)
边缘检测与蒙版产生的效果
裁剪显示图像

定义车道起始点位置
def make_coordinates(image,line_parameters):slope,intercept = line_parametersprint(image.shape)y1 = image.shape[0]y2 = int(y1*(3/5))x1 = int((y1 - intercept)/slope)x2 = int((y2 - intercept)/slope)return np.array([x1,y1,x2,y2])
霍夫变换的直线检测
用到的是Opencv封装好的函数cv.HoughLinesP函数,使用到的参数如下:
image:输入图像,通常为canny边缘检测处理后的图像
rho:线段以像素为单位的距离精度
theta:像素以弧度为单位的角度精度(np.pi/180较为合适)
threshold:霍夫平面累加的阈值
minLineLength:线段最小长度(像素级)
maxLineGap:最大允许断裂长度
lines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5)
绘制车道
def display_lines(image,lines):line_image = np.zeros_like(image)if lines is not None:for line in lines:# print(line)x1,y1,x2,y2 = line.reshape(4)cv2.line(line_image,(x1,y1),(x2,y2),(255,100,10),10)return line_image
效果图像

图像与绘制车道融合

视频流中位置检测
def average_slope_intercept(image,lines):left_fit = []right_fit = []if lines is None:return Nonefor 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)print(left_fit_average,'左')print(right_fit_average,'右')left_line = make_coordinates(image,left_fit_average)right_line = make_coordinates(image,right_fit_average)return np.array([left_line,right_line])

导入视频流做最后处理
cap = cv2.VideoCapture('3.mp4')# try:
while cap.isOpened():_,frame = cap.read()canny_image = canny(frame)cropped_image = region_of_interest(canny_image)lines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5)averaged_lines = average_slope_intercept(frame, lines)line_image = display_lines(frame, averaged_lines)combo_image = cv2.addWeighted(frame, 0.8, line_image, 1, 1)# cv2.resizeWindow("result", 1080, 960);cv2.imshow('result', line_image)cv2.waitKey(10)
完整代码
import cv2
import numpy as np
import matplotlib.pyplot as pltdef make_coordinates(image,line_parameters):slope,intercept = line_parametersprint(image.shape)y1 = image.shape[0]y2 = int(y1*(3/5))x1 = int((y1 - intercept)/slope)x2 = int((y2 - intercept)/slope)return np.array([x1,y1,x2,y2])def average_slope_intercept(image,lines):left_fit = []right_fit = []if lines is None:return Nonefor 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)print(left_fit_average,'左')print(right_fit_average,'右')left_line = make_coordinates(image,left_fit_average)right_line = make_coordinates(image,right_fit_average)return np.array([left_line,right_line])def canny(image):"""1.图像的灰度转化"""#把某一帧的图片转换成灰度图像gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)"""2.检测图像边缘"""#高斯模糊图像blur = cv2.GaussianBlur(gray, (5, 5), 0)#获取精明的图片canny = cv2.Canny(blur, 50, 150)return canny
#每一行都是一个二维数组,包含我们的线坐标,形式为[[x1,yl,x2,y2]]。这些坐标指定了线条的参数,以及线条相对与图像空间位置,确保他们被放置在正确的位置
def display_lines(image,lines):line_image = np.zeros_like(image)if lines is not None:for line in lines:# print(line)x1,y1,x2,y2 = line.reshape(4)cv2.line(line_image,(x1,y1),(x2,y2),(255,100,10),10)return line_imagedef region_of_interest(image):height = image.shape[0]polygons = np.array([[(300,height),(650,height),(500,150)]])mask = np.zeros_like(image)cv2.fillPoly(mask,polygons,255)masked_image = cv2.bitwise_and(image,mask)return masked_image# image = cv2.imread('1.png')
# lane_image = np.copy(image)
# canny_image = canny(lane_image)
# cropped_image = region_of_interest(canny_image)
# lines = cv2.HoughLinesP(cropped_image,2,np.pi/180,100,np.array([]),minLineLength=40,maxLineGap=5)
# averaged_lines = average_slope_intercept(lane_image,lines)
# line_image = display_lines(lane_image,averaged_lines)
# combo_image = cv2.addWeighted(lane_image,0.8,line_image,1,1)
# cv2.imshow('result',combo_image)
# cv2.waitKey(0)cap = cv2.VideoCapture('3.mp4')# try:
while cap.isOpened():_,frame = cap.read()canny_image = canny(frame)cropped_image = region_of_interest(canny_image)lines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5)averaged_lines = average_slope_intercept(frame, lines)line_image = display_lines(frame, averaged_lines)combo_image = cv2.addWeighted(frame, 0.8, line_image, 1, 1)# cv2.resizeWindow("result", 1080, 960);cv2.imshow('result', combo_image)cv2.waitKey(10)
用前须知
根据自己的需要适当微调参数:
def region_of_interest(image):height = image.shape[0]polygons = np.array([[(300,height),(650,height),(500,150)]])mask = np.zeros_like(image)cv2.fillPoly(mask,polygons,255)masked_image = cv2.bitwise_and(image,mask)return masked_image
效果显示

相关文章:
python进阶——自动驾驶寻找车道
大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页: lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…...
男,26岁,做了一年多的自动化测试,最近在纠结要不要转行,求指点。?
最近一个粉丝在后台问我,啊大佬我现在26了,做了做了一年多的自动化测试,最近在纠结要不要转行,求指点。首选做IT这条路,就是很普通的技术蓝领。对于大部分来说干一辈子问题不大,但是发不了什么财。如果你在…...
源码级别的讲解JAVA 中的CAS
没有CAS之前实现线程安全 多线程环境不使用原子类保证线程安全(基本数据类型) public class T3 {volatile int number 0;//读取public int getNumber(){return number;}//写入加锁保证原子性public synchronized void setNumber(){number;} }多线程环…...
JUC锁与AQS技术【我的Android开发技术】
JUC锁与AQS技术【我的Android开发技术】 AQS原理 AQS就是一个同步器,要做的事情就相当于一个锁,所以就会有两个动作:一个是获取,一个是释放。获取释放的时候该有一个东西来记住他是被用还是没被用,这个东西就是一个状…...
【问题代码】顺序点的深入理解(汇编剖析+手画图解)
这好像是一个哲学问题。 目录 前言 一、顺序点是什么? 二、发生有关顺序点的问题代码 vs中: gcc中: 三、细读汇编 1.vs汇编如下(示例): 2.gcc汇编如下(示例): 四…...
BinaryAI全新代码匹配模型BAI-2.0上线,“大模型”时代的安全实践
导语BinaryAI(https://www.binaryai.net)科恩实验室在2021年8月首次发布二进制安全智能分析平台—BinaryAI,BinaryAI可精准高效识别二进制文件的第三方组件及其版本号,旨在推动SCA(Software Composition Analysis&…...
nvidia设置wifi和接口
tx-nx设置wifi和接口前言基础知识点1.创建和删除一个wifi连接2. 启动连接和关闭连接代码和调试1. 代码展示2. 调试写到最后前言 针对嵌入式开发,有时候通过QT或PAD跨网络对设备设置WIFI,在此记录下,方便后续的查阅。 基础知识点 1.创建和删…...
PostgreSQL 变化数据捕捉(CDC)
PostgreSQL 变化数据捕捉(CDC)基于CDC(变更数据捕捉)的增量数据集成总体步骤:1.捕获源数据库中的更改数据2.将变更的数据转换为您的消费者可以接受的格式3.将数据发布到消费者或目标数据库PostgreSQL支持触发器&#x…...
Spring 事务【隔离级别与传播机制】
Spring 事务【隔离级别与传播机制】🍎一.事务隔离级别🍒1.1 事务特性回顾🍒1.2 事务的隔离级别(5种)🍒1.3 事务隔离级别的设置🍎二.Spring 事务传播机制🍒2.1 Spring 事务传播机制的作用🍒2.2 事…...
HTTP和HTTPS协议
HTTP协议 HTTP协议是一种应用层的协议,全称为超文本传输协议。 URL URL值统一资源定位标志,也就是俗称的网址。 协议方案名 http://表示的就是协议方案名,常用的协议有HTTP协议、HTTPS协议、FTP协议等。HTTPS协议是以HTTP协议为基础&#…...
day3——有关java运算符的笔记
今天主要学习的内容有java的运算符 赋值运算符算数运算符关系运算符逻辑运算符位运算符(专门写一篇笔记)条件运算符运算符的优先级流程控制 赋值运算符 赋值运算符()主要用于给变量赋值,可以跟算数运算符相结合&…...
Git多人协同远程开发
1. 李四(项目负责人)操作步骤 在github中创建远程版本库testgit将基础代码上传⾄testgit远程库远程库中基于main分⽀创建dev分⽀将 githubleaflife/testgit 共享给组员李四继续在基础代码上添加⾃⼰负责的模块内容 2. 张三、王五(组员&…...
Chapter4:机器人仿真
ROS1{\rm ROS1}ROS1的基础及应用,基于古月的课,各位可以去看,基于hawkbot{\rm hawkbot}hawkbot机器人进行实际操作。 ROS{\rm ROS}ROS版本:ROS1{\rm ROS1}ROS1的Melodic{\rm Melodic}Melodic;实际机器人:Ha…...
python(14)--集合
前言 本篇文章学习的是 python 中集合的基础知识。 集合元素的内容是不可变的,常见的元素有整数、浮点数、字符串、元组等。至于可变内容列表、字典、集合等不可以是集合元素。虽然集合不可以是集合的元素,但是集合本身是可变的,可以去增加或…...
【Spark分布式内存计算框架——Spark Core】4. RDD函数(中)Transformation函数、Action函数
3.2 Transformation函数 在Spark中Transformation操作表示将一个RDD通过一系列操作变为另一个RDD的过程,这个操作可能是简单的加减操作,也可能是某个函数或某一系列函数。值得注意的是Transformation操作并不会触发真正的计算,只会建立RDD间…...
Mysql 数据类型
1、数值数据类型 1.1 整数类型(精确值) INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT MySQL支持SQL标准的整数类型INTEGER (或INT)和SMALLINT。作为标准的扩展,MySQL还支持整数类型TINYINT、MEDIUMINT和BIGINT。下表显示了每种整数类型所需的存储和范围。…...
运行Whisper笔记(1)
最近chatGPT很火,就去逛了一下openai的github项目。发现了这个项目。 这个项目可以识别视频中的音频,转换出字幕。 带着一颗好奇的心就尝试自己去部署玩一玩 跟着这篇文章一步步来进行安装,并且跟着这篇文章解决途中遇到的问题。 途中还会遇…...
2023年最强大的12款数据可视化工具,值得收藏
做数据分析也有年头了,好的坏的工具都用过,推荐几个觉得很好用的,避坑必看! PS:一般比较成熟的公司里,数据分析工具不只是满足业务分析和报表制作,像我现在给我们公司选型BI工具,是做…...
LeetCode刷题系列 -- 523. 连续的子数组和
给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:子数组大小 至少为 2 ,且子数组元素总和为 k 的倍数。如果存在,返回 true ;否则,返回 false 。如果存…...
LeetCode刷题系列 -- 525. 连续数组
给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。示例 1:输入: nums [0,1]输出: 2说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。示例 2:输入: nums [0,1,0]输出: 2说明: [0, 1] (或 [1, 0]) 是具有相同数…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
