动手学无人驾驶(7):车道线检测

在这里插入图片描述
最近在研究视觉语义地图,需要进行车道线检测,发现这篇车道线检测论文效果蛮好的 (Ultra Fast Structure-aware Deep Lane Detection)。论文作者在知乎上已经介绍过了:https://zhuanlan.zhihu.com/p/157530787,本文中我简单介绍下论文原理,重点介绍如何使用原作者开源的模型检测自己采集的数据。


1.Method介绍

目前大多数车道线检测算法中都是将车道线检测看作是像素分割问题。但是这会存在两个问题,一是计算速度慢,二是在一些有挑战的场景中(遮挡、夜晚、极端光照条件)由于没有视觉线索很难进行检测。因此在本文中,作者提出了一个按行检测车道线的方法

作者首先将原始图像按照一定像素间隔划分成 hhh 个anchors,同时又将每一个anchor划分为 www 个网格。若图像全局特征用 XXX 表示,车道线数量用 CCC 表示,车道线分类器为 fijf^{ij}fij,则车道线预测概率为:
Pi,j,:=fij(X),s.t. i∈[1,C],j∈[1,h]P_{i, j,:}=f^{i j}(X), \text { s.t. } i \in[1, C], j \in[1, h] Pi,j,:=fij(X), s.t. i[1,C],j[1,h]

概率 Pi,j,:P_{i, j,:}Pi,j,:(w+1)(w+1)(w+1) 维的向量。

为什么本文提出的方法可以快速检测车道线呢?如下图所示,基于像素分割的车道线检测要进行 H×W×(C+1)H \times W \times (C+1)H×W×(C+1) 次分类,而本文提出的方法只需要进行 C×h×(w+1)C \times h \times (w+1)C×h×(w+1) 次分类,由于 h<<H,w<<Wh<<H,w<<Wh<<Hw<<W,因此整体计算量大幅减小。
在这里插入图片描述
同时在本文中作者又提出了两个新的结构损失函数。

  • 由于车道线一般是连续的,所有同一车道线在相邻anchor的预测概率应该是接近的,作者提出了车道线相似损失函数
    Lsim=∑i=1C∑j=1h−1∥Pi,j,:−Pi,j+1,:∥1L_{s i m}=\sum_{i=1}^{C} \sum_{j=1}^{h-1}\left\|P_{i, j,:}-P_{i, j+1,:}\right\|_{1} Lsim=i=1Cj=1h1Pi,j,:Pi,j+1,:1
  • 另一个是车道线形状损失函数,作者使用softmax函数得到车道线的概率:Prob⁡i,j,:=softmax⁡(Pi,j,1:w)\operatorname{Prob}_{i, j,:}=\operatorname{softmax}\left(P_{i, j, 1: w}\right)Probi,j,:=softmax(Pi,j,1:w),同时使用期望来表示车道线所处位置Loci,j=∑k=1wk⋅Prob⁡i,j,kL o c_{i, j}=\sum_{k=1}^{w} k \cdot \operatorname{Prob}_{i, j, k}Loci,j=k=1wkProbi,j,k。最后作者使用二阶微分方程来约束车道线位置:
    Lshp=∑i=1C∑j=1h−2∥(Loci,j−Loci,j+1)−(Loci,j+1−Loci,j+2)∥1\begin{aligned} L_{s h p}=\sum_{i=1}^{C} \sum_{j=1}^{h-2} \| &\left(L o c_{i, j}-L o c_{i, j+1}\right) -\left(L o c_{i, j+1}-L o c_{i, j+2}\right) \|_{1} \end{aligned} Lshp=i=1Cj=1h2(Loci,jLoci,j+1)(Loci,j+1Loci,j+2)1

2.自采数据集车道线检测

下面使用作者训练好的模型来检测车道线,代码链接为:https://github.com/cfzd/Ultra-Fast-Lane-Detection。

下载完源码后,创建一个lane_detection.py,首先导入需要的库:

import torch
import scipy.special
import os, cv2
from PIL import Image
from model.model import parsingNet
import numpy as np
import torchvision.transforms as transforms
from data.constant import tusimple_row_anchor

然后加载预训练模型,作者在两个车道线数据集上进行了训练,我这里选择是的在TuSimple数据集训练的模型,代码如下:

 net = parsingNet(pretrained = False, backbone='18',cls_dim = (101,56,4),use_aux=False) # we dont need auxiliary segmentation in testingtest_model = 'tusimple_18.pth'
