基于体素的三维重建的最终结果——Marching Cubes算法学习笔记

这个算法在3d重建中很常用,最早来自于1987年的论文《MARCHING CUBES: A HIGH RESOLUTION 3D SURFACE CONSTRUCTION ALGORITHM》。

不想重复造轮子,所以先贴几篇介绍这个算法的帖子:

游戏《孢子》的思考 —— Marching Cube算法

Marching Cube算法在点云重建上的简单应用

Marching Cubes初探——Marching Cubes构建体素圆

看完之后基本就对这个算法有一定的了解了。

我想补充的还有几点。


1. 论文阅读

1.1 核心思想

There are two primary steps in our approach to the surface construction problem. First, we locate the surface corresponding to a user-specified value and create triangles. Then, to ensure a quality image of the surface, we calculate the normals to the surface at each vertex of each triangle.

1.2 概念名词

这篇文章经常会提到一个名词:density。可能是3d重建领域的论文,时间跨度很大(比如这篇都很老了),对一个概念使用的名词会不统一。

思考之后,我认为它的意思类似于BundleFusion算法中的sdf值以及等值面的判断阈值。

2. 编码表的实现

Marching Cube的第一步中需要使用到二进制编码表的相关知识,还挺实用的。因为看到网上有一些文章就是在讨论Marching Cubes中这些EdgeTable,TriangleTable怎么实现比较方便。

我找到的可参考的代码,是BundleFusion中的extractIsoSurfaceAtPosition函数

3. 相关代码

我最近接触的项目中,使用到这个算法的有BundleFusion(C++)、tsdf-fusion(C++,python),有兴趣可以去github仔细阅读。

在tsdf-fusion-python中,我发现Marching Cubes算法已经被python-skimage库实现了,用起来很方便,功能也很全。

4. 法向量的求解

为什么我说skimage把Marching Cubes算法实现的很“全”呢?因为我发现以上我提到的使用C++实现的Marching Cube算法,似乎都没有完成第二步,即计算三角顶点的法向量。

这个原因不得而知,可能是因为不计算法向量对最终模型的结果影响不大吧,论文的表述说的也是“法向量有助于提高重建的质量”。

网上有关这个问题的介绍也比较少。

但最近我想把Marching Cubes的3d重建结果再修的好一点(自动补全,填洞),目前比较好的传统方法就是泊松重建了,但是这种泊松重建方法,必须要有法向量才能算,因此我不得不去自己想办法计算法向量。

和求解三角顶点的位置和颜色的方法类似,法向量的计算也是使用的插值。。。

(这里我还没想好怎么表述)

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于三维重建marching cubes算法的实现涉及到很多数学知识和图形学原理,因此在这里我只能给出一个简单的示例代码,供参考: 1. 首先,我们需要准备一些数据,例如一个3D数组,表示某个物体的体素数据: voxels = rand(10,10,10) > 0.5; 其中,rand(10,10,10)返回一个大小为10x10x10的随机数矩阵,大于0.5的元素被视为1,小于0.5的元素被视为0,从而生成一个模拟的3D物体。 2. 接下来,我们需要定义一些辅助函数,例如计算立方体的8个顶点坐标、查找某个点在数组中的索引等: function [vertices, faces] = isosurface_from_voxels(voxels, threshold) [X,Y,Z] = meshgrid(1:size(voxels,1), 1:size(voxels,2), 1:size(voxels,3)); vertices = [X(:), Y(:), Z(:)]; values = voxels(:); index = values > threshold; vertices = vertices(index,:); values = values(index); faces = isosurface(X,Y,Z,voxels,threshold); end function index = sub2ind_3d(size, sub) index = sub(1) + (sub(2)-1)*size(1) + (sub(3)-1)*size(1)*size(2); end function sub = ind2sub_3d(size, index) sub(1) = mod(index-1, size(1)) + 1; sub(2) = mod((index-1)/size(1), size(2)) + 1; sub(3) = floor((index-1)/(size(1)*size(2))) + 1; end 3. 最后,我们可以调用isosurface_from_voxels函数,将体素数据转换为三角网格,并使用patch函数绘制出来: [vertices, faces] = isosurface_from_voxels(voxels, 0.5); figure; patch('Vertices', vertices, 'Faces', faces, 'FaceColor', 'r', 'EdgeColor', 'none'); axis equal; 这个示例代码只是一个简单的演示,实际上marching cubes算法的实现要比这个复杂得多。如果你想深入了解该算法的原理及其实现细节,建议参考相关的论文或书籍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值