python进阶——自动驾驶寻找车道

news2024/11/29 0:47:16

  大家好,我是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 mask

image = 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_parameters
    print(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 None
    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)
    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 plt

def make_coordinates(image,line_parameters):
    slope,intercept = line_parameters
    print(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 None
    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)
    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_image

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

# 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

效果显示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/331300.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式-策略模式详解

1. 背景在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况&#xff0c;例如&#xff0c;出行旅游可以乘坐飞机、乘坐火车、骑自行车或自己开私家车等&#xff0c;超市促销可以釆用打折、送商品、送积分等方法。在软件开发中也常常遇到类似的情况&#xff0c;当实现某…

Java数据结构中栈和队列深度解析

栈和队列使用的范围很广&#xff0c;本篇用来深度解析Java数据结构中的栈和队列的深度解析&#xff0c;栈和队列都能用单向或双向链表来实现哦&#xff0c;希望可以帮助各位&#xff01; 文章目录 目录 一、栈 1.1栈的概念 1.2栈的使用 1.3栈的自定义顺序栈实现 1.4栈的练习题…

本机信息收集

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a; 内网安全 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c;永远…

【JavaEE】Java中复杂的Synchronized关键字

目录 一、synchronized的特性 &#xff08;1&#xff09;互斥 &#xff08;2&#xff09;刷新内存 &#xff08;3&#xff09;可重入 二、synchronized的使用 &#xff08;1&#xff09;修饰普通方法 &#xff08;2&#xff09;修饰静态方法 &#xff08;3&#xff09;修…

计网之初识网络(理解网络传输的基本流程)

文章目录一. 网络发展史二. IP地址和端口号三. 计算机网络分层1. 什么是网络协议2. OSI七层网络模型3. TCP/IP五层网络模型4. 数据在各个层的传输过程5. 网络设备所在分层一. 网络发展史 &#x1f342;独立模式(单机模式) 我们最初的计算机是在单机模式下使用的, 此时的计算机…

遇到“独自开”,开发出属于自己一套专属系统的时代还会远吗?

目录 一、前言 二、介绍 三、详细介绍 四、总结 一、前言 哈喽&#xff0c;大家好&#xff0c;我是追&#xff0c;看到标题独自开时&#xff0c;可能此处会有疑问了。独自开&#xff1f;半山居士王安石的“墙角数枝梅&#xff0c;凌寒独自开”&#xff1f;哈哈&#xff0c;…

北京化工大学2/7寒假集训题解(>1800)

目录 A-Fence B-D again​ C-Cut the Sequence D-Parade E-trade A-Fence #include<algorithm> #include<string.h> #include<stdio.h> #include<queue> using namespace std; struct nob {int v,p;bool operator <(const nob &a)const{retu…

网络协议(四):网络分类、ISP、上网方式、公网私网、NAT

网络协议系列文章 网络协议(一)&#xff1a;基本概念、计算机之间的连接方式 网络协议(二)&#xff1a;MAC地址、IP地址、子网掩码、子网和超网 网络协议(三)&#xff1a;路由器原理及数据包传输过程 网络协议(四)&#xff1a;网络分类、ISP、上网方式、公网私网、NAT 目录…

【沁恒WCH CH32V307V-R1开发板两路ADC读取实验】

【沁恒WCH CH32V307V-R1开发板两路ADC读取实验】1. 前言2. 软件配置2.1 安装MounRiver Studio3. ADC项目测试3.1 打开ADC工程3.2 编译项目4. 下载验证4.1 接线4.2 演示效果5. 小结1. 前言 ADC 模块包含 2 个 12 位的逐次逼近型的模拟数字转换器&#xff0c;最高 14MHz 的输入时…

2022年这5款熟悉的软件退出了历史舞台

在过去的一年里&#xff0c;有很多新产品发布&#xff0c;当然也有很多产品与我们就此别过。这些产品曾陪伴我们的生活&#xff0c;给我们带来欢乐&#xff0c;帮助我们成长。所以本文将盘点一下在2022年和我们告别的产品。1.微软IE浏览器IE浏览器1995年8月16日正式上线&#x…

window 安装debian的Linux系统+一些环境初始化

