TSDF截断符号距离
TSDF:截断符号距离函数
如何从零学习基于 TSDF 的三维重建? - Merce的回答 - 知乎
https://www.zhihu.com/question/486921125/answer/2406613708
1 概念定义
截断符号距离函数(Truncated Signed Distance Function,简称TSDF)是一种用于表示三维空间中物体表面的数据结构。它将空间划分为一个规则的体素网格,并为每个体素存储一个有符号距离值。这个距离值表示该体素中心到物体表面的距离。在物体表面内部的体素具有负值,而在物体表面外部的体素具有正值。为了减少存储和计算的开销,TSDF通常会对距离值进行截断,即只存储距离物体表面一定范围内的体素的距离值。
2 TSDF用途:
- 三维重建:TSDF常用于从多视角的深度图像重建三维模型。通过将来自不同视角的深度信息融合到一个统一的TSDF表示中,可以生成一个完整且连续的三维模型。
- 表面提取:TSDF可以用于提取物体表面的三维网格模型。通过在TSDF中找到距离值为零的体素,可以得到物体表面的一个近似表示。常用的算法有Marching Cubes算法。
- 机器人导航和避障:TSDF可以用于表示环境中的障碍物,从而帮助机器人进行导航和避障。
TSDF 算法的特点
(1) 计算简单,没有复杂的计算,但是需要大量的并行,需要比较大显存的显卡。
(2) TSDF 生成的网格的细节保持比较好,但是在边缘处以及前后景交界处,会出现较大的拖尾现象。因为在体素p向像素坐标系投影时会有一定的误差.
(3) TSDF占据非常大的显存空间,适合诸如室内环境的小场景三维重建。
3 TSDF 实现方法
TSDF的实现通过包括以下几个步骤:
- 从深度图像计算点云:首先,将深度图像转换为点云表示,即每个像素对应一个三维空间中的点。
- 融合多视角的点云:将来自不同视角的点云融合到一个统一的坐标系中。这通常需要估计相机的位姿(位置和方向)。
- 构建TSDF:将融合后的点云数据映射到一个规则的体素网格中,并为每个体素计算有符号距离值。这通常需要对距离值进行截断,以减少存储和计算的开销。
- 表面提取(可选):如果需要提取物体表面的三维网格模型,可以使用如Marching Cubes等算法在TSDF中找到距离值为零的体素。
TSDF思路很朴素,用一个大的空间包围盒(volume)去包括进去待3D构建的场景,volume成多个voxel(小立体方块):
如何计算tsdf?假设已经从深度相机获得多帧RGBD图像以及相机的位姿T。
左图中灰色小方格表示体素voxel,蓝色三角性表示视场,绿色线为截面对应的线。
第一步:计算体素 在世界坐标系下的坐标。记体素 在TSDF地图上得坐标为 。则该体素在世界坐标系下的位置为:
;
第二步:计算体素在相机坐标系下的坐标。相机的旋转为 平移为 ,则
则 ;
第三步:根据相机内参 计算体素在相机坐标系下 向深度:
;
第四步:重投影计算沿光心经过体素 到达物体表面 点对应的向深度:因为RGBD的信息已经知道,所以根据 可以直接查到 p 的深度值 depth(pic(x));
第五步:得到sdf:
第六步:截断: 即将sdf截断在[-t, t]内,sdf超过这个范围的voxel点不用计算,直接得1或者-1。
TSDF就非常直观了,只需要将像素点中距离绝对值大于1的值截断到1即可。然后提取绝对值最接近0的像素点进行连接即可生成图像轮廓.
第七步:将当前帧得到的值合并到已有的volume。通过将多帧合并成一个TSDF,既可以提升精度又可以补全单帧缺失的信息。。
$TSDFi(x) = \frac{W_{i−1}(x)TSDF_{i−1}(x) + w_{i}(x)tsdf_{i}(x)} {W_{i−1}(x) + w_{i}(x)} $
$W_{i}(x) = W_{i−1}(x) + w_{i}(x) $
对于需要更新的voxel wi(x)=1,没在当前视场内的点为0。
最后:重复遍历所有帧,得到合并后的TSDF。
TSDF也有不少改进值,例如权重是可以由光心到x的入射角度余弦值计算得到;也有适合慢速移动场景的TSDF++等等,在实践中,根据需要去选择。
并行化考虑:
非常适合并行化操作。