# Orbbec D2C Batch Converter (软件对齐) 将奥比中光相机采集的深度图(Depth)批量软件对齐到彩色图(Color)坐标系,输出与 RGB 分辨率一致的对齐深度图。 --- ## 原理 软件 D2C(Depth-to-Color)对齐流程: ``` 深度像素 (u_d, v_d, Z) ↓ Brown-Conrady 畸变校正 + 反投影 3D 点(深度相机坐标系)[X, Y, Z] ↓ 外参旋转 R + 平移 t 3D 点(彩色相机坐标系)[X_c, Y_c, Z_c] ↓ 彩色内参投影 彩色像素 (u_c, v_c) → 写入对齐深度图 ``` 多个深度点映射到同一彩色像素时,保留最近点(小 Z 值覆盖大 Z 值)。 ### 前向映射的间隙问题与 3×3 Splat 修复 前向映射(forward scatter)存在固有缺陷:每个深度像素只写入 color 平面的**一个像素**。由于深度相机与彩色相机的视角差异,经外参变换 + 透视投影后,相邻深度像素在 color 平面上的落点会出现跳跃,中间留下空洞,输出图像呈现**离散小方块**而非连续深度面。 **修复方案:3×3 邻域扩散(splat)** 对每个投影后的深度像素,同时写入以其为中心的 3×3 邻域,而不是单个像素。遍历顺序仍保持**远→近**,因此当多个 splat 重叠时,Z 值较小(较近)的深度最后写入并覆盖,遮挡关系依然正确: ``` for dv in -1, 0, +1: for du in -1, 0, +1: aligned[v + dv, u + du] = z # 远→近顺序,近处覆盖远处 ``` 如果局部仍有残留空洞(如深度图有效范围边缘),可将 3×3 扩大为 5×5(`range(-2, 3)`)。 --- ## 环境依赖 | 包 | 版本 | |----|------| | Python | 3.8 ~ 3.13 | | pyorbbecsdk | 2.x | | numpy | — | | opencv-python | — | ```bash pip install numpy opencv-python ``` ### 安装 pyorbbecsdk > 官方文档:https://orbbec.github.io/pyorbbecsdk/source/2_installation/install_the_package.html > GitHub:https://github.com/orbbec/pyorbbecsdk **支持平台:** Windows 10 x64 / Ubuntu 18.04·20.04·22.04 x64 / ARM64 #### 方式一:在线安装(推荐) ```bash # Windows / Linux pip install pyorbbecsdk2 ``` > 无论在线(`pyorbbecsdk2`)还是离线安装,最终包目录名均为 `pyorbbecsdk`,`import pyorbbecsdk` 均可正常使用。 #### 方式二:离线安装(.whl) 1. 前往 [Releases](https://github.com/orbbec/pyorbbecsdk/releases) 下载与 Python 版本和平台匹配的 `.whl` 文件 (例:Python 3.11 / Windows → `pyorbbecsdk-2.x.x-cp311-cp311-win_amd64.whl`) 2. 安装: ```bash pip install pyorbbecsdk-2.x.x-cp311-cp311-win_amd64.whl ``` #### 安装后验证 ```bash pip show pyorbbecsdk ``` #### 设备驱动配置 **Windows**(管理员 PowerShell): ```powershell Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser .\obsensor_metadata_win10.ps1 -op install_all ``` **Linux**: ```bash cd pyorbbecsdk/scripts/env_setup sudo chmod +x ./install_udev_rules.sh sudo ./install_udev_rules.sh sudo udevadm control --reload && sudo udevadm trigger ``` --- ## 文件说明 | 文件 | 说明 | |------|------| | `d2c_batch.py` | 主程序 | | `camera_params.json` | 相机参数缓存(自动生成,可复用) | | `utils.py` | 奥比中光 SDK 辅助函数(备用) | --- ## 使用方法 ### 完整流程(首次使用) ```bash python d2c_batch.py ``` 1. 列出相机所有 **RGB 配置**(分辨率 / 帧率 / 格式),输入序号选择 2. 列出所有 **Depth 配置**,输入序号选择 3. 自动启动相机,采集一帧,提取内外参,保存到 `camera_params.json` 4. 输入**深度图目录**路径 5. 批量转换,结果保存到 `<输入目录>_d2c/` ### 仅获取相机参数(不转换) ```bash python d2c_batch.py --params ``` 适合先连相机标定参数,稍后离线转换。 ### 仅批量转换(无需连相机) ```bash python d2c_batch.py --convert ``` 使用已有的 `camera_params.json`,直接输入深度图目录开始转换。适合相机参数已获取、需要反复处理不同数据集的场景。 ### 关闭 3×3 Splat 填充 ```bash python d2c_batch.py --no-splat ``` 默认开启 splat(前向映射后用 3×3 邻域扩散填补间隙)。加 `--no-splat` 可关闭,每个深度像素仅写入 color 平面的单个像素,适合对原始投影结果做对比分析。可与其他参数组合使用: ```bash python d2c_batch.py --convert --no-splat ``` --- ## 交互示例 ``` Found saved camera params: camera_params.json Use existing params? [y=use existing / n=re-fetch from camera]: n === Phase 1: Camera Parameter Acquisition === Available RGB (Color) profiles: # Resolution FPS Format ---------------------------------------- [0 ] 1920x1080 30 MJPG [1 ] 1280x720 30 MJPG [2 ] 640x480 30 RGB Select RGB (Color) profile index: 0 -> Selected: 1920x1080 @ 30fps MJPG Available Depth profiles: # Resolution FPS Format ---------------------------------------- [0 ] 1280x800 30 Y16 [1 ] 640x400 30 Y16 [2 ] 320x200 30 Y16 Select Depth profile index: 1 -> Selected: 640x400 @ 30fps Y16 Starting pipeline... Pipeline stopped. Camera params saved to: camera_params.json --- Camera Parameters Summary --- RGB : 1920x1080 @ 30fps MJPG fx=1382.5 fy=1382.5 cx=959.8 cy=539.4 Depth : 640x400 @ 30fps Y16 fx=424.0 fy=424.0 cx=319.5 cy=199.5 scale=0.001000 mm/unit Extrinsic t : [-14.82 0.12 0.03] (mm) Enter depth images directory: D:\data\depth_raw === Phase 2: Batch D2C Conversion === Input dir : D:\data\depth_raw Output dir : D:\data\depth_raw_d2c Files : 120 Depth scale: 0.001000 mm/unit Output size: 1920x1080 (color resolution) [ 1/120] 000001.png [ 2/120] 000002.png ... [ 120/120] 000120.png Done. 120/120 files converted in 8.3s Results: D:\data\depth_raw_d2c ``` --- ## 输入 / 输出格式 | 项目 | 说明 | |------|------| | 输入深度图 | PNG,uint16,单位为传感器原始单位(乘以 `depth_scale` 得 mm) | | 输出对齐深度图 | PNG,uint16,单位与输入相同,分辨率与所选 RGB 配置一致,目录名 `_d2c` | | 输出伪彩图 | PNG,uint8 BGR,JET colormap,无效像素为纯黑,目录名 `_d2c_vis` | --- ## camera_params.json 格式 ```json { "color": { "width": 1920, "height": 1080, "fps": 30, "format": "MJPG", "intrinsic": { "fx": 1382.5, "fy": 1382.5, "cx": 959.8, "cy": 539.4, "width": 1920, "height": 1080 }, "distortion": { "k1": -0.055, "k2": 0.071, "k3": 0.0, "k4": 0.0, "k5": 0.0, "k6": 0.0, "p1": 0.0, "p2": 0.0 } }, "depth": { "width": 640, "height": 400, "fps": 30, "format": "Y16", "scale": 0.001, "intrinsic": { "fx": 424.0, "fy": 424.0, "cx": 319.5, "cy": 199.5, "width": 640, "height": 400 }, "distortion": { "k1": 0.0, ... } }, "extrinsic": { "rot": [1,0,0, 0,1,0, 0,0,1], "transform": [-14.82, 0.12, 0.03] } } ``` `extrinsic.rot` 为行优先展平的 3×3 旋转矩阵,`extrinsic.transform` 为平移向量(单位 mm),方向为深度相机坐标系 → 彩色相机坐标系。 --- ## 注意事项 - 获取相机参数时需要相机**实际连接**;批量转换时不需要。 - 更换相机或修改分辨率后需重新获取参数(运行时选 `n` 或使用 `--params`)。 - 输入深度图分辨率须与获取参数时选择的 Depth 分辨率一致。 - 对齐深度图的有效区域受深度传感器视场角限制,彩色图边缘区域可能无深度值(值为 0)。