当前位置: 首页 > news >正文

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.htmlhttps://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进阶——自动驾驶寻找车道

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…...

男,26岁,做了一年多的自动化测试,最近在纠结要不要转行,求指点。?

最近一个粉丝在后台问我&#xff0c;啊大佬我现在26了&#xff0c;做了做了一年多的自动化测试&#xff0c;最近在纠结要不要转行&#xff0c;求指点。首选做IT这条路&#xff0c;就是很普通的技术蓝领。对于大部分来说干一辈子问题不大&#xff0c;但是发不了什么财。如果你在…...

源码级别的讲解JAVA 中的CAS

没有CAS之前实现线程安全 多线程环境不使用原子类保证线程安全&#xff08;基本数据类型&#xff09; 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就是一个同步器&#xff0c;要做的事情就相当于一个锁&#xff0c;所以就会有两个动作&#xff1a;一个是获取&#xff0c;一个是释放。获取释放的时候该有一个东西来记住他是被用还是没被用&#xff0c;这个东西就是一个状…...

【问题代码】顺序点的深入理解(汇编剖析+手画图解)

这好像是一个哲学问题。 目录 前言 一、顺序点是什么&#xff1f; 二、发生有关顺序点的问题代码 vs中&#xff1a; gcc中&#xff1a; 三、细读汇编 1.vs汇编如下&#xff08;示例&#xff09;&#xff1a; 2.gcc汇编如下&#xff08;示例&#xff09;&#xff1a; 四…...

BinaryAI全新代码匹配模型BAI-2.0上线,“大模型”时代的安全实践

导语BinaryAI&#xff08;https://www.binaryai.net&#xff09;科恩实验室在2021年8月首次发布二进制安全智能分析平台—BinaryAI&#xff0c;BinaryAI可精准高效识别二进制文件的第三方组件及其版本号&#xff0c;旨在推动SCA&#xff08;Software Composition Analysis&…...

nvidia设置wifi和接口

tx-nx设置wifi和接口前言基础知识点1.创建和删除一个wifi连接2. 启动连接和关闭连接代码和调试1. 代码展示2. 调试写到最后前言 针对嵌入式开发&#xff0c;有时候通过QT或PAD跨网络对设备设置WIFI&#xff0c;在此记录下&#xff0c;方便后续的查阅。 基础知识点 1.创建和删…...

PostgreSQL 变化数据捕捉(CDC)

PostgreSQL 变化数据捕捉&#xff08;CDC&#xff09;基于CDC&#xff08;变更数据捕捉&#xff09;的增量数据集成总体步骤&#xff1a;1.捕获源数据库中的更改数据2.将变更的数据转换为您的消费者可以接受的格式3.将数据发布到消费者或目标数据库PostgreSQL支持触发器&#x…...

Spring 事务【隔离级别与传播机制】

Spring 事务【隔离级别与传播机制】&#x1f34e;一.事务隔离级别&#x1f352;1.1 事务特性回顾&#x1f352;1.2 事务的隔离级别(5种)&#x1f352;1.3 事务隔离级别的设置&#x1f34e;二.Spring 事务传播机制&#x1f352;2.1 Spring 事务传播机制的作用&#x1f352;2.2 事…...

HTTP和HTTPS协议

HTTP协议 HTTP协议是一种应用层的协议&#xff0c;全称为超文本传输协议。 URL URL值统一资源定位标志&#xff0c;也就是俗称的网址。 协议方案名 http://表示的就是协议方案名&#xff0c;常用的协议有HTTP协议、HTTPS协议、FTP协议等。HTTPS协议是以HTTP协议为基础&#…...

day3——有关java运算符的笔记

今天主要学习的内容有java的运算符 赋值运算符算数运算符关系运算符逻辑运算符位运算符&#xff08;专门写一篇笔记&#xff09;条件运算符运算符的优先级流程控制 赋值运算符 赋值运算符&#xff08;&#xff09;主要用于给变量赋值&#xff0c;可以跟算数运算符相结合&…...

Git多人协同远程开发

1. 李四&#xff08;项目负责人&#xff09;操作步骤 在github中创建远程版本库testgit将基础代码上传⾄testgit远程库远程库中基于main分⽀创建dev分⽀将 githubleaflife/testgit 共享给组员李四继续在基础代码上添加⾃⼰负责的模块内容 2. 张三、王五&#xff08;组员&…...

Chapter4:机器人仿真

ROS1{\rm ROS1}ROS1的基础及应用&#xff0c;基于古月的课&#xff0c;各位可以去看&#xff0c;基于hawkbot{\rm hawkbot}hawkbot机器人进行实际操作。 ROS{\rm ROS}ROS版本&#xff1a;ROS1{\rm ROS1}ROS1的Melodic{\rm Melodic}Melodic&#xff1b;实际机器人&#xff1a;Ha…...

python(14)--集合

前言 本篇文章学习的是 python 中集合的基础知识。 集合元素的内容是不可变的&#xff0c;常见的元素有整数、浮点数、字符串、元组等。至于可变内容列表、字典、集合等不可以是集合元素。虽然集合不可以是集合的元素&#xff0c;但是集合本身是可变的&#xff0c;可以去增加或…...

【Spark分布式内存计算框架——Spark Core】4. RDD函数(中)Transformation函数、Action函数

3.2 Transformation函数 在Spark中Transformation操作表示将一个RDD通过一系列操作变为另一个RDD的过程&#xff0c;这个操作可能是简单的加减操作&#xff0c;也可能是某个函数或某一系列函数。值得注意的是Transformation操作并不会触发真正的计算&#xff0c;只会建立RDD间…...

Mysql 数据类型

1、数值数据类型 1.1 整数类型(精确值) INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT MySQL支持SQL标准的整数类型INTEGER (或INT)和SMALLINT。作为标准的扩展&#xff0c;MySQL还支持整数类型TINYINT、MEDIUMINT和BIGINT。下表显示了每种整数类型所需的存储和范围。…...

运行Whisper笔记(1)

最近chatGPT很火&#xff0c;就去逛了一下openai的github项目。发现了这个项目。 这个项目可以识别视频中的音频&#xff0c;转换出字幕。 带着一颗好奇的心就尝试自己去部署玩一玩 跟着这篇文章一步步来进行安装&#xff0c;并且跟着这篇文章解决途中遇到的问题。 途中还会遇…...

2023年最强大的12款数据可视化工具,值得收藏

做数据分析也有年头了&#xff0c;好的坏的工具都用过&#xff0c;推荐几个觉得很好用的&#xff0c;避坑必看&#xff01; PS&#xff1a;一般比较成熟的公司里&#xff0c;数据分析工具不只是满足业务分析和报表制作&#xff0c;像我现在给我们公司选型BI工具&#xff0c;是做…...

LeetCode刷题系列 -- 523. 连续的子数组和

给你一个整数数组 nums 和一个整数 k &#xff0c;编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组&#xff1a;子数组大小 至少为 2 &#xff0c;且子数组元素总和为 k 的倍数。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。如果存…...

LeetCode刷题系列 -- 525. 连续数组

给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组&#xff0c;并返回该子数组的长度。示例 1:输入: nums [0,1]输出: 2说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。示例 2:输入: nums [0,1,0]输出: 2说明: [0, 1] (或 [1, 0]) 是具有相同数…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...