文章目录一、安装&#xff1a;1、安装WSL22、微软商店搜索debian安装&#xff1a;3、也可以官方安装&#xff1a;二、更改镜像源1、查看debian系统版本&#xff1a;2、修改3、升级三、安装zsh1&#xff1a;检查2、安装zsh3、安装oh-my-zsh4、安装插件5、配置文件~/.zshrc:6、配…

软件工程详细知识点(下)

文章目录七、面向对象的分析设计1、面向对象分析&#xff08;OOA&#xff09;2、面向对象设计&#xff08;OOD&#xff09;八、编码1、程序设计语言九、软件测试十、软件维护十一、软件项目管理RUP&#xff08;统一软件开发过程&#xff09;面向对象编程和面向对象设计的五个基…

【C++STL】双向循环链表与其迭代器的深度剖析及实现(百字短文速通)

1&#xff0c;双向循环链表基本结构的实现&#xff08;不包含需要迭代器的部分&#xff09;先用struct封装链表的节点&#xff0c;这里我们仅需要提供一个构造函数即可&#xff0c;并且构造函数必须提供缺省值&#xff0c;因为会有如下使用场景&#xff1a;new Node();此时需要…

crawler爬虫抓取数据

crawler爬虫实现 学习目标&#xff1a; 了解 crawler爬虫运行流程了解 crawler爬虫模块实现 1. crawler功能 初始化driver输入公司名称,并点击判断是否需要验证如果需要验证&#xff0c;获取验证图片并保存获取打码坐标点击验证图片判断查询结果选择第一条查询结果获取主要信…

电脑自带的录屏软件在哪?图文教学,教你如何快速录屏

很多小伙伴或许都听说过电脑有一款自带的录屏软件&#xff0c;但却不知道这款录屏软件在哪里。电脑自带的录屏软件在哪&#xff1f;其实很简单&#xff0c;如果你的电脑是Win10或者Win11的电脑&#xff0c;那么就可以使用电脑自带的录屏软件&#xff0c;一起跟着小编来看看吧。…

初次认识C++类

目录 前言&#xff1a; 面向过程和面向对象的区别&#xff1a; C语言&#xff1a; C&#xff1a; 类的引入&#xff1a; 类的定义&#xff1a; 类的权限&#xff1a; 类的作用域&#xff1a; 类的实例化&#xff1a; 类的大小计算&#xff1a; 空类或则只…

急速肝了一波ChatGPT,听说阿里面试题都没问题~

目录前言注册步骤&#xff1a;最后总结前言 互联网圈子里面ChatGPT现在实在是太火了&#xff0c;但是你还没用过&#xff1f;我只能说你OUT了&#xff0c;ChatGPT是什么呢&#xff1f; 由人工智能实验室OpenAI发布的对话式大型语言模型ChatGPT引爆中文互联网。它可以与人类轻松…

2022年ts学习记录

以下记录的是&#xff0c;我在学习中的一些学习笔记&#xff0c;这篇笔记是自己学习的学习大杂烩&#xff0c;主要用于记录&#xff0c;方便查找一、TS 是什么 &#xff1f;##1、简介TS&#xff1a;是TypeScript的简称&#xff0c;是一种由微软开发的自由和开源的编程语言。ts …

朗润外盘国际期货:SC原油市场情绪回暖领涨期市

今日值得回溯的三个行情&#xff1a;①SC原油主力合约今日收高4.23%&#xff0c;研报建议仍以震荡行情对待&#xff1f;②沪锡主力合约收涨3.20%&#xff0c;现在做多合适吗&#xff1f;③鸡蛋主力合约收跌1.32%&#xff0c;研报称这只是小幅回调。 【今日期市盘面概况】 整体…

深度学习 Day25——使用Pytorch实现彩色图片识别

深度学习 Day25——使用Pytorch实现彩色图片识别 文章目录深度学习 Day25——使用Pytorch实现彩色图片识别一、前言二、我的环境三、前期工作1、导入依赖项和设置GPU2、下载数据3、加载数据4、数据可视化四、构建CNN网络结构1、函数介绍2、构建CNN并打印模型3、可视化模型结构五…