RGBD测程法是去寻找两个连续的RGBD图像对之间的相机移动。它的输入是一对RGBImage的实例,输出是刚体变换形式的运动。Open3D实现了 [Steinbrucker2011] and [Park2017]中的方法。
读取相机内参
我们首先从json文件中读取相机内参。
# -*- coding:utf-8 -*-
import numpy as np
import open3d as o3d
import Open3D.examples.python.open3d_tutorial as o3dtut
pinhole_camera_intrinsic = o3d.io.read_pinhole_camera_intrinsic(
"../../test_data/camera_primesense.json")
print(pinhole_camera_intrinsic.intrinsic_matrix)
[[525. 0. 319.5]
[ 0. 525. 239.5]
[ 0. 0. 1. ]]
注意:
Open3d 中许多小的数据结构都能够通过json文件来读写。包括相机参数,相机轨迹,姿态图等等。
读取RGBD图像
这个代码块是中读取两对Redwood格式的RGBD图像。我们提供了Redwood数据集的解释(在前一节有介绍)。
source_color = o3d.io.read_image("../../test_data/RGBD/color/00000.jpg")
source_depth = o3d.io.read_image("../../test_data/RGBD/depth/00000.png")
target_color = o3d.io.read_image("../../test_data/RGBD/color/00001.jpg")
target_depth = o3d.io.read_image("../../test_data/RGBD/depth/00001.png")
source_rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(source_color, source_depth)
target_rgbd_image = o3d.geometry.RGBDImage.create_from_color_and_depth(target_color, target_depth)
target_pcd = o3d.geometry.PointCloud.create_from_rgbd_image(target_rgbd_image, pinhole_camera_intrinsic)
注意:
Open3D假设彩色图像和深度图像是同步的,并且在同一坐标系下配准。这通常可以在RGBD相机中通过打开同步和配准设置来实现。
从一对RGBD图像中计算里程
option = o3d.pipelines.odometry.OdometryOption()
odo_init = np.identity(4)
print(option)
[success_color_term, trans_color_term,info] = o3d.pipelines.odometry.compute_rgbd_odometry(
source_rgbd_image, target_rgbd_image, pinhole_camera_intrinsic, odo_init,
o3d.pipelines.odometry.RGBDOdometryJacobianFromColorTerm(), option)
[success_hybrid_term, trans_hybrid_term,info] = o3d.pipelines.odometry.compute_rgbd_odometry(
source_rgbd_image, target_rgbd_image, pinhole_camera_intrinsic, odo_init,
o3d.pipelines.odometry.RGBDOdometryJacobianFromHybridTerm(), option)
odometry::OdometryOption class.
iteration_number_per_pyramid_level = [ 20, 10, 5, ]
max_depth_diff = 0.030000
min_depth = 0.000000
max_depth = 4.000000
这个代码块调用两种不同的RGBD测程方法。第一种来自[Steinbrucker2011].它是去最小化对齐图片的颜色一致性。第二种算法来自[Park2017]。除了颜色一致性以外,它还实现了几何约束。这两种方法运行速度接近。但是[Park2017]在我们的基准数据集中有着更高的精度,所以我们推荐使用。
OdometryOption()有几个参数:
- minimum_correspondence_ratio:对齐后,测量两张RGBD图像的重叠比率。如果两组RGBD图像的重叠区域小于指定的比例,则测程模块会认为这是失效的情况。
- max_depth_diff:在深度图像中,如果两个对齐的像素的深度差异是小于一个值的,则认为它们是对应的。值越大,搜索越激进,但是结果越不容易稳定。
- min_depth 和 max_depth:大于或小于指定深度的像素会被忽略。
可视化RGBD图像对
将RGBD图像对转换成点云并且一起渲染。要注意的是,第一个(源)RGBD图像是通过测程法估计出的变换来进行变换的。经过变化之后的两组点云是对齐的。
if success_color_term:
print("Using RGB-D Odometry")
print(trans_color_term)
source_pcd_color_term = o3d.geometry.PointCloud.create_from_rgbd_image(
source_rgbd_image, pinhole_camera_intrinsic)
source_pcd_color_term.transform(trans_color_term)
o3d.visualization.draw_geometries([target_pcd, source_pcd_color_term],
zoom=0.48,
front=[0.0999, -0.1787, -0.9788],
lookat=[0.0345, -0.0937, 1.8033],
up=[-0.0067, -0.9838, 0.1790])
if success_hybrid_term:
print("Using Hybrid RGB-D Odometry")
print(trans_hybrid_term)
source_pcd_hybrid_term = o3d.geometry.PointCloud.create_from_rgbd_image(
source_rgbd_image, pinhole_camera_intrinsic)
source_pcd_hybrid_term.transform(trans_hybrid_term)
o3d.visualization.draw_geometries([target_pcd, source_pcd_hybrid_term],
zoom=0.48,
front=[0.0999, -0.1787, -0.9788],
lookat=[0.0345, -0.0937, 1.8033],
up=[-0.0067, -0.9838, 0.1790])
Using RGB-D Odometry
[[ 9.99988286e-01 -7.53983409e-05 -4.83963172e-03 2.74054550e-04]
[ 1.83909052e-05 9.99930634e-01 -1.17782559e-02 2.29634918e-02]
[ 4.84018408e-03 1.17780289e-02 9.99918922e-01 6.02121265e-04]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
Using Hybrid RGB-D Odometry
[[ 9.99992973e-01 -2.51084541e-04 -3.74035273e-03 -1.07049775e-03]
[ 2.07046059e-04 9.99930714e-01 -1.17696227e-02 2.32280983e-02]
[ 3.74304875e-03 1.17687656e-02 9.99923740e-01 1.40592054e-03]
[ 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00]]