亲测代码程序可运行使用,open3d版本0.13.0。
open3d数据资源下载:GitHub - Cobotic/Open3D: Open3D: A Modern Library for 3D Data Processing
代码执行功能有:从 .log 文件中读取轨迹、TSDF空间融合(TSDF volume integration)、抽取网格,详情请见代码。
'''
Author: dongcidaci
Date: 2021-09-14 13:29:07
LastEditTime: 2021-09-14 13:34:29
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath: \open3d_code\2_05_RGBDronghe.py
'''
import open3d as o3d
import numpy as np
import copy
#RGBD融合
#TSDF算法
#从 .log 文件中读取轨迹
#该教程使用函数 read_trajectory从 .log 文件中读取相机轨迹。
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")
#TSDF空间融合(TSDF volume integration)
#Open3d提供了两种类型的TSDF空间:UniformTSDFVolume和ScalableTSDFVolume。推荐使用后一种的原因是因为使用了多层结构支持大尺度场景.
#ScalableTSDFVolume有几个参数。voxel_length = 4.0 / 512.0表示TSDF空间中单个体素尺度是 4.0 m /512.0 = 7.8125 m m
#减小这个值会得到高分辨率的TSDF空间,但是整合结果容易受到深度噪声的影响。
# sdf_trunc = 0.04指定符号距离函数(signed distance function ,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))
#抽取网格
#使用 [LorensenAndCline1987]中提出的marching cubes 算法进行网格绘制.
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)
#注意:TSDF空间就像3D空间中的加权平均过滤器.如果有更多的帧被整合,那么空间就会产生更加平滑的网格.