Cam2BEV
本仓库包含了我们论文中提出的方法的官方实现,该方法用于根据多个车载摄像头的图像计算语义分割的鸟瞰图(BEV)图像:
基于Sim2Real深度学习的多车载摄像头图像到语义分割鸟瞰图的转换方法 (IEEE Xplore, arXiv)
Lennart Reiher, Bastian Lampe, 和 Lutz Eckstein
亚琛工业大学汽车工程研究所(ika)
[!重要]
本仓库由亚琛工业大学汽车工程研究所(ika)开源并维护。
基于深度学习的感知是我们车辆智能与自动驾驶领域的众多研究主题之一。
如果您想了解更多关于我们如何支持您的高级驾驶辅助和自动驾驶工作,欢迎与我们联系!
Timo Woopen - 车辆智能与自动驾驶研究领域经理
+49 241 80 23549
timo.woopen@ika.rwth-aachen.de
摘要 — 准确的环境感知对自动驾驶至关重要。在使用单目摄像头时,环境中元素的距离估计是一个主要挑战。当摄像头视角转换为鸟瞰视角(BEV)时,可以更容易地估计距离。对于平面表面,逆透视映射(IPM)可以准确地将图像转换为BEV。但是,这种转换会扭曲车辆和弱势道路使用者等三维物体,使得难以估计它们相对于传感器的位置。本文描述了一种方法,可以根据多个车载摄像头的图像获得校正的360°BEV图像。校正后的BEV图像被分割成语义类,并包括对被遮挡区域的预测。这种神经网络方法不依赖于人工标注的数据,而是在合成数据集上训练,使其能够很好地泛化到真实世界的数据。通过使用语义分割图像作为输入,我们减小了模拟数据和真实世界数据之间的现实差距,并能够证明我们的方法可以成功应用于真实世界。在合成数据上进行的大量实验证明了我们的方法相比IPM的优越性。
我们希望我们的论文、数据和代码能够帮助您的研究。如果是这样,请引用:
@INPROCEEDINGS{ReiherLampe2020Cam2BEV,
author={L. {Reiher} and B. {Lampe} and L. {Eckstein}},
booktitle={2020 IEEE 23rd International Conference on Intelligent Transportation Systems (ITSC)},
title={A Sim2Real Deep Learning Approach for the Transformation of Images from Multiple Vehicle-Mounted Cameras to a Semantically Segmented Image in Bird's Eye View},
year={2020},
doi={10.1109/ITSC45102.2020.9294462}}
内容
仓库结构
Cam2BEV
├── data # 默认情况下我们的合成数据集下载到此处
├── model # 训练脚本和配置
│ ├── architecture # 神经网络架构的TensorFlow实现
│ └── one_hot_conversion # 定义语义分割图像的独热编码的文件
└── preprocessing # 预处理脚本
├── camera_configs # 定义我们数据集中使用的摄像头内参/外参的文件
├── homography_converter # 用于将OpenCV单应性转换为uNetXST空间变换器使用的脚本
├── ipm # 通过IPM生成经典单应性图像的脚本
└── occlusion # 向BEV图像引入遮挡类的脚本
安装
我们建议设置一个Python 3.7虚拟环境(例如使用_virtualenv_或_conda_)。在虚拟环境中,用户可以使用_pip_安装所有软件包依赖项。我们论文中的结果是使用_TensorFlow 2.1_(CUDA 10.1_用于GPU支持)实现的。该仓库现已在_TensorFlow 2.5_上进行了测试,但对更高版本的支持开始出现问题,因为_DeepLab_模型实现由于不可训练的lambda层而不支持_TensorFlow>2.5。
pip install -r requirements.txt
数据
我们提供了两个可用于训练神经网络的合成数据集。这些数据集托管在Cam2BEV数据仓库中。这两个数据集都用于产生我们论文中呈现的结果:
有关数据的更多信息,请参阅仓库的README。
可以通过运行提供的下载脚本轻松下载和提取这两个数据集:
./data/download.sh
注意: 下载大小约为3.7GB,两个数据集解压后的大小约为7.7GB。
预处理
我们的论文描述了两种预处理技术:
(1) 向标签图像引入_遮挡_类
(2) 生成单应性图像
1) 处理遮挡
交通参与者和静态障碍物可能会遮挡环境的部分区域,使得对BEV图像中这些区域的预测大多不可能。为了制定一个良好的问题,需要为摄像头视角中被遮挡的BEV区域向标签图像引入一个额外的语义类。为此,可以使用preprocessing/occlusion。下面是遮挡预处理的一个例子。
运行以下命令处理_dataset 1_FRLR_的原始标签图像,并引入_occluded_类别。你需要提供无人机摄像头和所有车载摄像头的相机内参/外参(以yaml文件形式)。
注意: 在批处理模式下,此脚本利用多进程。处理整个数据集仍可能需要相当长的时间。因此,我们还提供了已预处理的数据。
cd preprocessing/occlusion
./occlusion.py \
--batch ../../data/1_FRLR/train/bev \
--output ../../data/1_FRLR/train/bev+occlusion \
../camera_configs/1_FRLR/drone.yaml \
../camera_configs/1_FRLR/front.yaml \
../camera_configs/1_FRLR/rear.yaml \
../camera_configs/1_FRLR/left.yaml \
../camera_configs/1_FRLR/right.yaml
更多信息请参见preprocessing/occlusion/README.md。
2) 投影预处理
作为将逆透视映射(IPM)技术纳入我们方法的一部分,需要计算单应性,即车载摄像头帧和BEV之间的投影变换。作为我们第一种方法变体(第III-C节)的预处理步骤,IPM应用于所有车载摄像头图像。变换设置为捕获与地面实况BEV图像相同的视场。为此,可以使用preprocessing/ipm。下面是从四个车载摄像头图像计算得出的单应性图像示例。
运行以下命令从_dataset 1_FRLR_的所有摄像头图像计算单应性BEV图像。你需要提供无人机摄像头和所有车载摄像头的相机内参/外参(以yaml文件形式)。
注意: 为节省时间,我们还提供了已预处理的数据。
cd preprocessing/ipm
./ipm.py --batch --cc \
--output ../../data/1_FRLR/train/homography \
--drone ../camera_configs/1_FRLR/drone.yaml \
../camera_configs/1_FRLR/front.yaml \
../../data/1_FRLR/train/front \
../camera_configs/1_FRLR/rear.yaml \
../../data/1_FRLR/train/rear \
../camera_configs/1_FRLR/left.yaml \
../../data/1_FRLR/train/left \
../camera_configs/1_FRLR/right.yaml \
../../data/1_FRLR/train/right
更多信息请参见preprocessing/ipm/README.md。
训练
使用脚本model/train.py、model/evaluate.py和model/predict.py来训练模型、在验证数据上评估模型,并在测试数据集上进行预测。
输入目录、训练参数等可以通过CLI参数或配置文件设置。使用--help
标志运行脚本或参考提供的示例配置文件之一。我们为每个网络和数据集提供配置文件:
- model/config.1_FRLR.deeplab-mobilenet.yml
- model/config.1_FRLR.deeplab-xception.yml
- model/config.1_FRLR.unetxst.yml
- model/config.2_F.deeplab-mobilenet.yml
- model/config.2_F.deeplab-xception.yml
- model/config.2_F.unetxst.yml
以下命令将指导你在_dataset 1_FRLR_上训练_uNetXST_。
训练
通过传递提供的配置文件model/config.1_FRLR.unetxst.yml来开始训练_uNetXST_。如果验证数据集上的MIoU分数不再上升,训练将自动停止。
cd model/
./train.py -c config.1_FRLR.unetxst.yml
你可以通过将TensorBoard指向输出目录(默认为model/output
)来可视化训练进度。训练指标也会打印到stdout
。
评估
在评估训练好的模型之前,将参数model-weights
设置为指向其模型目录的Checkpoints
文件夹中的best_weights.hdf5
文件。然后运行评估以计算混淆矩阵和类IoU分数。
./evaluate.py -c config.1_FRLR.unetxst.yml --model-weights output/<YOUR-TIMESTAMP>/Checkpoints/best_weights.hdf5
评估结果将在评估结束时打印,并导出到模型目录的Evaluation
文件夹中。
测试
要实际查看网络的预测结果,请在未见过的输入图像(如验证数据集)上尝试。预测的BEV图像将导出到参数output-dir-testing
指定的目录。
./predict.py -c config.1_FRLR.unetxst.yml --model-weights output/<YOUR-TIMESTAMP>/Checkpoints/best_weights.hdf5 --prediction-dir output/<YOUR-TIMESTAMP>/Predictions
神经网络架构
我们在model/architecture中提供了_DeepLab_和_uNetXST_神经网络架构的实现。_DeepLab_有两种不同的骨干网络:MobileNetV2_或_Xception。
DeepLab
_DeepLab_模型应该将逆透视映射(preprocessing/ipm)计算的单应性图像作为输入。
配置
- 将
model
设置为architecture/deeplab_mobilenet.py
或architecture/deeplab_xception.py
- 将
input-training
和其他输入目录参数设置为包含单应性图像的文件夹 - 在配置文件中注释掉
unetxst-homographies
,或者不通过CLI提供
uNetXST
_uNetXST_模型包含SpatialTransformer单元,它们在网络内部执行IPM。因此,在构建网络时,需要提供从每个摄像头变换图像的单应性。
配置
- 将
model
设置为architecture/uNetXST.py
- 将
input-training
和其他输入目录参数设置为包含每个摄像头图像的文件夹列表(例如[data/front, data/rear, data/left, data/right]
) - 将
unetxst-homographies
设置为一个Python文件,该文件包含存储在变量H
中的单应性矩阵列表(例如../preprocessing/homography_converter/uNetXST_homographies/1_FRLR.py
)- 我们为两个数据集提供了这些单应性矩阵,分别在preprocessing/homography_converter/uNetXST_homographies/1_FRLR.py和preprocessing/homography_converter/uNetXST_homographies/2_F.py中
- 要为不同的摄像头配置计算这些单应性矩阵,请按照preprocessing/homography_converter中的说明进行操作
自定义
我想设置不同的训练超参数
使用--help
标志运行训练脚本,或查看提供的示例配置文件之一,了解可以轻松设置哪些参数。
我希望网络处理更多/更少的语义类别
我们提供的图像数据集包含所有30个_CityScapes_类别颜色。如何将这些类别减少到例如10个类别是在model/one_hot_conversion中的独热编码转换文件中定义的。使用训练参数--one-hot-palette-input
和--one-hot-palette-label
来选择其中一个文件。你可以轻松创建自己的独热编码转换文件,它们相当易于理解。
如果你调整了--one-hot-palette-label
,你还需要修改--loss-weights
。要么省略该参数以均匀加权所有输出类别,要么计算新的合适的损失权重。提供的配置文件中的权重是使用以下Python代码段(从model
目录)计算得出的。
import numpy as np
import utils
palette = utils.parse_convert_xml("one_hot_conversion/convert_9+occl.xml")
dist = utils.get_class_distribution("../data/1_FRLR/train/bev+occlusion", (256, 512), palette)
weights = np.log(np.reciprocal(list(dist.values())))
print(weights)
我想使用自己的数据
你需要在自己的数据上运行预处理方法。以下是需要考虑的大致步骤:
- 指定类似于[preprocessing/camera_configs](https://github.com/ika-rwth-aachen/Cam2BEV/blob/master/[preprocessing/camera_configs]中的文件的相机内参/外参
- 运行preprocessing/occlusion/occlusion.py
- 运行preprocessing/occlusion/ipm.py
- 按照preprocessing/homography_converter中的说明计算兼容uNetXST的单应性矩阵
- 调整或创建新的独热编码转换文件(model/one_hot_conversion)
- 在专用配置文件中设置所有训练参数
- 开始训练