Roxy's Library

Back

区别于2维图像,三维物体可以有很多表现形式,比如多视角的图像、点云、深度图、体素、网格等,这取决于我们如何获取这些数据和我们研究问题的需求

Depth Images#

深度图中每个点的值表示其与相机的距离。它是一种2.5D表示,因为它不能提供3D中任意两点的距离信息(需要内参矩阵K)

Backprojection#

给定图片中一个pixel的坐标(u,v,z)(u,v,z),我们可以通过内参矩阵K将其反投影到3D空间中:

已知:

(u,v)=(αxz+cx,βyz+cy)K=[α0cx0βcy001](u,v) = (\alpha \frac{x}{z} + c_x, \beta \frac{y}{z} + c_y) \quad K = \begin{bmatrix}\alpha & 0 & c_x \\ 0 & \beta & c_y \\ 0 & 0 & 1\end{bmatrix}

我们可以反解出:

x=(ucx)zα,y=(vcy)zβx = \frac{(u - c_x)z}{\alpha}, \quad y = \frac{(v - c_y)z}{\beta}

这样我们就可以将深度图转换成一个点云表示

Depth Sensors#

我们可以通过不同的传感器来获取深度图,一种常见的深度传感器是stereo sensor,它通过两个相机捕捉同一场景的图像,并通过比较两张图像中对应点的位移(视差)来计算深度信息

stereo sensor

OOOO'分别是两个相机的光心,ff是焦距,BB是两个相机之间的基线距离,uuu-u'是视差,即同名点的水平像素差。根据三角形相似,可以得到上面的公式

由于两个相机水平差距,我们只能计算重合部分的深度信息,因此在一些场景中可能会有盲区

stero sensor比较依赖场景纹理,对于一些场景难以得到准确的信息

一种改进叫做Active Stereo,它不是被动的接受光线,而是主动发出结构化光,另外的相机利用观测到的这些光的一些先验信息来计算深度

Mesh#

Mesh(网格)是一种由顶点、边和面组成的分段线性表面近似,将物体表面平滑的曲面用离散的平面来表示。最常见的网格是三角网格

mesh

关于Mesh的存储,可以使用下面两个列表

  • 顶点列表:存储每个顶点的坐标
  • 面列表:存储每个面由哪些顶点组成

Point Cloud#

点云是一群从物体上采样出的三维空间中的点,是一种简单的3D表示方法。每个点通常包含位置坐标(x, y, z)和可能的其他属性(如颜色等)

点云不能体现表面的位置,因为不知道哪些点可以连接起来

Sampling Strategy#

如何从表面信息(比如Mesh)中采样出点云呢?有两种常见的策略:

Uniform Sampling

采样的点云依赖于每个表面的面积大小,面积越大的表面应该采样更多

步骤:

  • 计算每个surface的面积和总面积
  • 根据每个surface的面积占总面积的比例作为权重,根据权重来分配采样点的数量
  • 在每个surface上均匀采样点