state_dict = torch.load(test_model, map_location='cpu')['model']compatible_state_dict = {}
for k, v in state_dict.items():if 'module.' in k:compatible_state_dict[k[7:]] = velse:compatible_state_dict[k] = vnet.load_state_dict(compatible_state_dict, strict=False)
net.eval()

然后是一些参数设置,如图片大小尺寸(我这里图片大小为 1280×5601280\times5601280×560),row anchor 尺寸(这里使用的是作者设置的anchor尺寸),图片预处理等(将图片大小resize为 800×288800\times288800×288):

img_w, img_h = 1280, 560
size = (img_w,img_h)
cls_num_per_lane = 56
row_anchor = tusimple_row_anchorimg_transforms = transforms.Compose([transforms.Resize((288, 800)),transforms.ToTensor(),transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
])

下一步就是车道线检测与可视化:

 with torch.no_grad():out = net(img)col_sample = np.linspace(0, 800-1, 100)
col_sample_w = col_sample[1] - col_sample[0]out_j = out[0].data.cpu().numpy()
out_j = out_j[:, ::-1, :]                               
prob = scipy.special.softmax(out_j[:-1, :, :], axis=0)  
idx = np.arange(100) + 1
idx = idx.reshape(-1, 1, 1)
loc = np.sum(prob * idx, axis=0)
out_j = np.argmax(out_j, axis=0)
loc[out_j == 100] = 0
out_j = loc                                             for i in range(out_j.shape[1]):if np.sum(out_j[:, i] != 0) > 2:for k in range(out_j.shape[0]):if out_j[k, i] > 0:ppp = (int(out_j[k,i] * col_sample_w * img_w / 800) - 1, int(img_h *   (row_anchor[cls_num_per_lane-1-k]/288))-1)cv2.circle(vis,ppp,4,(0,0,255),-1)
Image.fromarray(vis).show()

最后检测结果如下:
在这里插入图片描述

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

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

相关文章

Coursera自动驾驶课程第16讲:LIDAR Sensing

在第15讲《Coursera自动驾驶课程第15讲&#xff1a;GNSS and INS Sensing for Pose Estimation》 我们学习了自动驾驶定位中常用的两种传感器&#xff1a;IMU&#xff08;惯性测量单元&#xff09; 和GNSS&#xff08;全球导航卫星系统&#xff09;。 本讲我们将学习自动驾驶汽…

DB、ETL、DW、OLAP、DM、BI关系结构图

在此大概用口水话简单叙述一下他们几个概念&#xff1a; &#xff08;1&#xff09;DB/Database/数据库——这里一般指的就是OLTP数据库&#xff0c;在线事物数据库&#xff0c;用来支持生产的&#xff0c;比如超市的买卖系统。DB保留的是数据信息的最新状态&#xff0c;只有一…

Tarjan 算法 常用模板

可以求每个点属于第几个强连通分量&#xff1a;https://blog.csdn.net/dellaserss/article/details/8267192 int Tarjan(int u){int v;dfn[u]low[u]Index;stack[Top]u;Instack[u]1;for(int i0;i<G[u].size();i){vG[u][i];if(!dfn[v]){Tarjan(v);low[u]min(low[u],low[v]);}…

【HDU - 5012】Dice(模拟,bfs)

题干&#xff1a; There are 2 special dices on the table. On each face of the dice, a distinct number was written. Consider a 1.a 2,a 3,a 4,a 5,a 6 to be numbers written on top face, bottom face, left face, right face, front face and back face of dice A. S…

重读经典:《Generative Adversarial Nets》

GAN论文逐段精读【论文精读】这是李沐博士论文精读的第五篇论文&#xff0c;这次精读的论文是 GAN。目前谷歌学术显示其被引用数已经达到了37000。GAN 应该是机器学习过去五年上头条次数最多的工作&#xff0c;例如抖音里面生成人物卡通头像&#xff0c;人脸互换以及自动驾驶中…

一步步编写操作系统 62 函数调用约定

由于我们要将c语言和汇编语言结合编程啦&#xff0c;所以一定会存在汇编代码和c代码相互调用的问题&#xff0c;有些事情还是要提前交待给大家的&#xff0c;本节就是要给大家说下函数调用规约中的那些事儿。 函数调用约定是什么&#xff1f; 调用约定&#xff0c;calling co…

重读经典:《An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale》

