Monodepth2
这是参考的PyTorch实现,用于使用以下方法进行深度估计模型的训练和测试
深入研究自监督的单目深度预测
Clément Godard, Oisin Mac Aodha, Michael Firman 和 Gabriel J. Brostow
此代码仅供非商业用途;请参阅许可证文件以了解条款。
如果您在研究中发现我们的工作有用,请考虑引用我们的论文:
@article{monodepth2,
title = {Digging into Self-Supervised Monocular Depth Prediction},
author = {Cl{\'{e}}ment Godard and
Oisin {Mac Aodha} and
Michael Firman and
Gabriel J. Brostow},
booktitle = {The International Conference on Computer Vision (ICCV)},
month = {October},
year = {2019}
}
⚙️ 设置
假设有一个新的Anaconda发行版,您可以使用以下命令安装依赖项:
conda install pytorch=0.4.1 torchvision=0.2.1 -c pytorch
pip install tensorboardX==1.4
conda install opencv=3.3.1 # 仅用于评估
我们在PyTorch 0.4.1、CUDA 9.1、Python 3.6.6和Ubuntu 18.04上进行了实验。
我们还成功地使用PyTorch 1.0训练了模型,并且我们的代码兼容Python 2.7。如果您使用Python 3.7,可能会在安装OpenCV 3.3.1版本时遇到问题,建议创建一个Python 3.6.6的虚拟环境conda create -n monodepth2 python=3.6.6 anaconda
。
🖼️ 单张图片预测
您可以使用以下命令预测单张图片的缩放视差:
python test_simple.py --image_path assets/test_image.jpg --model_name mono+stereo_640x192
或者,如果您使用的是立体训练的模型,您可以估计度量深度:
python test_simple.py --image_path assets/test_image.jpg --model_name mono+stereo_640x192 --pred_metric_depth
第一次运行上述任一命令时,将会下载预训练的mono+stereo_640x192
模型(99MB)到models/
文件夹中。
我们提供了以下--model_name
选项:
--model_name | 训练模式 | 是否预训练Imagenet | 模型分辨率 | KITTI绝对相对误差 | delta < 1.25 |
---|---|---|---|---|---|
mono_640x192 | 单目 | 是 | 640 x 192 | 0.115 | 0.877 |
stereo_640x192 | 立体 | 是 | 640 x 192 | 0.109 | 0.864 |
mono+stereo_640x192 | 单目+立体 | 是 | 640 x 192 | 0.106 | 0.874 |
mono_1024x320 | 单目 | 是 | 1024 x 320 | 0.115 | 0.879 |
stereo_1024x320 | 立体 | 是 | 1024 x 320 | 0.107 | 0.874 |
mono+stereo_1024x320 | 单目+立体 | 是 | 1024 x 320 | 0.106 | 0.876 |
mono_no_pt_640x192 | 单目 | 否 | 640 x 192 | 0.132 | 0.845 |
stereo_no_pt_640x192 | 立体 | 否 | 640 x 192 | 0.130 | 0.831 |
mono+stereo_no_pt_640x192 | 单目+立体 | 否 | 640 x 192 | 0.127 | 0.836 |
您还可以下载使用单目和单目+立体训练模式在里程计数据集上训练的模型。
最后,我们提供了使用ImageNet预训练权重和从头训练的的resnet 50深度估计模型。
如果使用这些模型,请务必设置--num_layers 50
。
💾 KITTI训练数据
您可以通过运行以下命令下载整个原始KITTI数据集:
wget -i splits/kitti_archives_to_download.txt -P kitti_data/
然后用以下命令解压缩:
cd kitti_data
unzip "*.zip"
cd ..
注意: 该数据集约175GB,因此请确保您有足够的空间来解压缩!
我们的默认设置假定您已使用此命令将png图像转换为jpeg ,这也会删除原始的KITTI .png
文件:
find kitti_data/ -name '*.png' | parallel 'convert -quality 92 -sampling-factor 2x2,1x1,1x1 {.}.png {.}.jpg && rm {}'
或者您可以跳过此转换步骤,并通过在训练时添加--png
选项从原始png文件进行训练,但代价是加载时间较慢。
上述转换命令会生成与我们的实验匹配的图像,其中KITTI .png
图像在Ubuntu 16.04上以默认色度子采样2x2,1x1,1x1
转换为 .jpg
。
我们发现Ubuntu 18.04默认使用2x2,2x2,2x2
,这会导致不同的结果,因此在转换命令中显式参数。
您还可以将KITTI数据集放置在任何位置,并在训练和评估期间使用--data_path
选项指向它。
拆分
训练/测试/验证拆分定义在splits/
文件夹中。
默认情况下,代码将使用Zhou的子集 在KITTI标准Eigen拆分上训练深度模型,该子集设计用于单目训练。
您还可以通过设置--split
选项来使用新的基准拆分 或里程计拆分 进行模型训练。
自定义数据集
您可以通过编写继承自MonoDataset
的新的数据加载类在自定义单目或立体数据集上进行训练 - 请参阅datasets/kitti_dataset.py
中的 KITTIDataset
类以获取示例。
⏳ 训练
默认情况下,模型和tensorboard事件文件保存到~/tmp/<model_name>
。
您可以通过--log_dir
选项更改。
单目训练:
python train.py --model_name mono_model
立体训练:
我们的代码默认为使用Zhou的子采样Eigen训练数据。对于立体训练,我们必须指定使用完整的Eigen训练集 – 请参阅论文了解详细信息。
python train.py --model_name stereo_model \
--frame_ids 0 --use_stereo --split eigen_full
单目 + 立体训练:
python train.py --model_name mono+stereo_model \
--frame_ids 0 -1 1 --use_stereo
GPU
代码只能运行在单个GPU上。
您可以使用 CUDA_VISIBLE_DEVICES
环境变量指定使用哪个GPU:
CUDA_VISIBLE_DEVICES=2 python train.py --model_name mono_model
我们所有的实验都是在单个NVIDIA Titan Xp上进行的。
训练模式 | 大约GPU内存 | 大约训练时间 |
---|---|---|
单目 | 9GB | 12小时 |
立体 | 6GB | 8小时 |
单目+立体 | 11GB | 15小时 |
💽 微调预训练模型
在训练命令中添加以下内容以加载现有模型进行微调:
python train.py --model_name finetuned_mono --load_weights_folder ~/tmp/mono_model/models/weights_19
🔧 其他训练选项
运行 python train.py -h
(或查看 options.py
)以查看其他训练选项范围,例如学习率和消融设置。
📊 KITTI 评估
为了准备地面真实深度图,运行:
python export_gt_depth.py --data_path kitti_data --split eigen
python export_gt_depth.py --data_path kitti_data --split eigen_benchmark
假设您已将KITTI数据集放置在默认位置 ./kitti_data/
。
以下示例命令评估名为 mono_model
的模型的第19轮权重:
python evaluate_depth.py --load_weights_folder ~/tmp/mono_model/models/weights_19/ --eval_mono
对于立体模型,您必须使用 --eval_stereo
标志(请参阅以下注释):
python evaluate_depth.py --load_weights_folder ~/tmp/stereo_model/models/weights_19/ --eval_stereo
如果您使用我们的代码训练自己的模型,由于权重初始化和数据加载中的随机化,您可能会看到与发布结果有轻微差异。
可以设置额外参数 --eval_split
。
这里解释了 eval_split
的三种不同可能值:
--eval_split | 测试集大小 | 使用...训练的模型 | 描述 |
---|---|---|---|
eigen | 697 | --split eigen_zhou (默认) 或 --split eigen_full | 标准的Eigen测试文件 |
eigen_benchmark | 652 | --split eigen_zhou (默认) 或 --split eigen_full | 用来自new KITTI深度基准的改进的地面真实评估 |
benchmark | 500 | --split benchmark | new KITTI深度基准测试文件 |
由于new KITTI深度基准没有可用的地面真实数据,当设置 --eval_split benchmark
时不会报告任何分数。
相反,一组 .png
图片将被保存到磁盘,准备上传到评估服务器。
外部视差评估
最后,您还可以使用 evaluate_depth.py
评估其他方法的原始视差(或逆深度),使用 --ext_disp_to_eval
标志:
python evaluate_depth.py --ext_disp_to_eval ~/other_method_disp.npy
📷📷 关于立体评估的注释
我们的立体模型用有效基线 0.1
单位进行训练,而实际的KITTI立体装置基线为 0.54m
。这意味着评估时必须应用一个 5.4
的缩放比例。
另外,对于使用立体监督训练的模型,我们禁用了中值缩放。
在评估时设置 --eval_stereo
标志将自动禁用中值缩放并将预测深度按 5.4
缩放。
⤴️⤵️ 里程评估
我们提供了用于评估使用 --split odom --dataset kitti_odom --data_path /path/to/kitti/odometry/dataset
训练模型预测的姿态的代码。
对于此评估,必须下载 KITTI里程数据集 (彩色,65GB) 和 地面真实姿态 zip 文件。 如上所述,我们假定png已经转换为jpg。
如果这些数据已解压到文件夹 kitti_odom
,可以评估一个模型:
python evaluate_pose.py --eval_split odom_9 --load_weights_folder ./odom_split.M/models/weights_29 --data_path kitti_odom/
python evaluate_pose.py --eval_split odom_10 --load_weights_folder ./odom_split.M/models/weights_29 --data_path kitti_odom/
📦 预计算结果
您可以从以下链接下载我们预计算的视差预测:
训练模式 | 输入大小 | .npy 文件大小 | Eigen视差 |
---|---|---|---|
单目 | 640 x 192 | 343 MB | 下载 🔗 |
立体 | 640 x 192 | 343 MB | 下载 🔗 |
单目+立体 | 640 x 192 | 343 MB | 下载 🔗 |
单目 | 1024 x 320 | 914 MB | 下载 🔗 |
立体 | 1024 x 320 | 914 MB | 下载 🔗 |
单目+立体 | 1024 x 320 | 914 MB | 下载 🔗 |
👩⚖️ 许可证
版权所有 © Niantic, Inc. 2019. 专利待批。 保留所有权利。 请参见 许可证文件 了解具体条款。