一种在三角形中均匀采样的方法:(假设三角形的三个顶点为v1,v2,v3v_1, v_2, v_3

  • 生成两个均匀分布在[0,1][0, 1]间的随机数r1r_1r2r_2
  • p=r1(v2v1)+r2(v3v1)+v1p = r_1(v_2-v_1) + r_2(v_3-v_1) + v_1,通过这样可以在平行四边形内均匀采样点
  • 如果r1+r2>1r_1 + r_2 > 1,则将r1r_1r2r_2替换为r1=1r1r_1' = 1 - r_1r2=1r2r_2' = 1 - r_2,这样可以将点映射到三角形内

这样取样之后, 在取样量不算非常大的时候, 经常会出现不太均匀的情形

Farthest Point Sampling(FPS)

我们想要选取NN个点使其两两距离求和最大,但这个问题是NP-hard的,因此我们使用一个近似的贪心算法来实现:

步骤:

  • 从点云中随机选择一个点作为初始点
  • 计算所有未选择点到所有已选择点的最小距离,选择距离最远的点加入已选择点集合
  • 重复上述步骤直到达到所需的采样数量

这样实际上更均匀

Metric#

我们可以定义一些距离度量来衡量两个点云之间的相似性:

  • Chamfer Distance(CD):对于点云S1S_1S2S_2,计算每个点云中每个点到另一个点云的最近距离的和,再把两个结果相加
dCD(S1,S2)=xS1minyS2xy2+yS2minxS1xy2d_{CD}(S_1, S_2) = \sum_{x \in S_1} min_{y \in S_2} ||x - y||_2 + \sum_{y \in S_2} min_{x \in S_1} ||x - y||_2
  • Earth Mover’s Distance (EMD):计算将一个点云变换成另一个点云所需的最小工作量,工作量定义为点之间的距离乘以点的权重
dEMD(S1,S2)=minϕ:S1S2xS1xϕ(x)2d_{EMD}(S_1, S_2) = min_{\phi: S_1 \to S_2} \sum_{x \in S_1} ||x - \phi(x)||_2

其中ϕ\phi是一个双射函数,将S1S_1中的每个点映射到S2S_2中的一个点

CD 对于采样不敏感,而EMD对于采样非常敏感

Implicit Field#

与前面的显式表示(如Mesh和点云)不同,隐式场不会显式去表示空间结构,而是用函数来定义一个空间

SDF#

Signed Distance Function (SDF) 是一种隐式场表示方法,它定义了一个函数f(x,y,z)f(x,y,z),它具有下面这些特性:

  • 内部点:f(x,y,z)<0f(x,y,z) < 0
  • 表面点:f(x,y,z)=0f(x,y,z) = 0
  • 外部点:f(x,y,z)>0f(x,y,z) > 0
  • f(x,y,z)f(x,y,z)的绝对值表示点到表面的距离

SDF to Mesh#

我们可以使用Marching Cubes算法将SDF转换成Mesh。该算法的基本思想是将空间划分成一个个小立方体,然后根据每个立方体的88个顶点的SDF值来确定该立方体与表面的交点位置,从而生成三角形网格

这里我们先看一个2D的例子:

Marching Cubes

我们先将SDF离散化,在每个像素点上计算处其SDF值。然后根据表面的定义进行二值化(这里认为1.51.5是表面),大于这个值的置为11,小于这个值的置为00,这样我们就得到了一个二值图像

Binary Image

对于一个正方形网格,根据其四个顶点的二值化结果,我们可以将其分成1616种情况(每个顶点有两种状态,24=162^4=16),每种情况对应一个特定的边界划分

那么我们只需要根据每个网格的情况来查找对应的边界划分表格,就可以生成一个近似的表面

查找表的边界只是简单的二分,对于一些交界处(比如1133),边界(1.51.5)可能并不落在中央,因此需要进行线性插值进行微调,来更准确地确定边界位置

在划分查找表时,会有一些ambiguity的情况

Ambiguity

对于上图的情况,由于不知道中间点的情况,所以可能有两种划分方式;对于三维的情况,可能会有更多的ambiguity情况

目前的一种解决方案是拓展查找表,通过看周围的网格的情况来确定如何选取

Deep SDF#

这些隐式函数应该如何表示,对于简单的几何体,我们或许可以用一些解析函数来表示,但对于复杂的物体,我们需要更强大的函数表示能力,这时我们可以使用神经网络来学习隐式函数

3D Deep Learning#

三维信息处理有两种基本的方向:

  • 把处理二维信息的方法进行改进,使其可用于三维数据
  • 把三维数据投影到二维空间中,利用二维方法进行处理

PointNet#

对于点云数据,我们要设计处理它的神经网络,需要满足shuffle invariance(点云的顺序不应该影响结果)

因此,使用FC或者简单拉成1D向量做卷积都不合适

一个满足shuffle invariance的想法是使用对称函数,即输出不随输入顺序改变而改变的函数,比如max或者average。下面的工作就变成了如何用神经网络来构造对称函数

PointNet依赖于一个结论:f=γg(h(x1),h(x2),,h(xn))f = \gamma\circ g(h(x_1),h(x_2),\cdots,h(x_n))是对称函数,当gg是一个对称函数

PointNet

γ\gammahh都用MLP来实现,这就是PointNet的基本结构

3D Vision II
https://astro-pure.js.org/blog/cvintro_05_06
Author GreyRat
Published at May 10, 2026
Comment seems to stuck. Try to refresh?✨