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]) 是具有相同数…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
