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

9.3.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-车道线检测

目录

    • 前言
    • 1. 车道线检测
    • 总结

前言

杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。

本次课程学习 tensorRT 高级-自动驾驶案例项目self-driving-车道线检测

课程大纲可看下面的思维导图

在这里插入图片描述

1. 车道线检测

这节我们学习车道线检测模型的分析,我们的目的是找到车道线检测的 onnx,分析其 onnx 的大致使用逻辑,然后写出最简洁版本的 predict.py,大体可以分为以下三步:

1. 打开车道线检测的 onnx,查看其输入与输出

2. 查看代码,找到 onnx 的预处理,分析得到预处理的逻辑

3. 针对获得的信息,编写 predict.py,尝试写出来

值得注意的是,在这个案例中,由于后处理过于复杂,因此考虑合并到 onnx 中,使得模型尽量的简单

在开始之前,我们先对车道线检测任务进行一个简单的分析

对于常规的框回归任务,例如求取下图中硬币在图像中的位置,cx,cy,w,h,其通常直接输出 4 个标量值进行回归

在这里插入图片描述

图1 常规框回归

目前最新的,大家更倾向于使用位置概率点乘其位置作为输出值,属于加权和,如下图所示

在这里插入图片描述

图2 位置概率

这种方法将回归的坐标以 n 个位置概率进行表示,例如对于 cx 的回归,表示为 5 个概率,可以认为对图像划分为 5 块,然后 cx 更有可能落到哪一块上进行表述。例如落在图像中心上时,其中心概率最高。有一种 attention 的味道。像 NanoDet、Alphapose 的后处理都与位置概率类似

车道线检测图如下所示:

在这里插入图片描述

对于车道线检测任务,我们是有一些先验知识的,比如车道线一样是位于图像下半部分,图像上半部分是天空无需考虑。另外检测的车道线通常是驾驶区域的 2 条加上两侧总共 4 条车道线;还有车道线点坐标的 y 值是知道的,我们会将图像按行划分为 N 个网格,每条车道线输出的点数就是 N,因此每个点的 y 我们是已知的;唯一不确定的是每个点的 x 坐标,这是需要模型学习出来的

那模型该如何回归这些点的 x 坐标呢?其实是通过位置概率来实现的,我们将图像按列分成 M 个网格,网络需要输出的总数量是 4xNxM,另外我们还要在列方向上增加一个维度,用来判断该点是否存在,因此网络的最终输出就是 4xNx(M+1)

我们来观察下车道线的 onnx 模型,如下图所示:

在这里插入图片描述

图3 onnx模型

可以看到 onnx 模型的输入是 1x3x288x800,其中输入图像的高度是 288,宽度是 800,输出是 1x201x18x4,其中 4 代表 4 条车道线,18 代表将图像下半部分划分为 18 行(即 N=18),201 代表将图像下半部分划分为 201 列(即 M=200)

我们分析总结可以得到如下信息:

1. 输入是:1x3x288x800

2. 输出是:1x201x18x4

3. 对于车道线检测任务而言有一些定义或者说是先验

  • 只需要识别 4 条线
  • 对于车道线基本是在地面上的,因此 y 方向可以从图像中心开始,也就是 anchor 起始坐标是图像中心到图像底部
  • 对于车道线的检测,因为线是连续的,因此这里可以转变为离散的点的检测,对于一根线可以设计为 18 个点来描述
  • 因此回归一个点,其 y 坐标已知,x 坐标需要回归出来
  • 对于 x 的回归,采用了位置概率来表示,划分为 200 个网格表示其坐标
  • 对于车道线的点是否存在这个问题,采用第 201 个概率表示,若这个点不存在,则 201 个点位置的值是最大的

我们再分析项目中的 image_processor/lane_engine.cpp 代码可以得出具体的预处理和后处理所做的工作:(详细分析请参照视频)

预处理部分

  • 图像的预处理直接是 image / 255.0
  • 图像需要从 BGR 到 RGB
  • 图像直接 resize 到 288x800

后处理部分

  • 对 0-200 维度进行 softmax,此时得到的是位置概率
  • 对位置概率和位置索引点乘相加,得到 location,此时 location 是 18x4
  • 对原始输出的最大值进行判断,决定该点是否存在
  • 最后通过过滤得到 4 根线的坐标

