资源汇总:
论文下载地址:https://arxiv.org/abs/1802.05591
github项目地址:https://github.com/MaybeShewill-CV/lanenet-lane-detection
LanNet资料合集:https://ai-wx.blog.csdn.net/article/details/108575549
LanNet论文翻译:车道线检测网络之LaneNet
一、LaneNet 算法详解
1.1 LaneNet 简介
传统的车道线检测方法依赖于手工提取的特征来识别,如颜色的特征、结构张量、轮廓等,这些特征还可能与霍夫变换、各种算子或卡尔曼滤波器相结合。在识别车道线之后,采用后处理技术来过滤错误检测并将其分组在一起以形成最终车道。然而,由于道路场景的变化,这些传统的方法容易出现鲁棒性问题!
更新的方法利用深度学习模型,这些模型被训练用于像素级车道分割。但这些方法仅限于检测预定义的固定数量的车道,例如当前车道,并且不能应对车道改变。
基于此,2018年Davy Neven等人提出一种新的车道线检测网络LaneNet,LaneNet主要做出了如下两个贡献:
- 将车道检测问题归结为一个实例分割问题,其中每条车道都形成了自己的实例,可以端到端地进行训练。
- 构建了一个新的网络H-Net,用于学习给定输入图像的透视变换参数,该透视变换能够对坡度道路上的车道线进行良好地拟合,克服了鲁棒性不好的问题。
1.2 整体结构分析
1.3 LaneNet 网络结构
LaneNet的整体网络结构如下:
二值化分割网络
Lanenet的一个分支为二值化分割网络,该网络将车道线像素与背景区分开。由于目标类别是2类(车道/背景),并且高度不平衡,因此参考了ENet,损失函数使用的是标准的交叉熵损失函数。
实例分割网络
该分支网络参考了《Semantic Instance Segmentation with a Discriminative Loss Function》,使用基于one-shot的方法做距离度量学习,将该方法集成在标准的前馈神经网络中,可用于实时处理。该分支网络训练后输出一个车道线像素点距离,基于归属同一车道的像素点距离近,不同车道线像素点距离远的基本思想,利用聚类损失函数聚类得到各条车道线。
聚类损失函数
损失函数如下:
$x_ =max(0, x)$
$L{total}=L{var} L_{dist}$
其中,各个参数表示如下:
- C——表示车道线实例个数;
- $N_c$——每个车道线实例中像素的个数;
- $u_c$——每个车道线实例的像素中心;
- $L_{var}$是方差损失,他的目的是为了降低类内距离;
- $L_{dist}$是距离损失,它的目的是增大类间距离 (不同车道线之间的距离);
网络结构图
LaneNet的架构基于编码器-解码器网络ENet,该网络是由5个阶段组成。前3个阶段是编码器网络,进行了两次下采样;后两个阶段是解码器网络,进行了两次上采样。
LaneNet在该网络的基础上修改成了双分支网络。由于ENet的编码器比解码器包含更多的参数,完全在两个任务之间共享完整的编码器将导致不令人满意的结果。因此,LaneNet只在两个分支之间共享前两个阶段(1和2),留下ENet编码器的阶段3和完整的ENet解码器作为每个单独分支的主干。分割分支的最后一层输出单通道图像,用于二值化分割;而实例分割分支的最后一层输出N通道图像,其中N是实例维度。每个分支的损失项都是相等加权的,并通过网络反向传播。
1.4 H-Net 网络结构
LaneNet网络输出的是每条车道线的像素集合,常规的处理是将图像转为鸟瞰图,然后用二次或三次多项式拟合出弯曲的车道线。然而,目前所使用的透视变换矩阵的参数通常是预先设定、不会改变的,在面对水平线波动的影响(如上下坡)等情况下的车道线拟合并不准确,鲁棒性不强。因此,作者提出了H-net模型,用来学习透视变换矩阵的参数H。
H有6个自由度,放置零是为了强制约束,即在变换下水平线保持水平。
H-NET的网络体系结构较小,由3x3卷积、BN层 和 Relu 的连续块构成。使用最大池化层来降低维度,并在最后添加2个全连接层。完整的网络结构如下图所示:
最后一个全连接层的结点数是6,对应的就是H矩阵中的6个参数。
1.5 LaneNet 性能优点
检测速度。在英伟达1080Ti显卡上进行测试,检测一帧大小为512x512的彩色图片,耗时19ms,因此每秒可处理50帧左右。
检测精度。 通过使用LaneNet结合三阶多项式拟合和H-Net的变换矩阵,在tuSimple挑战中检测精度达到96.4%,获得了第四名,与第一名相比只有0.5%的差异。结果可以在下表中看到。
二、手把手带你实现 LaneNet
2.1 项目介绍
该项目在github上已经开源,获得了1.3k的星标,想试试的同学可克隆下来:https://github.com/MaybeShewill-CV/lanenet-lane-detection,如果打不开,也可以从我的百度云网盘下载:LaneNet资料合集 ,提取码:1024
代码结构和各部分功能如下:
代码语言:txt复制lanenet-lane-detection
├── config //配置文件
├── data //一些样例图片和曲线拟合参数文件
├── data_provider // 用于加载数据以及制作 tfrecords
├── lanenet_model
│ ├── lanenet.py //网络布局 inference/compute_loss/compute_acc
│ ├── lanenet_front_end.py // backbone 布局
│ ├── lanenet_back_end.py // 网络任务和Loss计算 inference/compute_loss
│ ├── lanenet_discriminative_loss.py //discriminative_loss实现
│ ├── lanenet_postprocess.py // 后处理操作,包括聚类和曲线拟合
├── model //保存模型的目录semantic_segmentation_zoo
├── semantic_segmentation_zoo // backbone 网络定义
│ ├── __init__.py
│ ├── vgg16_based_fcn.py //VGG backbone
│ └─ mobilenet_v2_based_fcn.py //mobilenet_v2 backbone
│ └── cnn_basenet.py // 基础 block
├── tools //训练、测试主函数
│ ├── train_lanenet.py //训练
│ ├── test_lanenet.py //测试
│ └── evaluate_dataset.py // 数据集评测 accuracy
│ └── evaluate_lanenet_on_tusimple.py // 数据集检测结果保存
│ └── evaluate_model_utils.py // 评测相关函数 calculate_model_precision/calculate_model_fp/calculate_model_fn
│ └── generate_tusimple_dataset.py // 原始数据转换格式
├─ showname.py //模型变量名查看
├─ change_name.py //模型变量名修改
├─ freeze_graph.py//生成pb文件
├─ convert_weights.py//对权重进行转换,为了模型的预训练
└─ convert_pb.py //生成pb文
2.2 环境搭建
根据开源作者描述,其测试的环境为:
- ubuntu 16.04
- python3.5
- cuda-9.0
- cudnn-7.0
- GTX-1070 GPU
- tensorflow 1.12.0
我使用的环境与配置为:
- ubuntu16.04系统
- PyCharm 2020
- python3.6
- tensorflow1.13.1-gpu
- cuda-10.0
- cudnn7.6.4
- opencv4.0.0
- RTX 2070 GPU
想尝试的朋友,可以参考上面两种配置,也可以自行尝试其他的版本。
2.3 准备工作
如果想要自行训练的同学,可以下载TuSimple数据集,进行训练。同样,我们也可以直接使用官方训练好的模型,来输入图片,看看测试效果。为了方便,下面我们直接加载已经训练好的模型,进行本地测试。
(1) 下载TuSimple数据集,如果不训练可以跳过这一步。
(2) 下载训练好的模型,下载链接:LaneNet资料合集 ,提取码:1024
下载完后,我们将模型文件tusimple_lanenet放在工程目录下的model文件中,如下图所示:
2.4 模型测试
完成环境配置和模型部署后,我们就可以进行测试了!
(1) 先对TusSample数据集中的图片进行测试
- 第一步,在原工程目录下的data文件中新建一个Mytest文件夹,然后任意选取TusSample数据集中的一张图片放入其中,例如1.jpg,如下图所示:
- 第二步,使用PyCharm打开下载好的项目工程,配置好环境后,打开终端,如下图所示:
- 第三步,在终端输入以下命令,执行程序:
python tools/test_lanenet.py --weights_path model/tusimple_lanenet/tusimple_lanenet.ckpt --image_path data/Mytest/1.jpg
最后车道线检测效果如下:
(2)对自己的图片进行测试
- 第一步,选择自己拍摄的一张车道线图片2.jpg,放入刚才新建好的Mytest文件夹下,如下图所示:
第二步,打开终端,输入命令,执行程序:
代码语言:txt复制python tools/test_lanenet.py --weights_path model/tusimple_lanenet/tusimple_lanenet.ckpt --image_path data/Mytest/2.jpg
对自己的拍摄的图片检测效果如下:
测试分析:
从图中可以看出,对自己的图片进行检测时,最终的检测结果虽然能够完美地与实际车道线重合,但是延伸至了空中。
产生这种情况最主要的原因是:没有自己制作数据集进行训练,从而得到更有针对性的模型造成的。由于这里我使用的测试模型是在TuSimple数据集下训练得到的,所以我们对TuSimple中的图片测试效果会很好,比如前面的1.jpg。
如果我们想要对自己的图片进行测试,得到更好的效果,那么就需要自己的数据集。比较好的办法是:
- 首先在TuSimple数据集下进行训练,得到的训练模型作为预训练模型,这一部分工作其实已经做好了,大家直接下载预训练模型即可
- 然后,在预训练模型的基础上,加载自己制作的数据集,再进行训练,直到达到预期的效果。
采用这种迁移学习的思想,往往能够事半功倍!
1024,祝大家节日快乐!喜欢就给我点个赞吧,您的支持是我创作的最大动力!
戳戳这里,观看原文:https://ai-wx.blog.csdn.net/article/details/108575549