Open3D是一个开源库,支持快速开发和处理3D数据。Open3D在c++和Python中公开了一组精心选择的数据结构和算法。后端是高度优化的,并且是为并行化而设置的。
本系列学习计划有Blue同学作为发起人,主要以Open3D官方网站的教程为主进行翻译与实践的学习计划。点云PCL公众号作为免费的3D视觉,点云交流社区,期待有使用Open3D或者感兴趣的小伙伴能够加入我们的翻译计划,贡献免费交流社区,为使用Open3D提供中文的使用教程。
ps:感觉这章名字应该叫通过RGBD数据生成网格,关于这章的内容建议大家去百度搜一下关于TSDF算法的博客,或者直接看下面给出的参考论文,有助于大家理解)
Open3d实现了一种可扩展的RGBD图像融合算法。这个算法基于[Curless1996] 和[Newcombe2011] 提出的技术。为了支持大尺度的场景,我们使用了Integrater in ElasticReconstruction.中介绍的分层哈希结构。
从 .log 文件中读取轨迹
该教程使用函数 read_trajectory从 .log 文件中读取相机轨迹。一个示例 .log文件如下:
# examples/TestData/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("../../TestData/RGBD/odometry.log")
TSDF空间融合(TSDF volume integration)
Open3d提供了两种类型的TSDF空间:UniformTSDFVolume和ScalableTSDFVolume。推荐使用后一种的原因是因为使用了多层结构支持大尺度场景.
ScalableTSDFVolume有几个参数。
voxel_length = 4.0 / 512.0 表示TSDF空间中单个体素尺度是 4.0m/512.0 = 7.8125 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.integration.ScalableTSDFVolume(
voxel_length=4.0 / 512.0,
sdf_trunc=0.04,
color_type=o3d.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(
"../../TestData/RGBD/color/{:05d}.jpg".format(i))
depth = o3d.io.read_image(
"../../TestData/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))
Integrate 0-th image into the volume.
Integrate 1-th image into the volume.
Integrate 2-th image into the volume.
Integrate 3-th image into the volume.
Integrate 4-th image into the volume.
抽取网格
使用 [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)
Note:
TSDF空间就像3D空间中的加权平均过滤器.如果有更多的帧被整合,那么空间就会产生更加平滑的网格.请去 Make fragments 中查看更多的例子.
资源
三维点云论文及相关应用分享
【点云论文速读】基于激光雷达的里程计及3D点云地图中的定位方法
3D-MiniNet: 从点云中学习2D表示以实现快速有效的3D LIDAR语义分割(2020)
PCL中outofcore模块---基于核外八叉树的大规模点云的显示
更多文章可查看:点云学习历史文章大汇总
SLAM及AR相关分享
往期线上分享录播汇总
点云PCL更多活动请查看:点云PCL活动之应届生校招群
扫描下方微信视频号二维码可查看最新研究成果及相关开源方案的演示:
如果你对Open3D感兴趣,或者正在使用该开源方案,就请加入我们,一起翻译,一起学习,贡献自己的力量,目前阶段主要以微信群为主,有意者发送“Open3D学习计划”到公众号后台,和更多热爱分享的小伙伴一起交流吧!如果翻译的有什么问题或者您有更好的意见,请评论交流!!!!
以上内容如有错误请留言评论,欢迎指正交流。如有侵权,请联系删除
扫描二维码
关注我们
让我们一起分享一起学习吧!期待有想法,乐于分享的小伙伴加入免费星球注入爱分享的新鲜活力。分享的主题包含但不限于三维视觉,点云,高精地图,自动驾驶,以及机器人等相关的领域。
分享及合作:微信“920177957”(需要按要求备注) 联系邮箱:dianyunpcl@163.com,欢迎企业来联系公众号展开合作。
点一下“在看”你会更好看耶