what is KinectFusion
kinectfusion是微软研究院利用kinect进行三维重建的项目,深入了解该算法及其实现可以为3D重建的kinect类应用提供一定的参考。该项目本身需要比较强大的CUDA显卡支持实现实时重建。
相应的开源版本可以使用KinFu,其下载地址在http://pointclouds.org/downloads/
How KinectFusion Works
KinectFusion重建的基本流程是(according to 《Real-time 3D Reconstruction and interaction Using a Moving Depth Camera》)
- Depth Map Conversion
- Camera Tracking
- Volumetric Integration
- Raycasting
接下来,我们详细地说说这几步
pre-work
在进行下面的处理处理之前,kinectFusion实际还对原始的深度信息进行了一定的降噪平滑,采用双边滤波(Bilateral filtering),在保留边缘的基础上进行平滑,是个可以接受的选择。
Depth Map Conversion
主要是求出有原先的图像点u=(x,y),以及深度值D(u),求得每个点的法向量n(u)。根据相机的内部矩阵,将图像2D坐标转化为相机原点坐标系的3D点。
Camera Tracking
此步骤用ICP(iterative closest point)算法,求解出相机每次的相对位移与转动。相机位置可以用来将相机原点坐标系的结果转化到世界坐标系。
采用的基本算法根据这篇paper的研究《S. Rusinkiewicz and M. Levoy. Efficient variants of the
ICP algorithm. 3D Digital Imaging and Modeling, Int.
Conf. on, 0:145, 2001.》
其cuda算法实现如下
详细的介绍可以参考http://blog.youkuaiyun.com/viewcode/article/details/8426846 中关于fasticp的介绍。
每次迭代的基本思路就是:
- 筛选:点集或曲面的筛选(滤波)
- 有全选,随意筛选,均匀分布,特征筛选等多种方法,kinectFusion中使用的应该是最朴素的全选(由于使用了GPU,并行化增加的前提下简单的算法有无可比拟的优势)
- 匹配:两个点集之间的点进行配对
- 注意这并不是要保证匹配的点对是真实的匹配,因为本身ICP是迭代计算出匹配点并将其拟合的收敛过程。我们需要做的是每次选取合适的初始值。
- KinectFusion采用的是投影关联(projective data association)。简单来说就是用上一个世界坐标系中的点,先转化成上个相机坐标系点 vi−1 (3D),再转化成上一个图像坐标系点P(2D),然后找到本次图片中同样的2D坐标点,用当前的Ti值和Ri值去计算出点v及其法向量n,最后判断v和n与其对应点的相容性(其实是第4步去除的操作)。这样就完成了一次找匹配点的计算。
- 权重:给每个匹配的点对分配权重
- 去除:去除不符合条件的点对
- 误差度量:基于以上点对,给出每个点对的误差计算方法
- 最小化:最小化误差度量
经过上面的一次迭代,我们找到一堆匹配点,并求出其中使得匹配度最优(可以取类似最小二乘的值)的T,然后将本次测量的深度图进行相应的变换来进行下次迭代。
由于采用的是类似连续图像处理的方式,每一帧的深度测量值相差都很接近,这样才能使得算法能够迭代收敛。对每个点用一个GPU线程去处理的方法有效的简化了ICP的过程。
Volumetric Integration
上一环节已经形成了每个相机图像个子的T和R,可以将每一帧采集的数据转化成世界坐标系当中。通过本环节的操作,我们可以形成水密的物体重建,采用TSDF(Truncated Signed Distance Function)的方法。
接下来我们对每一步进行解释,非常通俗易懂且巧妙的算法:
将重建空间进行体素划分,比如划分成 5123 (即长宽高都是512的立方体晶格)。
我们将整个空