GLSL截断符号距离表示(TSDF)实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GLSL截断符号距离表示(TSDF)实现相关的知识,希望对你有一定的参考价值。
我期待着实现RGB-D图像的模型重建。在手机上首选。为此,我读到了,所有这些都是通过TSDF表示完成的。我现在阅读了大量关于层次结构和其他想法的论文来加快这一点,但我的问题是,我仍然不知道如何实际实现这种表示。
如果我有一个大小为n的体网格,那么n x n x n我希望在每个体素中存储有符号的距离,重量和颜色信息。我唯一的猜测是,我必须为每个体素位置构建一组离散的点。并且用GLSL“绘制”所有这些点并计算最近的距离。但是,计算这个n ^ 3次似乎并不是那么好或有效。
我怎么能想象实现这样的TSDF表示?
问题是,我唯一的想法是将体素网格存储在有符号距离的数据中。但是对于每个深度图,我必须再次渲染所有体素并计算所有距离。有没有办法以反过来渲染它?
那么我不能渲染深度图的点并在体素网格中存储信息吗?
实际的艺术状态如何以有效的方式呈现这种有符号距离的表示?
你是在正确的轨道上,这是一个雄心勃勃的项目,但如果你能做到这一点非常酷。
首先,值得了解这些事情是如何运作的。标识TSDF的原始论文是由Curless和Levoy完成并且相当平易近人 - 副本是here。有许多后来的变化,但这是起点。
其次,您需要创建nxnxn存储,如您所述。这很快变大了。例如,如果您想要400x400x400体素的RGB数据和浮点值的距离和重量,那么这将是768MB的GPU内存 - 您可能需要检查移动设备上可用的GPU内存量。是的,我说GPU因为......
虽然您可以在CPU上实现玩具解决方案,但如果您希望获得任何性能,您确实需要认真对待GPU编程。我在Intel i7 CPU笔记本电脑上构建了早期版本。不可否认,我没有花时间优化它,但整合单个深度图像花了几十秒。如果你想获得实时(30Hz),那么你需要一些GPU编程。
现在您有了TSFD数据表示,您需要执行以下每个帧:
1.在世界坐标中确定摄像机相对于TSDF的位置。通常假设您是时间t = 0时的原点,然后测量相对于前一帧的相对平移和旋转。最常见的方法是使用称为迭代最近点的算法(ICP)您可以自己实现或使用像PCL这样的库,虽然我不确定它们是否有移动版本。我建议你在没有这个的情况下开始,只需保持你的相机和场景静止,然后再建立运动。
2.将您拥有的深度图像集成到TSDF中这意味着使用下一个深度图像更新TSDF。您不会丢弃迄今为止的信息,而是将新信息与旧信息合并。您可以通过迭代TSDF中的每个体素来执行此操作:
a)计算从体素中心到相机的距离
b)将点投影到深度相机的图像平面以获得像素坐标(使用上面获得的外部相机位置和可轻松搜索Kinect的相机内部参数)
c)在该像素坐标处查找深度图中的深度
d)使用像素x和y坐标加上深度和相机属性将此点投射回太空以获得对应于该深度的3D点
e)使用值distance_from_step_d更新当前体素距离的值 - distance_from_step_a(更新通常是现有值加上新值的加权平均值)。
您可以对体素颜色使用类似的方法。
将所有深度图集成到TSDF后,可以通过光线跟踪或提取iso曲面(3D网格)并在另一个包中查看结果来显示结果。
一篇非常有用的论文可以帮助你找到here。这是一些实际在PC上实现Kinect Fusion的学生的实验报告。这几乎是一步一步的指导,尽管你仍然需要学习CUDA或类似的实现它
你也可以在GitHub上查看我的源代码以获取想法,尽管所有关于适用性的正常免责声明都适用。
祝好运!
在我发布了我的其他答案后,我想到了另一种方法,它似乎与你问题的第二部分相匹配,但它绝对不是重建,也不涉及使用TSDF。它实际上是一个可视化,但它更简单:)
每帧都可以获得RGB和深度图像。假设这些图像被注册,即RGB图像中(x,y)处的像素表示与深度图像中(x,y)处的像素相同的像素,则可以创建使用RGB数据着色的密集点云。要做到这一点,你会:
对于深度图中的每个像素a)使用相机的内在矩阵(K),该点处的地图中的像素坐标和深度值将该点投影到相机坐标中的3D点b)将RGB值关联到与空间中的那个点相同的像素
所以现在你有一个(可能是640x480)结构的数组,如{x,y,z,r,g,b}
只需创建一组顶点和渲染点,就可以在GLES上使用它们进行渲染。有关如何做这个here的讨论
使用这种方法,您可以每帧丢弃数据并从头开始重做。重要的是,您没有获得重建曲面,也没有使用TSDF。你可以得到漂亮的结果,但它不是重建。
以上是关于GLSL截断符号距离表示(TSDF)实现的主要内容,如果未能解决你的问题,请参考以下文章