【小白深度教程 1.22】手把手教你使用 Open3D(5)对彩色点云数据进行配准
对 RGBD 数据进行集成(Marching Cubes)_open3d rgbd-CSDN博客_files/92d19ef909634086971f61aa88cfd52d.png)
1. RGBD 集成的概念
Open3D 实现了可扩展的 RGBD 图像集成算法。该算法基于 Curless1996 和 Newcombe2011 提出的技术。为了支持大场景,我们使用了在 ElasticReconstruction Integrater 中引入的分层哈希结构。
2. 从 .log 文件读取轨迹
本教程使用 read_trajectory 函数从 .log 文件中读取相机轨迹。以下是一个示例 .log 文件。
# examples/test_data/RGBD/odometry.log
0 0 1
1 0 0 2
0 1 0 2
0 0 1 -0.3
0 0 0 1
1 1 2
0.999988 3.08668e-005 0.0049181 1.99962
-8.84184e-005 0.999932 0.0117022 1.97704
-0.0049174 -0.0117024 0.999919 -0.300486
0 0 0 1
class CameraPose:
def __init__(self, meta, mat):
self.metadata = meta
self.pose = mat
def __str__(self):
return 'Metadata : ' + ' '.join(map(str, self.metadata)) + '\n' + \
"Pose : " + "\n" + np.array_str(self.pose)
def read_trajectory(filename):
traj = []
with open(filename, 'r') as f:
metastr = f.readline()
while metastr:
metadata = list(map(int, metastr.split()))
mat = np.zeros(shape=(4, 4))
for i in range(4):
matstr = f.readline()
mat[i, :] = np.fromstring(matstr, dtype=float, sep=' \t')
traj.append(CameraPose(metadata, mat))
metastr = f.readline()
return traj
camera_poses = read_trajectory("../../test_data/RGBD/odometry.log")
3. TSDF 体积集成
Open3D 提供了两种类型的 TSDF 体积:UniformTSDFVolume 和 ScalableTSDFVolume。推荐使用后者,因为它采用分层结构,从而支持更大的场景。
ScalableTSDFVolume 有多个参数。例如,voxel_length = 4.0 / 512.0 表示 TSDF 体积的单个体素大小为 4.0 m 512.0 = 7.8125 m m \frac{4.0m}{512.0} = 7.8125mm 512.04.0m=7.8125mm。降低该值可以生成高分辨率的 TSDF 体积,但集成结果可能对深度噪声敏感。sdf_trunc = 0.04 指定了符号距离函数 (SDF) 的截断值。
当 color_type = TSDFVolumeColorType.RGB8 时,8 位 RGB 颜色也会作为 TSDF 体积的一部分进行集成。浮点类型的强度可以通过 color_type = TSDFVolumeColorType.Gray32 和 convert_rgb_to_intensity = True 集成。颜色集成的灵感来自 PCL。
volume = o3d.pipelines.integration.ScalableTSDFVolume(
voxel_length=4.0 / 512.0,
sdf_trunc=0.04,
color_type=o3d.pipelines.integration.TSDFVolumeColorType.RGB8)
for i in range(len(camera_poses)):
print("Integrate {:d}-th image into the volume.".format(i))
color = o3d.io.read_image("../../test_data/RGBD/color/{:05d}.jpg".format(i))
depth = o3d.io.read_image("../../test_data/RGBD/depth/{:05d}.png".format(i))
rgbd = o3d.geometry.RGBDImage.create_from_color_and_depth(
color, depth, depth_trunc=4.0, convert_rgb_to_intensity=False)
volume.integrate(
rgbd,
o3d.camera.PinholeCameraIntrinsic(
o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault),
np.linalg.inv(camera_poses[i].pose))
4. 提取网格
网格提取使用经典的 Marching Cubes 算法 LorensenAndCline1987。
print("Extract a triangle mesh from the volume and visualize it.")
mesh = volume.extract_triangle_mesh()
mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh],
front=[0.5297, -0.1873, -0.8272],
lookat=[2.0712, 2.0312, 1.7251],
up=[-0.0558, -0.9809, 0.1864],
zoom=0.47)
对 RGBD 数据进行集成(Marching Cubes)_open3d rgbd-CSDN博客_files/68fe1777a7f14ab289d2275cf08494c0.png)
144
被折叠的
条评论
为什么被折叠?
对 RGBD 数据进行集成(Marching Cubes)_open3d rgbd-CSDN博客_files/weixin.png)
对 RGBD 数据进行集成(Marching Cubes)_open3d rgbd-CSDN博客_files/zhifubao.png)
对 RGBD 数据进行集成(Marching Cubes)_open3d rgbd-CSDN博客_files/jingdong.png)
对 RGBD 数据进行集成(Marching Cubes)_open3d rgbd-CSDN博客_files/recharge.png)