Pseudo-LiDAR 简介

来自康奈尔大学的"Pseudo-LiDAR from Visual Depth Estimation: Bridging the Gap in 3D Object Detection for Autonomous Driving". 

主要探讨了为什么Image-based 3D Perception与LiDAR-based 3D Perception之间存在较大的gap,并且提出了bridge this gap的解决方案。

首先利用DRON或PSMNET从单目 (Monocular)或双目 (Stereo)图像获取对应的深度图像(depth map);然后将原图像结合深度信息得到伪雷达点云 (pseudo-LiDAR);最后用pseudo-LiDAR代替原始雷达点云,以3D point cloud和鸟瞰图(bird's eye view)的形式,分别在LiDAR-based的F-PointNet以及AVOD上与图像的正视图(front view)表示进行了比较。

Pseudo-LiDAR整个pipeline如下图所示。

3D目标检测 综述 双目3d目标检测_神经网络


Pseudo-LiDAR一堆对比实验如表所示。 

3D目标检测 综述 双目3d目标检测_神经网络_02

 

 其中蓝色字体为利用图像的pseudo-LiDAR表示;灰色字体为利用原始雷达点云;黑色字体为利用图像的前视图表示 (原始表示)。从表中可以看到,将图像转换为pseudo-LiDAR表示后,确实是bridged the gap between Image-based 3D Perception and LiDAR-based 3D Perception。

Image-based 3D Perception 劣势原因

  • 不准确的深度信息

从2D图像进行3D感知本身就是一个ill-posed问题,因为图像缺少3D感知最为关键的深度信息。虽然通过单目或双目深度估计可以得到深度图像,但是其不准确的深度信息会严重影响网络对三维空间的理解。这也是为什么目前主流的3D感知算法都会采用LiDAR的原因,即为什么LiDAR-based 3D Perception要远远优于Image-based 3D Perception, 因为LiDAR提供的深度信息是完全无误的。真正的原因好像不仅仅局限于此。

  • 这种2D图形表示形式的才是真正原因

目前的Image-based 3D Perception方案具体是怎么做的:一种方式是通过深度估计将深度信息作为additional channel加到原始图像后;另一种方式也是以叠加的方式,加入ground, class semantic, instance semantic, shape, context, location等手动特征(hand-crafted features), 以尽可能提供多方位的空间信息。

神经网络能够有效地从这些“无脑”叠加的多类特征图中感知到三维物体的真实属性吗?我们可以看一个实验结果。

3D目标检测 综述 双目3d目标检测_3D目标检测 综述_03


左上是由原始图像 (front view)估计的深度信息,右上是原始深度图通过二维卷积得到的结果;左下是对应得到的pseudo-Lidar (BEV形式);右下是将经过2D卷积处理后的深度图像变换到三维空间的点云。我们可以看到,原图像的深度信息经过2D卷积后发生了剧烈的畸变扭曲,原始的车辆形状也发生了巨大的改变。

因此,2D卷积在以front view形式的Image-based 3D Perception中并不work,以下给出理论分析

  • 不同物体之间应该不连贯

在2D图像中,不同深度的物体均呈现在同一个平面上,因此在卷积核的某一感受野之内,不同物体实际上是physically incoherent,但相邻的像素点之间并没有显式表示这种关系。比如图四的bounding box中,按深度从小到大排序有手、人脸、球拍等物体,这些物体以front view的形式是连贯在一起的,而网络并不能感知到实际的physically incoherent关系。Focal Loss的提出也是为了解决类似的前景、背景不平衡的问题,但是个人认为更重要的原因是2D图像的front view表示形式,严重限制了神经网络的2D和3D Perception。

  •  深度图客观造成不同尺度

在front view后简单叠加depth map,虽然能够提供重要的深度信息,但是深度图仍然没有直观地展示真实三维空间的分布属性,但是伪雷达点云可以哦。除此之外,越远的物体在front view中是越小的,而检测小物体本身就是一个比较难的任务。因此,深度图中不同尺度的物体也增加了Image-based 3D Perception的难度。而雷达点云可以保持三维空间中最原始的尺度。

综上,目前的Image-based 3D Perception方案较差的性能主要是由于front view这种2D图形表示,而不是之前一直纠结的不准确的depth map。

下表给出了实验论证,使用相同方法估计的depth map,以BEV形式 (pseudo-Lidar投影得到)的3D Perception要远优于FV+depth map的形式。

3D目标检测 综述 双目3d目标检测_3D_04



经过上面的分析,LiDAR-based 3D Perception的优越性便显而易见了。

首先,在三维点云中(或BEV),卷积和池化操作的区域都是physical nearby,不同位置的不同物体并不会混为一谈;其次,物体的尺度具备深度不变性(不会向图像那样近大远小),保持了三维空间中最原始的尺度。总之,虽然本文没有任何技术层面的创新与改进,但是重新审视了Image-based 3D Perception的致命点,能够给目前的三维感知一些重要的启示。

从3D检测中悟出的2D检测的一些改进

我们知道,目前几乎所有的3D Detector都是继承了2D Detector的结构以及设计思路 (除了PointNet),其改进的主要思想也都是来自2D Detector。

但是,从pseudo-Lidar对3D Detection的探讨中,我们也可以得到有益于2D Detection的启发,即主要限制复杂场景物体检测的原因是2D图像的front view表示。

因此,对于这种场景,通过depth estimation-point cloud-3D detection-2D projection可能会比在FV上用focal loss更有效。

融合LiDAR与pseudo-LiDAR

这也是作者在future work中提到的,因为雷达点云虽然精确并有反射强度信息,但是非常稀疏,而且线数不同分辨率也不同。

pseudo-LiDAR虽然不是特别精确,但是点云要密集的多,且具备RGB颜色信息。

因此,将两者进行融合 (互补),会是一个比较有意思的工作,这样比传统的RGB image & LiDAR point cloud fusion方式,比如MV3D, AVOD等,更加易于神经网络感知。

此外,可以尝试在pseudo-LiDAR和LiDAR之间架一个GAN,以生成更高精度的pseudo-LiDAR,使得Image-based 3D Perception性能进一步接近LiDAR-based 3D Perception,即在自动驾驶中,使相机完全代替雷达成为可能。

深度估计与pseudo-LiDAR转化

开源代码中使用的是PSMnet来估计深度,双目深度估计。

双目差异估计算法将一对左右图像作为输入,图像从具有水平偏移b(即基线)的一对相机捕获,并输出与两个输入图像中任一一个相同大小的视差图Y(u,v)为像素坐标。

在不失一般性的情况下,假设深度估计算法将左图像视为基准,并且在Y中记录右图像每个像素的的水平视差,水平视差Y(u,v)需要PSMnet train出来。
我们可以通过以下变换导出深度图D,fU为左摄像机的水平焦距

3D目标检测 综述 双目3d目标检测_3D_05

 

Pseudo-LiDAR的生成

不像其他论文那样将深度D作为多个附加通道并入RGB图像,我们的做法是输出左相机坐标系中每个像素(u,v)的3D位置(x,y,z)

3D目标检测 综述 双目3d目标检测_神经网络_06

 

其中(cU,cV)是对应于摄像机中心的像素位置,fV是垂直焦距。
通过将所有像素反投影到3D坐标中,我们得到3D点云。
在给定参考视点和观察方向的情况下,可以将这样的点云变换为任何独立坐标系。
我们将得到的点云称为pseudo-LiDAR(伪点云)。

Pseudo-LiDAR 复现

使用KITTI物体检测基准训练双目深度估计器、3D物体探测器的指导和代码、预训练模型。

3D目标检测 综述 双目3d目标检测_3D_07

Dependencies
python2.7 for PSMnet and pseudo-lidar
        pip install torch==0.4.1 -f https://download.pytorch.org/whl/cu90/stable
        torchvision 0.2.0
        KITTI 
        Scene Flow
python3.5 for avod 
        apt install python3-pip python3-pyside python3-tk -y
        pip3 install tensorflow-gpu==1.8.0 
        pip3 install mayavi

KITTI 3D object detection dataset

KITTI/object/
    
    train.txt
    val.txt
    test.txt
    trainval.txt 
    
    training/ # 5个软连接
        calib/
        image_2/ #left image
        image_3/ #right image
        label_2/
        lidar_velodyne/ 

    testing/
        calib/
        image_2/
        image_3/
        lidar_velodyne/

Velodyne点云(LiDAR)仅用作训练双目深度估计器(例如PSMNet)的GT。

双目深度估计 - PSM

PSMnet使用Scene Flow和KITTI的3,712个训练图像,提供预训练PSMNet模型。

pseudo_lidar/psmnet/Pretrained_Model
    pretrained_sceneflow.tar
    finetune_300.tar

还直接提供pseudo-LiDAR点云、训练的GT和由该预训练模型评估的测试图像的结果。

如果要将我们的pseudo-LiDAR数据用于3D对象检测,可以跳过以下内容并直接转到对象检测模型。

Generate GT( image disparities)

使用./preprocessing/generate_disp.py处理train.txt中出现的所有velodyne文件,这是我们的训练GT。

或者你可以直接从 disparity【disparity.zip】下载它们。将此文件夹命名为disparity并将其放在training文件夹中。

生成的视差需要依靠点云,即从空闲位置映射(内外参)到左右照片,同一个空间点在左右相片的像素差即为视差。

生成train的GT【*.npy在disparity/和*.png在disparity_png/】,用于训练模型,
python ./preprocessing/generate_disp.py --data_path ./KITTI/object/training/ --split_file ./KITTI/object/train.txt --save_disparity_path ./KITTI/object/training/disparity
生成val的GT【*.npy在disparity/和*.png在disparity_png/】,用于评价模型。
python ./preprocessing/generate_disp.py --data_path ./KITTI/object/training/ --split_file ./KITTI/object/val.txt --save_disparity_path ./KITTI/object/val/disparity

Train the stereo model

可以根据需要训练任何双目视差模型。

这里我们举一个例子来训练PSMNet,修改PSMNet源码后的保存在文件夹psmnet中。

确保按照此文件夹中的README安装正确的python和库。

我强烈建议使用conda env来组织python环境,因为我们将使用不同版本的Python。

此处pretrained_sceneflow.tar】下载在Sceneflow数据集上预先训练的psmnet模型。

# train psmnet with 4 TITAN X GPUs.
python ./psmnet/finetune_3d.py --maxdisp 192 \
     --model stackhourglass \
     --datapath ./KITTI/object/training/ \
     --split_file ./KITTI/object/train.txt \
     --epochs 300 \
     --lr_scale 50 \
     --loadmodel ./pretrained_sceneflow.tar \
     --savemodel ./psmnet/kitti_3d/  --btrain 12

# 例如
cd psmnet
CUDA_VISIBLE_DEVICES=4,5,6,7 python ./finetune_3d.py --maxdisp 192 --model stackhourglass --datapath ../KITTI/object/training/ --split_file ../KITTI/object/train.txt --epochs 300 --lr_scale 50 --loadmodel ./pretrained_sceneflow.tar --savemodel ./kitti_3d/ --btrain 12

Predict the disparities

cd psmnet
# 为了之后avod,需要生成预测的disparity,再转为伪雷达
CUDA_VISIBLE_DEVICES=1 python submission.py --loadmodel ./kitti_3d/finetune_xxx.tar --datapath ../KITTI/object/training/ --save_path ../KITTI/object/training/predict_disparity 【--save_float】
CUDA_VISIBLE_DEVICES=1 python submission.py --loadmodel ./Pretrained_Model/finetune_300.tar --datapath ../KITTI/object/training/ --save_path ../KITTI/object/training/predict_disparity
# for testing
CUDA_VISIBLE_DEVICES=2 python submission.py --loadmodel ./kitti_3d/finetune_300.tar --datapath ../KITTI/object/testing/ --save_path ../KITTI/object/testing/predict_disparity

评估 PSMNet on KITTI 2015 test data

CUDA_VISIBLE_DEVICES=0 python submission.py --maxdisp 192   --model stackhourglass   --KITTI 2015   --datapath ../KITTI/object/training/   --loadmodel  ./Pretrained_Model/finetune_300.tar
CUDA_VISIBLE_DEVICES=0 python submission.py --maxdisp 192   --model stackhourglass   --KITTI 2015   --datapath ../KITTI/object/training/   --loadmodel  ./kitti_3d/finetune_1.tar

Convert the disparities to point clouds

# training
python ./preprocessing/generate_lidar.py  \
    --calib_path ./KITTI/object/training/calib/ \
    --save_path ./KITTI/object/training/pseudo-lidar_velodyne/ \
    --disp_path ./KITTI/object/training/predict_disparity \
    --max_high 1
# testing
python ./preprocessing/generate_lidar.py  \
    --calib_path ./KITTI/object/testing/calib/ \
    --save_path ./KITTI/object/testing/pseudo-lidar_velodyne/ \
    --disp_path ./KITTI/object/testing/predict_disparity \
    --max_high 1

例如

对于training数据,将预测的disparity【png】的转为伪雷达点云【bin】
python ./preprocessing/generate_lidar.py --calib_dir ./KITTI/object/training/calib/  --save_dir ./KITTI/object/training/pseudo-lidar_velodyne/   --disparity_dir ./KITTI/object/training/predict_disparity   --max_high 1
对于testing数据,将预测的disparity【png】的转为伪雷达点云【bin】
python ./preprocessing/generate_lidar.py --calib_dir ./KITTI/object/testing/calib/ --save_dir ./KITTI/object/testing/pseudo-lidar_velodyne/ --disparity_dir ./KITTI/object/testing/predict_disparity --max_high 1
对于training数据,将生成的disparity【png】的再转回为雷达点云【bin】,对比两个BIN的异同。
python ./preprocessing/generate_lidar.py --calib_dir ./KITTI/object/training/calib/ --save_dir ./KITTI/object/training/pseudo-lidar_velodyne/ --disparity_dir ./KITTI/object/training/predict_disparity --max_high 1

RANSAC
如果要训练用于3D物体检测的 AVOD 模型,则需要从pseudo-lidar点云筛选plane,先训练得到ransac回归的权重,再利用权重来筛选点云。

#training
python ./preprocessing/kitti_process_RANSAC.py \
    --calib ./KITTI/object/training/calib/ \
    --lidar_dir  ./KITTI/object/training/pseudo-lidar_velodyne/ \
    --planes_dir /KITTI/object/training/pseudo-lidar_planes/
#testing
python ./preprocessing/kitti_process_RANSAC.py \
    --calib ./KITTI/object/testing/calib/ \
    --lidar_dir  ./KITTI/object/testing/pseudo-lidar_velodyne/ \
    --planes_dir /KITTI/object/testing/pseudo-lidar_planes/

例如

生成伪点云的plane
python ./preprocessing/kitti_process_RANSAC.py --calib ./KITTI/object/training/calib/  --lidar_dir ./KITTI/object/training/pseudo-lidar_velodyne/  --planes_dir ./KITTI/object/training/pseudo-lidar_planes/
python ./preprocessing/kitti_process_RANSAC.py --calib ./KITTI/object/testing/calib/  --lidar_dir ./KITTI/object/testing/pseudo-lidar_velodyne/  --planes_dir ./KITTI/object/testing/pseudo-lidar_planes/
生成真实点云的plane
python ./preprocessing/kitti_process_RANSAC.py --calib ./KITTI/object/training/calib/  --lidar_dir ./KITTI/object/training/velodyne/  --planes_dir ./KITTI/object/training/planes/
python ./preprocessing/kitti_process_RANSAC.py --calib ./KITTI/object/testing/calib/  --lidar_dir ./KITTI/object/testing/velodyne/  --planes_dir ./KITTI/object/testing/planes/

AVOD

https://github.com/kujason/avod 下载代码并安装Python依赖项。

按照他们的README准备数据,然后将velodyne中的文件替换为pseudo-lidar_velodyne中的文件,将planes文件替换为pseudo-lidar_planes中的文件。

mv  velodyne lidar_velodyne

ln -s pseudo-lidar_velodyne velodyne 

ln -s pseudo-lidar_planes  planes 

请注意,您仍应将文件夹名称保留为velodyne和plane。

按照README训练pyramid_cars_with_aug_example 模型。

您也可以下载我们的预训练模型并直接评估它。但是如果您想将结果提交到排行榜,则需要在trainval.txt上进行训练。

pretrained AVOD (trained only on train.txt)【avod.zip】

生成planes

参见3.2

AVOD 环境配置

cd pseudo_lidar
git clone https://github.com/kujason/avod
cd avod
vim .git/config  
    [submodule "wavedata"]
        url = https://github.com/kujason/wavedata.git
git submodule update --init --recursive
apt install python-pip3
pip3 install -r requirements.txt
pip3 install tensorflow-gpu==1.8.0
pip3 install protobuf==3.7.1
export PYTHONPATH=$PYTHONPATH:~/ld/pseudo_lidar/avod
export PYTHONPATH=$PYTHONPATH:~/ld/pseudo_lidar/avod/wavedata
#在wavedata中编译积分图像库
sh scripts/install/build_integral_image_lib.bash
# Avod使用Protobufs配置模型和训练参数。在使用框架之前,必须编译protos,忽略WARNING。
vim avod/protos/kitti_dataset.proto
    line11:   optional string dataset_dir = 2 [default = "~/ld/pseudo_lidar/KITTI/object"];  雷达、伪雷达、雷达16 不同
sh avod/protos/run_protoc.sh
apt-get install texlive-extra-utils   gnuplot

AVOD 点云可视化
 

python3 westwell/mayavi_tools/view_pc.py
若要展示ransac处理的结果,请执行:
python3 scripts/preprocessing/gen_mini_batches.py view

AVOD训练数据生成 

vim scripts/preprocessing/gen_mini_batches.py
process_trk= True     # Truck
process_car = False # Cars
process_ped = False # Pedestrians
process_cyc = False # Cyclists
process_ppl = False #Pedestrians+Cyclists

python3 scripts/preprocessing/gen_mini_batches.py noview

vim avod/protos/kitti_dataset.proto
    line11: optional string dataset_dir = 2 [default = "~/ld/pseudo_lidar/KITTI/object"]; 雷达、伪雷达不同
sh avod/protos/run_protoc.sh

点云空间生成anchor,再与label计算,保存的是anchor正反例信息,lidar和lidar16生成的信息不一样。

AVOD Configuration
在avod / configs中有训练的示例配置文件。您可以使用示例配置训练,或修改现有配置。
要训练新配置,请复制配置例如pyramid_cars_with_aug_example.config,将此文件重命名,并确保文件名与配置中的checkpoint_name例如'pyramid_cars_with_aug_example'条目匹配。
avod/data/outputs/pyramid_cars_with_aug_example/ 下是该配置的ckpt 、event等。

官方模型下载安装
cd ~/ld/pseudo_lidar/avod/avod/data/
mkdir -p outputs/pyramid_cars_with_aug_example_scratch_300_val/checkpoints
cd ~/ld/pseudo_lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example_scratch_300_val/checkpoints
cp avod.zip . && unzip avod.zip && rm -rf avod.zip

cp ~/ld/pseudo_lidar/avod/avod/configs/pyramid_cars_with_aug_example.config ~/ld/pseudo_lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example_scratch_300_val/pyramid_cars_with_aug_example_scratch_300_val.config
cd ~/ld/pseudo_lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example_scratch_300_val/
vim pyramid_cars_with_aug_example_scratch_300_val.config
 6 checkpoint_name: 'pyramid_cars_with_aug_example_scratch_300_val'
113 max_iterations: 240000
cp pyramid_cars_with_aug_example_scratch_300_val.config ~/ld/pseudo_lidar/avod/avod/configs/pyramid_cars_with_aug_example_scratch_300_val.config

cd ~/ld/pseudo_lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example_scratch_300_val/checkpoints
vim checkpoint 
model_checkpoint_path: "/headless/ld/pseudo_lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example_scratch_300_val/checkpoints/pyramid_cars_with_aug_example_scratch_300_val-00120000"
all_model_checkpoint_paths: "/headless/ld/pseudo_lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example_scratch_300_val/checkpoints/pyramid_cars_with_aug_example_scratch_300_val-00120000"

AVOD Train
 

python3 avod/experiments/run_training.py --pipeline_config=avod/configs/pyramid_cars_with_aug_example.config --device='1'  --data_split='train'
【默认:--device='0' --data_split='train' 】
【根据您的设置,使用Titan Xp训练大约需要16小时,使用GTX 1080需要20小时。如果过程中断,训练(或评估)将从上次保存的检查点继续(如果存在)。】
官方模型fintune:
python3 avod/experiments/run_training.py --pipeline_config=./avod/configs/pyramid_cars_with_aug_example_scratch_300_val.config --device='7' --data_split='train'

AVOD Evaluator ,自带的不好用

python3 avod/experiments/run_evaluation.py --pipeline_config=avod/configs/pyramid_cars_with_aug_example.config --device='0' --data_split='val'
【默认:--device='0' --data_split='val' 】
Evaluator有两种主要模式,您可以评估单个检查点,也可以重复评估检查点索引列表【checkpoints/checkpoint】中所有的ckpt。
Evaluator可在同一GPU上与train并行运行,以重复评估检查点,这可以在同一个配置文件中配置(查看eval_config条目)。
除了评估损失,计算精度等之外,Evaluator还在每个检查点上运行KITTI原生评估代码。
预测转换为KITTI格式,并为每个检查点计算AP。
结果保存在scripts / offline_eval / results / pyramid_cars_with_aug_example_results_0.1.txt中,其中0.1是分数阈值。 IoUs设置为(0.7,0.5,0.5)。
/headless/ld/pseudo_lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example/predictions/ 预测结果目录

自训练模型评估

1 验证集预测 step = 12w为例
python3 avod/experiments/run_inference.py --checkpoint_name='pyramid_cars_with_aug_example' --data_split='val' --ckpt_indices=120 --device='1'
2 转为KITTI提交的数据格式
python3 scripts/offline_eval/save_kitti_predictions.py pyramid_cars_with_aug_example 120
3 离线评估AP
cd ~/ld/kitti_native_evaluation
./evaluate_object_3d_offline ../KITTI/data_object_label_2/training/label_2/
/headless/ld/lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example/predictions/kitti_predictions_3d/val/0.1/20000/

官方模型评估

cd /headless/ld/pseudo_lidar/avod/
python3 avod/experiments/run_inference.py --checkpoint_name='pyramid_cars_with_aug_example_scratch_300_val' --data_split='val' --ckpt_indices=0 --device='1' ## 由于没有120k以前的indices,所以0代表120k step,1代表121k,120k代表240k
python3 scripts/offline_eval/save_kitti_predictions.py pyramid_cars_with_aug_example_scratch_300_val 120
./evaluate_object_3d_offline ../KITTI/data_object_label_2/training/label_2/ /headless/ld/pseudo_lidar/avod/avod/data/outputs/pyramid_cars_with_aug_example_scratch_300_val/predictions/kitti_predictions_3d/val/0.1/20000/

AVOD View the TensorBoard summaries

cd avod/data/outputs/pyramid_cars_with_aug_example
tensorboard --logdir logs

AVOD Inference

需要有KITTI/object/training/velodyne 和KITTI/object/training/planes,要软连接上才行。
python3 avod/experiments/run_inference.py --checkpoint_name='pyramid_cars_with_aug_example' --data_split='val' --ckpt_indices=120 --device='1'
python3 avod/experiments/run_inference.py --checkpoint_name='pyramid_cars_with_aug_example_scratch_300_val ' --data_split='val' --ckpt_indices=0 --device='1'
这里的ckpt_indices表示列表中检查点的索引。
如果配置中的checkpoint_interval为1000,则要评估检查点116000和120000,索引应为--ckpt_indices = 116 120.
您也可以将此值设置为-1以评估最后一个检查点。

AVOD Viewing Results

所有结果保存在avod/data/outputsoutputs/【ckpt name】/predictions/
在这里,您应该看到proposals_and_scores和final_predictions_and_scores结果。
要显示这些结果,您可以运行demos/show_predictions_2d.py。
需要根据您的特定实验配置脚本。
scripts/offline_eval/plot_ap.py将绘制AP与步骤的关系,并为中等难度的每个评估指标打印5个性能最高的检查点。
python3 demos/show_predictions_2d.py pyramid_trucks_with_aug_example 120 Truck

AVOD outputs

1  outputs/[ckpt name或config name]/prediction/
final_boxes_box_4ca_and_scores/[数据集名字,如val]/[step,如120000]/   
    # 
final_predictions_and_scores/[数据集名字,如val]/[step,如120000]/*.txt
    #  最终预测的结果,每行代表一个目标,一行9列。
proposals_and_scores/[数据集名字,如val]/[step,如120000]/*.txt  
    # proposal top的结果,每行代表一个目标,一行8列,300行。
images_2d/
    overlaid/[数据集名字,如val]/[step,如120000]/[rpn_score_threshold,如:0.1]/*.png 
    predictions/[数据集名字,如val]/[step,如120000]/[rpn_score_threshold,如:0.1]/*.png 
    proposals/[数据集名字,如val]/[step,如120000]/[rpn_score_threshold,如:0.1]/*.png 
        #以上三个目录分别对应avod/demos/show_predictions_2d.py中的
        # Drawing Toggles
    draw_proposals_separate = True #False
              draw_overlaid = True #False
              draw_predictions_separate = True
kitti_native_eval/  
    # 包含KITTI object devkit源码和一些自己的脚本
kitti_predictions_3d/
    # save_kitti_predictions.py转化为KITTI格式

2 outputs/[ckpt name或config name]/checkpoints/

3 outputs/[ckpt name或config name]/logs/

4 outputs/[ckpt name或config name]/[ckpt name或config name].config

Pseudo-LiDAR方案Inference开销评估

PSMnet模块Inference开销评估
硬件开销
CPU%    200~300    目前没有进行优化
内存    2g    目前没有进行优化
显存    4.4g    目前没有进行优化

时间开销
Mean:0.38s
Inference精度
mean mae: 89.3743
mean rmse: 95.4981
mean inverse mae: 0.0579692
mean inverse rmse: 0.0751476
mean log mae: 1.74577
mean log rmse: 1.9721
mean scale invariant log: 1.07096
mean abs relative: 0.762296
mean squared relative: 0.805205

结论
mean mae为89.3743,相当预测的深度图上每个点的深度距离真实点相差89,可以看到这个结果很差,这结果是在作者提供的预训练模型在KITTI目标检测数据集上的结果,我觉得有必要下载KITTI官方提供的深度估计数据集进行训练,另外也没有在sence flow数据集上fintune。作者还提供了sence flow的预训练模型,但是都没有在KITTI目标检测数据集上经过训练。
目前整个Pseudo-lidar的模型在此处是个短板,因为psmnet的结果不理想,所以造成后面的avod结果很差,真实的点云数据表明avod的模型并不差。

Pseudo-LiDAR转换模块开销评估
时间开销
不需要GPU,CPU计算,但是时间开销波动较大,取决于server是否busy。
mean    0.47
max    3.03
min    0.10

AVOD模块Inference开销评估
硬件开销
物理内存 2.2g  此处没有进行优化
CPU% 1200~1400 对TensorFlow框架进行了线程限制,CPU占用依然很高
显存    满载    目前可以限制显存占用到70%跑通

时间开销
如果是伪雷达点云,则会造成Feed dict 的时长长于64线真实雷达点云。
主要是因为伪雷达点云更密集,但是并不会对模型本身的Inference时长产生影响。


伪雷达点云

雷达点云

Feed dict time

Min

0.47

0.27

Max

2.33

5.08

Mean

1.01

0.68

Inference time

Min

0.10

0.11

Max

7.34

5.77

Mean

0.15

0.16

Total

Mean

1.16

0.84


Inference精度


avod的评价策略是,训练120个模型,每个模型都有个最佳结果,取所有这些最好结果的最好的作为最终模型,刷榜KITTI。
这个最佳结果就是:测试一个模型,根据置信度检测到的框全都列出来,人为选定一个使合适的置信度,使该模型的结果最好。
每个模型在每个照片输出上百个结果,纯雷达数据的最好的结果可以达到论文中的结果。
目前需要评价量化avod的结果。
Step 120000: 3423 / 3769, Inference on sample 007478
Step 120000: Eval RPN Loss: objectness 0.144, regression 0.321, total 0.465
Step 120000: Eval AVOD Loss: classification 0.009, regression 0.000, total 0.474
Step 120000: Eval AVOD Loss: localization 0.000, orientation 0.000
Step 120000: RPN Objectness Accuracy: 0.9765625
Step 120000: AVOD Classification Accuracy: 1.0
Step 120000: Total time 6.95996880531311 s

Step 120000: 3424 / 3769, Inference on sample 007480
Step 120000: Eval RPN Loss: objectness 1.034, regression 0.242, total 1.276
Step 120000: Eval AVOD Loss: classification 0.009, regression 0.000, total 1.285
Step 120000: Eval AVOD Loss: localization 0.000, orientation 0.000
Step 120000: RPN Objectness Accuracy: 0.681640625
Step 120000: AVOD Classification Accuracy: 1.0
Step 120000: Total time 4.422899007797241 s

Step 120000: Average RPN Losses: objectness 0.319, regression 0.385, total 0.704
Step 120000: Average Objectness Accuracy:0.915057886426694 
Step 120000: Average AVOD Losses: cls 0.02275, reg 2.21640, total 2.94283 
Step 120000 Average AVOD Losses: loc 3.79380 ang 0.51566
Step 120000: Average Classification Accuracy: 0.9974780762873082

Ongoing
1 PSMnet的结果不好,需要train
2 avod的CPU开销较大
3 需要量化avod的评价标准,可以使用deepbox的3d iou评价。
4 时间开销较大约为0.4+0.5+1=1.9,很高。
5 pseudo-lidar转换开销测试非常不稳定。