我们可以简单的写个 demo 来验证下,代码如下:

import onnxruntime
import cv2
import numpy as np
import matplotlib.pyplot as plt
import scipysession = onnxruntime.InferenceSession("workspace/ultra_fast_lane_detection_culane_288x800.onnx", provider_options=["CPUExecutionProvider"])image = cv2.imread("workspace/imgs/dashcam_00.jpg")
show  = image.copy()
image = cv2.resize(image, (800, 288))
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_tensor = (image / 255.0).astype(np.float32)
image_tensor = image_tensor.transpose(2, 0, 1)[None]prob = session.run(["200"], {"input.1": image_tensor})[0][0]print(prob.shape)out_j = prob
prob = scipy.special.softmax(out_j[:-1, :, :], axis=0)
idx = np.arange(200) + 1
idx = idx.reshape(-1, 1, 1)
loc = np.sum(prob * idx, axis=0)print(loc.shape)# 201 x 18 x 4, 201 维度上找最大值
out_j = np.argmax(out_j, axis=0)
loc[out_j == 200] = 0col_sample = np.linspace(0, 800 - 1, 200)
col_sample_w = col_sample[1] - col_sample[0]
ys = np.array([121, 131, 141, 150, 160, 170, 180, 189, 199, 209, 219, 228, 238, 248, 258, 267, 277, 287])xs = loc * col_sample_w * show.shape[1] / 800
ys = ys * show.shape[0] / 288colors = [(0, 255, 0), (255, 0, 0), (255, 0, 0), (0, 255, 0)]for iline in range(4):for x, y in zip(xs[:, iline], ys):if x == 0:continuecv2.circle(show, (int(x), int(y)), 5, colors[iline], -1, 16)cv2.imwrite("lane.jpg", show)

输出如下图:

在这里插入图片描述

图4 输出

可以看到输出符合我们的预期,输出的车道线检测图如下所示:

在这里插入图片描述

图5 车道线检测效果图

那如果要使用 tensorRT 进行推理,你会发现后处理太复杂了,我们需要考虑将后处理放到 onnx 中,我们可以先导出后处理的 onnx 模型,然后把它添加到我们的 onnx 模型中,如下图所示:

在这里插入图片描述

图6 复杂后处理放onnx

总结

本次课程学习了开源项目中的车道线检测案例,主要是对车道线检测模型的 onnx 进行了简单分析,并通过对项目代码的分析将预处理和后处理部分理清楚,然后通过 onnxruntime 进行了简单验证,随后将复杂的后处理部分塞到 onnx 中方便后续在 tensorRT 上执行推理

相关文章:

9.3.tensorRT高级(4)封装系列-自动驾驶案例项目self-driving-车道线检测

目录 前言1. 车道线检测总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。 本次课程学习 tensorRT 高级-自动驾驶案例项目self-driving-车道…...

django.core.exceptions.AppRegistryNotReady: Apps aren‘t loaded yet.

运行django测试用例报错django.core.exceptions.AppRegistryNotReady: Apps arent loaded yet. 解决:在测试文件上方加上 django.setup() django.setup()是Django框架中的一个函数。它用于在非Django环境下使用Django的各种功能、模型和设置。 在常规的Django应用…...

【C#】C#调用进程打开一个exe程序

文章目录 一、过程二、效果总结 一、过程 新建WinForm程序,并写入代码,明确要调用的程序的绝对路径(或相对路径)下的exe文件。 调用代码: 这里我调用的另一个程序的路径是: F:\WindowsFormsApplication2…...

宝塔面板定时监控和重启MySQL数据库(计划任务)

往期教程 如果还有不了解宝塔面板怎么使用的小伙伴,可以看下我总结的系列教程,保证从新手变老鸟: 【建站流程科普】 个人和企业搭建网站基本流程及六个主要步骤常见的VPS主机运维面板汇总—网站运维面板云服务器,VPS&#xff0…...

Beats:安装及配置 Metricbeat (二)- 8.x

这篇文章是继文章 “Beats:安装及配置 Metricbeat (一)- 8.x” 的续篇。你可以先阅读之前的那篇文章再继续阅读这篇文章。我们在这篇文章中继续之前的探讨。 使用 fingerprint 来代替证书 在实际的使用中,我们需要从 Elasticsear…...

