self-supervised-depth-completion数据管道全解析:KITTI数据集结构、相机标定与16位深度PNG读取
self-supervised-depth-completion数据管道全解析KITTI数据集结构、相机标定与16位深度PNG读取【免费下载链接】self-supervised-depth-completionICRA 2019 Self-supervised Sparse-to-Dense: Self-supervised Depth Completion from LiDAR and Monocular Camera项目地址: https://gitcode.com/gh_mirrors/se/self-supervised-depth-completionself-supervised-depth-completion 是 MIT 团队发表于 ICRA 2019 的自监督深度补全Self-supervised Sparse-to-Dense项目的 PyTorch 官方实现只用稀疏 LiDAR 点云加单目相机图像无需稠密深度标注就能训练出密集深度图。而这一切的地基就是它的数据管道——本文带你完整读懂 KITTI 数据集结构、相机标定文件的用法以及最容易踩坑的16 位深度 PNG 读取技巧帮你快速上手这套深度补全训练流程。一、项目与代码获取一分钟了解背景 这套代码在仅使用 KITTI 数据集的情况下完成了深度补全训练没有用 Cityscapes 等其他驾驶数据集做预训练。核心模块分工如下模块文件职责数据集加载dataloaders/kitti_loader.pyKITTI 数据读取、路径组织、图像/深度解码相机标定dataloaders/calib_cam_to_cam.txtKITTI 标定原始文件解析出内参矩阵数据变换dataloaders/transforms.py裁剪、翻转、色彩抖动等增强位姿估计dataloaders/pose_estimator.pySIFT 特征匹配 PnP 求解相机位姿训练入口main.py命令行参数、损失组合、训练主循环如需本地复现可直接克隆仓库git clone https://gitcode.com/gh_mirrors/se/self-supervised-depth-completion二、KITTI 数据集结构深度补全的“原料库” 数据准备分两步先从 KITTI 官网下载 Depth Completion 评测基准含 Velodyne 稀疏深度与半稠密标注再运行仓库自带的脚本抽取对应帧的 RGB 图像./download/rgb_train_downloader.sh # 抽取训练集 RGB ./download/rgb_val_downloader.sh # 抽取验证集 RGB两个脚本的工作逻辑非常巧妙从 KITTI 原始云端下载*_sync.zip压缩包解压后只保留image_02/image_03灰度相机目录删掉立体相机image_00、image_01、激光雷达点云和 IMU 文件以节省空间最终存入../data/data_rgb。训练与验证序列在脚本里通过注释开关显式指定保证了训练/验证严格不重叠。整理后的完整目录结构如下. ├── self-supervised-depth-completion # 代码主目录 ├── data | ├── data_depth_annotated # 半稠密真值标注 | | ├── train | | ├── val | ├── data_depth_velodyne # 稀疏 LiDAR 深度投影到相机图像 | | ├── train | | ├── val | ├── depth_selection # 评测用选帧 | | ├── test_depth_completion_anonymous | | ├── test_depth_prediction_anonymous | | └── val_selection_cropped | └── data_rgb # 下载脚本抽取的 RGB 图像 | | ├── train | | └── val └── results # 训练输出代码中通过 glob 模式把三类文件对齐见dataloaders/kitti_loader.py的get_paths_and_transform稀疏深度data_depth_velodyne/{train,val}/*_sync/proj_depth/velodyne_raw/image_0[2,3]/*.png稠密真值data_depth_annotated/{train,val}/*_sync/proj_depth/groundtruth/image_0[2,3]/*.pngRGB 图像按同样目录约定从data_rgb映射生成其中image_0[2,3]这个写法表示同时支持灰度相机的 02/03 两个子目录0[2,3]也是为什么image_00/image_01可以安全删除的原因。数据加载器还会做长度一致性校验任何一类文件缺失都会直接抛出明确的RuntimeError方便你定位是漏下载了哪一类数据。三、相机标定解析从 calib 文件到内参矩阵 自监督训练中的光度损失photometric loss依赖精确的相机内参而内参来自dataloaders/calib_cam_to_cam.txt——这是 KITTI 2011-09-26 校准日的原始标定文件。dataloaders/kitti_loader.py的load_calib()第 18–39 行只取文件中P_rect_02一行P_rect_02: 721.5377 0 609.5593 44.85728 0 721.5377 172.8540 2.163791 ...这是 3×4 的投影矩阵P K [R|t]取左上 3×3 就是内参矩阵 K焦距fx fy ≈ 721.54主点cx ≈ 609.56、cy ≈ 172.85。容易忽略的细节KITTI 原图尺寸为 1242×375而训练时要做中心裁剪到 1216×352裁剪会移动光心但焦距不变所以代码对手动做了补偿K[0,2] - 13宽度两侧各裁 13 像素1242 → 1216K[1,2] - 11.5高度两侧各裁 11.5 像素375 → 352这个补偿值必须和BottomCrop的输出尺寸oheight, owidth 352, 1216严格对应改输出尺寸时记得同步修改。main.py中用同一份load_calib()构造Intrinsics(owidth, oheight, fu, fv, cu, cv)供inverse_warp.py做多尺度逆投影。四、16 位深度 PNG 读取为什么深度值要除以 256 这是整个数据管道里最容易出错的一步。KITTI 的深度图是 16 位uint16PNG存储约定为像素值 深度米× 256即 1 米 256 个计数读取逻辑在kitti_loader.py的depth_read()第 148–163 行核心只有三句depth_png np.array(img_file, dtypeint) # 按整数读避免精度丢失 assert np.max(depth_png) 255 # 校验确认是 16bit 而非 8bit depth depth_png.astype(np.float) / 256. # 计数 → 米要点归纳先断言最大值 255如果文件被某些看图软件转存成 8 位 PNG断言会直接失败提醒你文件已损坏。除以 256 而不是 255KITTI 的 16 位深度用的是米 × 256编码与图像亮度归一化/255不同两者千万别混。零值 无测量depth 0的像素表示 LiDAR 没有打到点后续损失计算中会用mask (d 1e-3)把这些位置剔除只在有真值的像素上算监督。读取后通过np.expand_dims(depth, -1)补上通道维变成(H, W, 1)以便和 RGB 的(H, W, 3)走同一套变换管线。与之对应的rgb_read()则按uint8读取保持在 [0, 255] 整数范围。五、数据增强BottomCrop、随机翻转与色彩抖动 ️增强逻辑在train_transform()中组合完成不同 split 使用不同策略变换训练集验证集full评测select/testBottomCrop((352, 1216))✅ 垂直取底 水平居中✅❌ 原尺寸水平随机翻转概率 0.5✅❌❌色彩抖动亮度/对比度/饱和度 ±--jitter默认 0.1✅ 仅作用于 RGB❌❌几个值得注意的设计几何变换对 RGB、稀疏深度、真值同步生效保证像素严格对齐翻转时 RGB 与深度一起np.fliplr不会出现错位。色彩抖动只加在 RGB 上这正是光度自监督训练想要的让网络学会忽略光照变化。裁剪放在图像底部驾驶场景中地面占据画面下半部分保留底部能让深度密集区尽量留在视野内。dataloaders/transforms.py是 torchvision 变换风格的定制版Compose/ToTensor等把(H, W, C)转成(C, H, W)的张量。六、自监督关键一步邻帧采样与 PnP 位姿估计 训练模式中只要包含photo光度损失main.py就会置args.use_pose True此时数据管道额外做两件事随机抓邻帧get_rgb_near()从当前帧号 ±3 内随机挑一个存在的近邻帧作为rgb_near供逆投影做光度对齐。无 GT 位姿估计dataloaders/pose_estimator.py的get_pose_pnp()用 SIFT 特征匹配两帧灰度图再借助当前帧稀疏深度把匹配点反投影为 3D 点convert_2d_to_3d最后用cv2.solvePnPRansac解出旋转/平移。为缓解稀疏点覆盖不足会先对深度图做 4×4 膨胀。健壮性设计若 PnP 失败或平移量小于0.1米说明两帧几乎没动光度约束无意义数据加载器会退化为邻帧 当前帧、零位移、单位旋转保证训练不中断。这套机制让自监督训练完全绕开了 KITTI 的 odometry GT。七、接入训练main.py 中的数据流 ⚙️main.py用KittiDepth(train, args)与KittiDepth(val, args)构建数据集再包进DataLoader默认 4 个 worker、pin_memoryTrue。命令行用--input选择输入组合d/rgb/rgbd/g/gd--train-mode选择监督方式python main.py --train-mode dense -b 1 --input rgbd # 半稠密标注监督 python main.py --train-mode sparsephoto # 纯自监督 python main.py --evaluate [checkpoint-path] --val select每个样本最终是一个字典按需包含rgb、d稀疏深度、gt稠密真值、g灰度、r_mat/t_vec位姿、rgb_near等键训练循环里再按--train-mode组合三种损失深度监督损失MaskedMSELoss 加权光度损失 平滑损失权重由args.w1/w2控制。八、常见报错排查清单 ✅按数据管道出问题的频率排序np.max(depth_png)255, path...断言失败→ 深度 PNG 被转成了 8 位请重新从 KITTI 原始包提取勿经修图软件。Found 0 images under ...→--data-folder默认../data下缺少data_depth_velodyne或data_depth_annotated或没跑下载脚本。Requested sparse depth but none was found→--input含d但稀疏深度目录为空检查是否误删了velodyne_raw。Requested rgb images but none was found→data_rgb未生成运行download/rgb_train_downloader.sh与download/rgb_val_downloader.sh。Produced different sizes for datasets→ 三类文件数量对不上通常是部分序列下载失败重新跑对应下载脚本。光度损失异常大/训练不稳→ 检查输出尺寸是否为 352×1216标定补偿13 / 11.5 像素必须与裁剪尺寸匹配。总结self-supervised-depth-completion 的数据管道可以用一句话概括用 glob 对齐稀疏深度—稠密真值—RGB三类文件用P_rect_02内参加裁剪补偿标定相机用×256编码读取 16 位深度 PNG再用几何/色彩增强与 PnP 邻帧位姿估计把 KITTI 原始数据喂给光度自监督训练。读懂dataloaders/kitti_loader.py一个文件基本就掌握了 80% 的数据细节剩下 20% 在dataloaders/transforms.py与dataloaders/pose_estimator.py中。建议对照本文的报错清单逐项检查你的数据目录跑通训练通常只隔一层窗户纸。【免费下载链接】self-supervised-depth-completionICRA 2019 Self-supervised Sparse-to-Dense: Self-supervised Depth Completion from LiDAR and Monocular Camera项目地址: https://gitcode.com/gh_mirrors/se/self-supervised-depth-completion创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考