ViT论文逐段精读【论文精读】这次李沐博士邀请了亚马逊计算机视觉专家朱毅博士来精读 Vision Transformer&#xff08;ViT&#xff09;&#xff0c;强烈推荐大家去看本次的论文精读视频。朱毅博士讲解的很详细&#xff0c;几乎是逐词逐句地讲解&#xff0c;在讲解时把 ViT 相关…

【Gym - 101612C】【2017-2018NEERC】Consonant Fencity(状压枚举,预处理)

题干&#xff1a; 把26个字母分成19个辅音字母和7个元音字母&#xff0c;让你通过 将某些字母改为大写状态&#xff0c;使得字符串中连续的两个大小写状态不同的辅音字母组成的字母对数量最多&#xff0c;输出该状态下的字符串。注意输出的字符串中同一字母必须形态统一&#…

浅谈Mysql 表设计规范

本文首先探讨下数据库设计的三大范式&#xff0c;因为范式只是给出了数据库设计的原则&#xff0c;并没有告诉我们实际操作中应该怎样操作&#xff0c;应该注意什么&#xff0c;所以我们还会谈下实际工作中需要注意的具体操作问题。 三大范式 首先放出三大范式内容&#xff0c…

从零开始学视觉Transformer(1):Hello Vision Transformer

Vision Transformer打卡营分享一门很棒的 ViT 课程&#xff0c;课程详细介绍可以看这篇文章&#xff1a; 《Vision Transformer打卡营来啦&#xff01;朱欤博士带你从零玩转ViT爆款模型&#xff01;》

SQLServer中ISNULL、NULLIF和CONVERT函数

效率&#xff1a; UNION和UNION ALL关键字都是将两个结果集合并为一个&#xff0c;但这两者从使用和效率上来说都有所不同。 1、对重复结果的处理&#xff1a;UNION在进行表链接后会筛选掉重复的记录&#xff0c;Union All不会去除重复记录。 2、对排序的处理&#xff1a;Union…

一步步编写操作系统 66 浅析c库函数与系统调用1

本来说好的接下来的工作是要去“丰满”我们的内核&#xff0c;可咱们这种一步一回头的学习方式还得继续啊。其实我了解大家急切写内核的心情&#xff0c;但本书《操作系统真象还原》&#xff08;请大家支持正版&#xff09;的目的不是写一个操作系统就完事了&#xff0c;而是让…

给不会调用C++STL库中二分函数lower_bound,upper_bound,binary_search同学的一些话!

lower_bound算法返回第一个大于等于给定值所在的位置。设置两个指针start和last&#xff0c;其中start指向数组的起始位置&#xff0c;last指向数组末尾位置之后的位置。当start和last指向相同位置时循环结束。mid指向[start,last)区间的中间位置&#xff0c;当中间位置元素值大…

详解IMU标定经典论文:A Robust and Easy to Implement Method for IMU Calibration without External Equipments

本文介绍一篇 关于IMU 标定的经典论文&#xff0c;论文收录于 ICRA14&#xff0c;在论文中作者介绍了如何不适用外部设备标定 IMU 加速度和角速度偏差、尺度系数、轴偏移参数。 论文链接&#xff1a;https://readpaper.com/paper/2021503353、https://readpaper.com/paper/221…

重读经典:《Momentum Contrast for Unsupervised Visual Representation Learning》

MoCo 论文逐段精读【论文精读】这次论文精读李沐博士继续邀请了亚马逊计算机视觉专家朱毅博士来精读 Momentum Contrast&#xff08;MoCo)&#xff0c;强烈推荐大家去看本次的论文精读视频。朱毅博士和上次一样讲解地非常详细&#xff0c;几乎是逐词逐句地讲解&#xff0c;在讲…

【HRBUST - 1623】Relation(思维模拟,拆解字符串)

题干&#xff1a; 一天&#xff0c;ikki在看书的时候发现书上有个类似于家谱状的插图&#xff0c;突然ikki想到了一个有趣的现象&#xff1a;有时候用某个人一连串 的关系描述另一个人的时候&#xff0c;最后可能还是他本身。例如&#xff1a;小明的爸爸的爸爸和小明的爷爷是同…

一步步编写操作系统 67 系统调用的实现1-2 68

接上文&#xff1a; 系统调用的子功能要用eax寄存器来指定&#xff0c;所以咱们要看看有哪些系统调用啦&#xff0c;在linux系统中&#xff0c;系统调用是定义在/usr/include/asm/unistd.h文件中&#xff0c;该文件只是个统一的入口&#xff0c;指向了32位和64位两种版本。在a…