Redis之哨兵模式解读

目录 基本介绍 单哨兵模式 多哨兵模式 哨兵的本质 配置哨兵模式 故障恢复原理 哨兵监控工作流程 哨兵模式缺点 基本介绍 当主服务器宕机后,需要手动把一台从服务器切换为主服务器,这就需要人工干预,费事费力,还会造成一段时间内服务不可用。这不是一种推荐的方式,更多…...

题目:2644.找出可整除性得分最大的整数

​​题目来源: leetcode题目,网址:2644. 找出可整除性得分最大的整数 - 力扣(LeetCode) 解题思路: 遍历计算即可。 解题代码: class Solution {public int maxDivScore(int[] nums, int[] di…...

报错:axios 发送的接口请求 404

axios 发送的接口请求 404 一、问题二、分析 一、问题 二、分析 axios 发送的接口请求 404,根本没有把接口信息发送到后端,这个时候你可以查看检查一下自己的接口名字,或让后端配合换一个接口名字再发送一次接口请求...

三年前端还不会配置Nginx?刷完这篇就够了

什么是Nginx Nginx是一个开源的高性能HTTP和反向代理服务器。它可以用于处理静态资源、负载均衡、反向代理和缓存等任务。Nginx被广泛用于构建高可用性、高性能的Web应用程序和网站。它具有低内存消耗、高并发能力和良好的稳定性,因此在互联网领域非常受欢迎。 为…...

blender 场景灯光基础设置

在 blender 中,打光分为两个部分,一个是世界光,一个是场景光; 世界光: 世界光:在 Blender 中,世界光指的是用于设置场景整体照明的环境光。它可以通过调整颜色、强度、阴影等参数来影响场景的…...

如何查看 SQLyog 中数据库连接信息中的密码

SQLyog 数据库连接信息中的密码无法选择明文展示,也无法复制 可以将数据库连接信息导出到文本查看明文密码 工具--》导入/导出连接详情:...

【SpringSecurity】八、集成图片验证码

文章目录 1、生成图片验证码2、创建验证码过滤器3、将过滤器加入SpringSecurity过滤链4、修改登录页 SpringSecurity是通过过滤器链来完成的,接下来的验证码,可以尝试创建一个过滤器放到Security的过滤器链中,在自定义的过滤器中比较验证码。…...

【本地代码问题】启动程序,报错:java.lang.IllegalArgumentException: No selectors

启动程序的时候报错了 问题怎么出现的解决方式,注释掉jetty的内容,回归tomcat的使用 问题怎么出现的 我本地启动程序的时候报错了:报的是这个错误,可能和容器的选择有关吧 解决方式,注释掉jetty的内容,回…...

手写RPC框架--4.服务注册

RPC框架-Gitee代码(麻烦点个Starred, 支持一下吧) RPC框架-GitHub代码(麻烦点个Starred, 支持一下吧) 服务注册 服务注册a.添加服务节点和主机节点b.抽象注册中心c.本地服务列表 服务注册 a.添加服务节点和主机节点 主要完成服务注册和发现的功能,其具体流程如下&…...

oracle 解锁表

操作的前提 用 sys 用户 以 SYSDBA 角色登录 第一种解锁方式 1.查询被锁的表 select object_name,machine,s.sid,s.serial# from v$locked_object l,dba_objects o ,v$session s where l.object_id  o.object_id and l.session_ids.sid;2.查询那个session引起表被锁 sele…...

使用Dbeaver连接GaussDB

1.下载DBeaver,官网地址 2.安装软件,打开软件,点击数据库->驱动管理器,具体操作如下图: 3、选择新建后进行参数设置,如下图: 具体参数如下图 驱动名称: GS #随便定义 驱动类型&#…...

WSL使用技巧 / 虚拟机对比

WSL使用技巧 / 虚拟机对比 前言虚拟机比较VMware使用技巧WSL使用技巧官方文档工具安装WSL基本命令运行命令关闭卸载磁盘管理导入导出指定安装路径 前言 本文介绍了VMware和WSL的区别,并详细介绍了WSL的使用方法和技巧。 虚拟机比较 VMware 比较灵活,拥…...

vuex_cart案例

json-server使用 在目录下新建db文件夹>里面新建index.json index.json {"cart": [{"id": 100001,"name": "低帮城市休闲户外鞋天然牛皮COOLMAX纤维","price": 128,"count": 6,"thumb": "http…...

Linux系统的安装

文章目录 1 Linux介绍1.1 Linux是什么1.2 Linux的特点1.3 Linux的应用1.4 Linux的发行版本1.5 Linux的Shell 2 Linux安装2.1 安装方式2.2 什么是VMware2.3 VMware主要功能2.4 什么是CentOS2.5 VMware与CentOS与Linux的关系2.6 VMware安装CentOS的步骤 1 Linux介绍 1.1 Linux是…...

微服务设计和高并发实践

文章目录 1、微服务的设计原则1.1、服务拆分方法1.2、微服务的设计原则1.3、微服务架构 2、高并发系统的一些优化经验2.1、提高性能2.1.1、数据库优化2.1.2、使用缓存2.1.3、服务调用优化2.1.4、动静分离2.1.5、数据库读写分离 2.2、服务高可用2.2.1、限流和服务降级2.2.2、隔离…...

2023年高教社杯数学建模思路 - 案例:粒子群算法

文章目录 1 什么是粒子群算法?2 举个例子3 还是一个例子算法流程算法实现建模资料 # 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法? 粒子群算法(Pa…...

Tomcat 集群介绍

一.Tomcat 集群介绍 在实际生产环境中,单台 Tomcat 服务器的负载能力或者说并发能力在四五百左右。大 部分情况下随着业务增长,访问量的增加(并发量不止四五百),单台 Tomcat 服务器是 无法承受的。这时就需要将多台 Tomcat 服务器组织起来&a…...

Windows右键添加用 IDEA 打开

1.安装IDEA时 安装时会有个选项来添加,如下: 勾选即可 2.修改注册表 安装时未勾选,可以把下面代码中程序路径改为自己的,保存为对应的 idea.reg文件,双击即可 Windows Registry Editor Version 5.00[HKEY_CLASSES…...

Golang 中return和defer执行先后顺序

先给出最终结论: 执行return语句 -> 执行defer函数 -> 函数返回 这里可能会有一个疑问, 执行return语句和函数返回难道不是一回事? Golang语言中函数的return不是原子操作,而是分为了两步: 返回值赋值真正函数返回 Gol…...

业务数据模拟/采集

业务数据模拟/采集 2.2 业务数据模拟 2.2.1 连接MySQL 通过MySQL可视化客户端连接数据库。2.2.2 建表语句 1)通过SQLyog创建数据库2)设置数据库名称为gmall,编码为utf-8,排序规则为utf8_general_ci3)导入数据库结构脚本…...

qt day 5

实现局域网的网络聊天室功能 1>服务器代码 --------------------------------------------------------------- widget.h --------------------------------------------------------------- #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMes…...

Java设计模式之适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式&#xff0c;它结合了两个独立接口的功能。 这种模式涉及到一个单一的类&#xff0c;该类负责加入独立的或不兼容的接口功能。举个真实的例子&#xff0…...

每天一个工业通信协议(3)2023.8.29 (DAP接口)

文章目录 参考文献1.DAP接口介绍2.DAP接口的2/3pin3.一种DAP接口方案应用的说明,通过两步初始化把JTAG接口变成DAP接口使用4.DAP接口的协议4.1 DAP电报的分类(只用JTAG类电报)4.2 电报格式4.3 DAP有限状态机参考文献 李婧. DAP模块验证组件系统级开发和实现[D]. 陕西:西安电…...

如何将Word转成PDF?试一下这个转换方法

Word转成PDF是现代办公中常见的需求&#xff0c;它可以确保文件的格式和内容在不同平台上保持一致&#xff0c;并且更加方便共享和打印。在这个数字化时代&#xff0c;我们经常需要将Word文档转换为PDF格式&#xff0c;无论是个人用户还是商务用户都会遇到这样的需求。那么如何…...

成都睿趣科技:现在开一家抖音小店还来得及吗

随着社交媒体的迅猛发展&#xff0c;抖音已经成为了一个全球范围内广受欢迎的社交平台。在这个短视频应用上&#xff0c;人们分享着各种各样的内容&#xff0c;从搞笑段子到美食教程&#xff0c;再到时尚搭配和手工艺品制作。随着用户数量的不断增长&#xff0c;很多人都在思考…...