
【斯坦福CS231n 学习笔记11】3D Vision
学习了3D视觉的相关内容,了解了当前3D视觉发展的一些趋势。
3D 几何表示
3D 几何表示是 3D 视觉的基础,与 2D 图像仅由规则的像素矩阵构成不同,3D 对象的表示方式非常多样。主要分为显式表示和隐式表示。
具体的表示主要有以下考量:
- 存储:同样精度下,体素、网格、电云、隐式网络的存储与带宽成本差异较大。
- 创造新形状:不同的表示支持的交互方式不同,例如 CAD 可以通过拖拽参数/曲线生成,而生成模型则从分布中采样。
- 操作:编辑、简化、平滑、修补、滤波——这些在网格上可能是经典几何处理流程,在点云上可能更依赖局部邻域与重采样,在隐式函数上可能变成对 的正则化或重建。
- 渲染:无论是什么渲染管线,最终要将表示映射到可渲染的信号。
- 动画:如果形状要动,表示要么要支持形变/骨骼/拓扑变化,要么要支持时间维度的连续建模。
显式表示
点云
点云可以写成一组在三维欧氏空间中的离散采样点:
在实际的系统中,一个点往往不止有坐标,还会携带属性通道,因此更完整的写法常见是
其中 可能包含:颜色 、强度/反射率(LiDAR intensity/reflectance)、法向 、语义标签、时间戳等。即用一些样本点去近似一个连续的 3D 表面/场景”,但其不直接表示表面如何连起来。
点云最典型的来源是距离测量到三维坐标反投影的流程,通常来自于 LiDAR、RGB-D 深度相机以及多视角重建/SLAM 融合:
- LiDAR(激光雷达):本质是发射激光并测距(飞行时间 ToF 等),在不同扫描角度上得到一系列射线的命中距离;每条射线给出一个 3D 点(通常还带反射强度)。它的典型特点是视角依赖强、遮挡严重、密度随距离变化(远处更稀疏)。
- RGB-D 深度相机(Kinect/RealSense 等):先得到每个像素的深度 Z(u,v)Z(u,v)Z(u,v),再用相机内参把深度图转成点云:
这也表明了点云经常来自于一个 2D 网格上的深度信号,只是将其展开为了无序的 3D 点集。
- 多视角重建/SLAM 融合:把不同视角下的点云通过位姿估计对齐,再融合成更完整的场景点云;这类点云往往包含更复杂的噪声模式(漂移、重复、错配点)。
点云主要具有以下关键性质:
- 非结构化:点云没有图像那样的规则网络邻接关系,也没有接下来的 mesh 那样的显式的边/面连接,因此局部邻域不是数据结构的目的,需要经过临时构造:例如 kNN 邻域、半径邻域、或者通过体素哈希建立近邻索引。
- 无序:点云作为集合满足以下公式:
即存储顺序不应影响几何含义,直接将 作为序列输入到网络中会引入伪顺序,因此点云网络必须实现置换不变性。
- 采样不均匀:点云密度取决于传感器、距离、入射角、材质与遮挡;这会导致同一物体表面上,有的地方点很密、有的地方几乎空洞。很多几何量(曲率、法向)都高度依赖局部点分布,因此“同一个形状”在不同采样下会看起来像不同的数据。
- 视角与遮挡:点云通常只覆盖可见表面:背面、凹槽、被遮挡区域直接缺失,所以点云经常代表的是“一个视角下的可见壳层”,而不是“封闭实体”。
尽管点云是 3D 传感器获取数据的直接形式,但其非结构化特性带来了诸多显著局限:由于缺乏面片定义与显式的顶点连接关系,直接渲染点云往往会导致视觉上的“孔洞”与锯齿效应,工程上常通过 Splatting 或 Surfel 技术将离散点近似为微小平面元以模拟连续表面,但这本质上属于后处理假设而非数据本身提供的几何连续性;同时,点云在拓扑与语义表达上极为匮乏,无法直接编码表面的边界、封闭性或连通关系,导致体积计算、连通分量分析以及内外测试等几何属性定义模糊,通常需要借助泊松重建或隐式场拟合等高成本手段将问题转化为几何推断过程;此外,点云对采集过程中的测距误差、多路径反射等噪声及离群点高度敏感,这些偏差会显著干扰法向量与曲率等局部几何特征的鲁棒估计,进而误导下游学习任务;最后,点云还面临着分辨率与计算效率的内生矛盾,单纯增加点密度不仅会呈几何级数增加存储与近邻搜索的算力负担,且受限于非均匀采样与噪声干扰,高分辨率往往仅意味着“高冗余度与高不稳定性”,并不等同于更高质量的表面表征。
Polygonal Meshes
Polygonal Mesh 明确定位成一种边界表示,其不试图表示物体内部的体素/密度,而是用一张“皮肤”去近似物体表面。最常见也最标准的是三角网格,可以形式化为:
其中 是顶点坐标, 是面片的顶点索引,每个三角形由 3 个顶点构成。实际上还可以显式存储边的集合 ,或者使用更加工程化的数据结构去编码一个面的旁边是谁,一个边的对面是哪条边,这些邻接关系会决定后续能否进行高效编辑与几何处理。
网格表示的本质是分片线性近似——每个三角形都是一个平面片,曲面是由大量平面片拼出来的,因此如果想要更加精细表示曲率的细节,就需要增加三角形的数量,表面几何(法向、曲率、边界)都可以从三角形的局部结构直接计算或近似得到。
网格相对于点云而言,几何处理更加友好,因为有 (连通性),因此可以用明确的拓扑操作去改变分辨率与质量,而不是多采点/少采点,由此可以定义网格上的三种操作:
- 上采样:细分的典型做法是将每个三角形拆得更小(例如每条边取中点,将一个三角形分成 4 个),然后用插值/平滑规则更新顶点的位置,使得新网格在视觉上更加接近光滑曲面。上采样不仅是加面数,其通常还会隐藏一个低通平滑,因此会让表面更圆润,更连续。
- 下采样:简化的目标不是随便删除三角形,而是让删掉很多面之后的形状仍然保持原来的,实践中经典的策略包括 edge collapse(将一条边的端点合并为一个点,从而消除若干三角形),或者用某种误差度量来决定先删除哪条边最不影响形状。可以将其简化为一个优化问题:在面数下降的情况下,最小化形状偏差与外观偏差。
- 网格正则化:正则化的目的是改善三角形的分布,例如需要避免极“瘦长”的三角形(这会让数值不稳定、法向噪声大、仿真/学习容易出问题),让三角形的大小更加均匀,或者让高曲率区域更密、平坦区域更稀。通常是通过局部重连、顶点平滑、重网格化等手段,使网格更加适合渲染和计算。
Mesh 的优势来自连通性,但是代价必须是其必须维护拓扑一致性与几何合法性,否则就会出现一条边被多个面共享、局部邻域不像是一个盘,导致算法失效的非流形问题,与三角片相互穿插、使得内外的定义混淆的自交问题,以及不封闭问题。
Parametric Representation
点云和 Mesh 都是在 3D 中直接离散表面,而参数化表面则是一个更加规整的参数空间中定义曲面,再将其映射到 3D,这天然带来光滑性与可微结构。
假设有一个映射:
当要表示 3D 空间中的一张曲面时,最常见的设定是:
即用二维的参数去生成三维的点:
曲面是一个 2D 流形嵌入到 3D 中,所以用两个自由度的参数去铺开它是合理的,而且一旦有了 ,曲面中的很多几何量都可以通过微分得到,例如切向量、法向量、面积元素等等。
只要 足够光滑(至少一阶可微),就能够在每个参数点计算两条切向量:
法向量可以写成:
这件事情在 Mesh中也能够实现,但是在参数化曲面是连续函数直接给出的结构,而不是 Mesh 中离散近似的副产物。
工业界常用的曲线族主要有Bézier 曲线、B-spline / NURBS 曲线与Subdivision 曲线:
- 二维参数化 Bézier 曲面可以写成控制点网格 的加权和:
其中 是 Bernstein 多项式。可以把它理解成“一个二维的控制点棋盘”, 像是在棋盘上平滑地插值出一张曲面,因此天然光滑、也方便做局部编辑(改动某些控制点会在空间里产生可预测的形变)。
- Bézier 的一个弱点是控制点影响范围偏全局,而 B-spline / NURBS 通过分段基函数与结点向量(knot vector)增强了局部控制能力;NURBS 进一步用“有理形式”把圆、椭圆等二次曲线精确表示出来,所以它是 CAD 系统里非常主流的曲面表示。
- 细分曲面从一个粗的控制网格出发,反复执行细分规则(例如 Loop、Catmull–Clark 等),得到越来越密的网格;在迭代极限下,这个过程对应一张连续曲面。它将网格的可编辑性与曲面的光滑性结合在一起,使得依然可以像编辑网格那样动控制顶点,但最终得到的是一张更光顺的曲面,而不是满是折线感的多面体。
- 以上几种都是 3D 图像的显式表示,这些方法都直接定义了物体表面的几何元素,其优势在于易于获取和采样,但是对拓扑结构和内部状态的描述能力较弱,例如难以直接回答某点是在内还是在外:
由此引入隐式表示。
隐式表示
最基本的隐式表示的定义是
其中 是一个标量场,整个空间都被 赋予了一个值,而表面只是其中的一条“等高线/等值面”。为了让这个表示在实体层面有意义,通常会规定符号:
- :在物体内部。
- :在物体外部。
这样网络就变成了一个常数时间的符号判断,不需要 Mesh 的封闭性,也不需要复杂的射线交点计数,只需要看 的正负即可。
代数曲面
最早也是最数学的隐式表示是代数曲面: 是多项式,例如球体可以写成:
很多形状的几何边界都可以被一个解析式刻画,并且可微、可解析。
CSG:用布尔运算拼形状
CSG 的核心是如果有两个实体 和 ,其各自对应的隐式函数为 ,,那么可以通过函数级的组合得到并集/交集/差集。
一个常见且直观的构造是基于符号场的 min/max:并集 ,交集 ,以及差集(将 从 中挖掉): 。在隐式表示中,布尔运算就只是一行公式,而在 Mesh 中做布尔运算则往往需要处理复杂的面片相交与拓扑修补。
距离函数
隐式函数中最常用的并且最几何友好的是距离函数,尤其是带符号距离函数 SDF。设 是物体表面,SDF 的定义为:
不再只是一个“任意的零集合函数”,而是一个有度量意义的场,数值大小直接表明离表面有多远,符号表明在内还是在外。
SDF 还有一个几何副产品:在光滑区域,表面法向可以由梯度给出:
更进一步,理想 SDF 满足 Eikonal 约束 (离表面越近越准确),这会在后面的“学习型隐式函数”里变成常见正则项。此外,之前的 min/max 做并交会在拼接处产生不可微的折角,这在优化与学习中并不友好,因此工程中常用 smooth min/ soft union 来进行可微过度,例如用 log-sum-exp 形式近似 :
越大越接近硬 ,越小越平滑。这表明隐式表示不仅支持“几何布尔”,还天然支持“可微版本的几何布尔”,这对神经网络参与几何建模非常关键。
Level Set Methods
当把形状表示为 的水平集时,形状随时间的变化就等价于场的演化;一个经典写法是:
其中 是某种速度场(可以依赖曲率、外力或数据项)。当两个部分靠近并“融合”时,零水平集会自然地合并;当形状被切割时,零水平集也会自然分裂。
想象一张 2D 地形图,地图上的每一条“等高线”就是一个 2D 水平集(海拔高度 )。在 3D 视觉中,将这一概念升维,物体表面就是 3D 空间中某个物理量(如距离、密度)相等的那些点组成的面。
Voxels
令一个 bounding box 被划分为 的规则网络,每个格子对应一个体素单元 ,体素表示通常存储两类信息之一:
- 占据网格
其中 表示该体素被物体占据,$0$ 表示空,这样能够将一个实体的体积离散成三维二值图像。
- 标量场采样
其中 是体素中心点或格点位置, 可以是隐式函数,例如 SDF,这类体素更像是体数据,在之后的等值面提取中也更加自然。
在深度学习中,体素数据通常会被打包成张量:
其中 是通道数。
体素完美契合了卷积神经网络的平移不变性和局部性,但是其存储和计算需求的时间和空间复杂度都来到了 ,并且在一个 的实心网格中,占据物体表面的体素数量仅仅约为 ,绝大多数体素是空的,即其具有空间稀疏性。
至此,3D 几何表示的方法就主要有以上几类:
3D 数据集与任务
数据集
早期的 3D 数据集以 Princeton Shape Benchmark(PSB)为代表,其仅包含 1814 个模型、182 个类别,规模不大但覆盖面较广,因此更适合用于校准“类别语义与几何变化”之间的关系,并作为检索/分类等任务的早期评测基准。随后出现的大规模合成对象数据集 ShapeNet,将数据量与组织结构同时向前推进:它不仅提供了更丰富的 CAD 形状集合,还试图借助 taxonomy(如 WordNet 体系)把类别以层级方式组织起来,从而使类间关系、部件语义、规范化对齐(canonical alignment)等结构化信息能够被模型利用,而不是把每个 3D 模型当作彼此孤立的样本。再往后,Objverse/Objverse-XL 代表了一种更“贴近现实分布”的数据范式:它强调真实资产与真实扫描的规模化汇集,使几何细节、纹理材质与噪声统计更接近真实世界,同时带来更强的类别多样性与长尾分布,这对需要学习“几何—外观联合分布”的生成式建模尤为关键。与上述“以 3D 资产为中心”的数据不同,CO3D 的核心形态是多视角视频序列,它更直接服务于“从图像学习 3D”的路线:一方面可用于训练与评测从多视角图像恢复 3D 表示(例如隐式场或神经渲染类方法),另一方面也为将 2D 大模型的表征能力迁移到 3D 提供了天然接口。随着任务进一步从“整体形状”走向“结构理解”,数据的组织也开始从 objects 过渡到 parts:对象类别不再只是平铺的标签,而是具有层级与语义关系的体系,并且不同实例之间存在可对齐的部件对应(part correspondences),从而支持更细粒度的形状解析、可组合生成与结构化推理;与之相配套的 PartNet 等数据集提供了细粒度、实例级且层级化的部件标注(并常伴随可动部件/关节信息),而在更复杂的场景层面,ScanNet 等室内 RGB-D 扫描数据集进一步把监督扩展到相机位姿、表面重建与实例级语义分割,使得“对象—部件—场景”的 3D 学习链条能够在更真实的传感器数据与几何约束下闭环。
3D 视觉任务
主要包括判别式任务与生成式任务。
- 判别式任务主要是从 3D 表示中读出语义,输入是某种 3D 表示 (点云/网格/体素/多视角图像),输出是理解层面的变量。这类任务主要包括分类、检索/度量学习、3D 语义分割、姿态对齐、场景理解等。
- 生成式任务主要是往 3D 空间中写入几何。输入通常是某种条件(类别、文本、图像、部分观测),输出是一个 3D 对象或场景。这类任务主要包括无条件生成、条件生成、补全/重建以及新视角合成。
3D 深度学习方法
Multi-View CNN
3D 原生表示(点云/体素/网格)要么不规则,要么计算爆炸,而 2D CNN 已经非常强并且工程成熟,Multi-View CNN 的思路就是将 3D 物体从多个角度渲染成一组 2D 图像,将问题转换成对一组图片进行分类/检索。
给定一个 3D 图像 ,先选取 个相机视角 ,通过渲染算子 得到多视图图像集合:
于是一个 3D 样本就被转写为一个 2D 图像集合:
对于每张视图图像 ,使用共享权重的 2D CNN 提取特征:
而后将其聚合为一个全局向量 ,最经典的做法是对称聚合,以保证置换不变性:
最后接上输出头,完成对应的分类或检索任务。
这种方式直接复用了 ImageNet 预训练,使得 2D CNN 的特征迁移非常成熟,而 3D 数据集往往较小,MVCNN 可以使用 2D 的预训练初始化,降低了 3D 学习的样本复杂度。但是仍然存在几何信息丢失、依赖于视角采样、以及难以端到端对齐真实数据分布的问题。
3D-GANs
3D-GAN 的核心是将 GAN 从 2D 像素迁移到 3D 体素。
上文提到体素可以作为张量输入,因此直接可以套用 3D CNN/3D deconv,通过编码器来对特征进行理解压缩,解码器使用压缩的语义信息进行生成重建,共同构成生成器,然后将其输入到判别器中,这样不再需要点对点的重建监督,而是直接从真实的形状中学习什么样的体素可以对应一个合理的物体。
Visual Object Networks(VON)
VON 的思路是将生成的过程分解为三个潜变量:
- 形状:,常见的还是使用体素表示。
- 纹理/外观:,可以是纹理场、贴图或者某种外观参数。
- 视角:,可以是相机的位姿或者视点随机采样。
然后经过一个渲染/投影算子将 3D 图像变为 2D 图像,判别器不再查看 3D 体素,而是看渲染出来的 2D 图像。因为只要生成的 3D 在各种随机视角下渲染出来都像真实图像,那 3D 形状+纹理组合就被迫学到合理的 3D 结构。
Octave Tree Representations
在 3D 空间中,octree 是一种递归的空间划分结构,根节点对应一个立方体空间,每次细分将一个立方体沿着三个轴各二分,得到 8 个子立方体,对于每个子立方体,如果其靠近表面或者包含有效信号,就继续细分,否则停止细分并且作为叶子节点。
纯体素网格的浪费来自于空的空间也要存储,octree 通过空的空间不再细分以及只在表面附近细分来解决这个问题,高分辨率只需要覆盖一个接近 2D 的邻域,因此有效单元的数量要比 慢得多。
但是问题也随之而来:在不规则的稀疏结构上,如何定义局部邻域并高效做卷积/池化。
在规则体素中,一个格子邻居是固定的 6/18/26 邻接,但是在 octree 中,不同的单元尺度可能不同,因此邻域必须同时处理同层邻居和跨层邻居。这就要求网络将树结构展平成某种稀疏张量并且维护映射索引或者在树上做层级卷积与 pooling。
Octree 的层级天然对应多尺度表征,向上 pooling 相当于将 8 个子块汇聚成父块,向下 upsamping 相当于将父块特征广播/细化到子块,因此在语义分割、重建这一类任务中,其天然提供了类似于 U-Net 的 encoder-decoder 多尺度路径。
具体的生成也要按照层级递归,先生成粗层级的结构,再决定哪些 cell 需要细分,最后在这些局部区域生成更高分辨率细节,可以将其抽象为
其中 决定哪些单位继续展开为 8 个子单位,这样生成过程的计算量只与表面复杂度相关,而不是与整个 相关。
PiontNet
在点云上进行学习的关键是对点云做函数逼近,输入是点集:
目标是学习一个函数,例如分类:
或分割:
但这里立刻出现两条硬约束,分别是之前提到的置换不变性与采样不变性,其中采样不变性是指同一个几何体可以被不同密度、不同数量的云采样出来,希望网络对点数 N 的变化、局部密度变化以及少量缺失等具有鲁棒性,否则其只能学习到采样的伪差异而非几何本质。
PointNet 的核心本质是逐点特征与对称聚合,任何满足置换不变的几何函数,都可以写成逐元素映射加上对称函数的形式:
其中: 是共享的逐点 MLP(对每个点同一套权重); 是对称函数(max/sum/avg); 是后续的 MLP 分类头。
在 PointNet 里最经典的是max pooling: , 可以将 理解成“全局 shape code”:每个维度取所有点的最大响应,相当于让网络自动选择最能激活某个几何模式的关键点。
PointNet 虽然解决了集合输入,但是其表达也有明显的缺陷, 是对全体点的全局聚合,而点与点之间的局部结构不是直接建模的,因此需要先进行局部邻域,再进行局部聚合。
对于每个点 ,可以使用 kNN 或者半径球定义邻域,kNN:,半径球:。而局部聚合中,典型图网络更新可以抽象为:
其中 仍然是对称函数(sum/max),这样既保留局部结构,又保持邻域内置换不变。
PointNet的典型思路就是:分层采样(FPS)+ 局部 grouping + 局部 PointNet(在每个局部 patch 内再做一次 PointNet),从而形成类似 CNN 的多尺度结构。
而当重建/生成时,输出也是点集 ,需要衡量其与真实点集 的差异,但是点与点之间并没有固定的对应关系,因此不能使用普通的 L2 来对应损失,通常使用两种集合距离。
- 最近邻双向覆盖(Chamfer Distance):,第一项保证真实点云每个点都能在预测中找到近邻,第二项保证预测点不会距离真实点云之外太远,其计算简单、可微。但是其也容易出现点堆叠的问题,因为其只要求每个点找到最近邻,不惩罚多个预测点同时在一个真实点云附近。
- Earth Mover’s Distance(EMD):EMD 将点集看作是质量分布,寻找一个一一匹配 使得运输的代价最小:,在点数相等且可一一匹配时,其更像是最小权匹配的代价。EMD 更加严格,其强迫预测点与真实点云分布对齐,天然抑制点堆叠,因此几何质量往往更好。但是其代价就是计算量较大,通常需要近似算法。因此一般情况下在训练时使用最近邻双向覆盖,只有在评测或小规模时才使用 EMD。
AtlasNet
AtlasNet 将 3D 表面表示成 个参数化 patch 的并集,对第 个 patch ,参数域通常取一个简单的 2D 集合(最常见的是单位正方形),并且学习一个映射 (通常使用 MLP 表示),其中 是形状的 latent code, 是 patch 解码器参数(通常各 patch 共享一部分结构但是可以有独立分支)。于是该 patch 生成的曲面点集是:
整体表面(以点采样形式)是:
可以把它理解为:网络拿到一个形状编码 后,会“把 张橡皮布(2D patch)拉伸到 3D 空间”,拼出一个对象的表面。
AtlasNet 的输出是点集,因此训练时最自然的监督是集合距离,最常用的是 Chamfer Distance。给定真实表面的点集 ,最小化:
AtlasNet 相比于直接生成点云,点不是独立产生的,而是来自一个 2D 连续参数域的映射,因此其内置了较强的几何偏置:
- 局部连续性:如果 是连续函数,那么参数域中相邻的 会映射到 3D 里相邻的点,这能够让生成结果更多像是表面而不是散点,输出更加平滑、更成片。
- 可控的拓扑复杂度:单一的 patch 很难覆盖拓扑复杂的表面,AtlasNet 通过多个 patch 的并集来增强表达力,当 较小时,模型输出会具有更强的光滑性和结构约束,但是可能覆盖补全,容易拉伸形变;当 较大时,模型输出的覆盖更好、细节更丰富、但是更加容易出现 patch 之间的裂缝与重叠。
但是 AtlasNet 也有自己的问题:patch 裂缝(不同 patch 独立生成,没有对边界情况进行强制约束,用 Chamfer 训练时,整体点集距离小仍然可能会出现局部细缝)、patch 重叠(多个 patch 可能映射到同一片区域,甚至发生自交,chamfer 不直接惩罚这种现象)、参数化畸变(为了覆盖复杂的曲面, 可能把参数域的某一小块拉伸成 3D 的一大片,导致采样点分布不均、局部细节表达不足)。
Deep Implicit Functions
隐式表示相对于直接学习更有优势,且学习参数化表面会遇到拼缝与拓扑限制,于是不妨可以直接一个隐式函数,让网络成为 的参数化器,这样表面就是 的水平集,拓扑可以自然出现,查询也变得更加统一。
深度隐式函数的基本形式如下:
输入是空间坐标 ,输出是一个标量,根据所选择的具体语义,标量可以代表以下内容:
- Occupancy 。
- SDF ,SDF 的好处是输出有度量意义,并且梯度与法向之间有直接关系。
如果只学习一个 ,得到的将会是一个固定形状,但是通常希望学习到的是一个形状族,因此引入条件变量 :
可以来自编码器 ,或者可以被当作每个训练实例的可学习 latent,与网络一起优化。
隐式函数的训练方式不是对整个 3D 空间进行密集监督,而是对一批采样点 监督 ,采样的策略决定网络在哪里学习得更准。
Occupancy 从真实网格或 TSDF 中得到 inside/outside 标签 ,训练使用交叉熵 ,SDF 中如果能够计算真实 SDF(或近似),则使用回归损失 ,一般会对靠近表面的点采样更密,因为几何细节主要集中在那里。此外一般还会再加上一个 Eikonal 正则,在 DeepSDF 中,理想的 SDF 满足
于是训练时加入 Eikonal loss:
因为如果只用点上的 SDF 回归,网络可能学出一个数值正确但梯度乱的函数,导致法向、等值面提取不稳定;Eikonal 把函数空间限制到更接近真实距离场的那一类,从而让几何更平滑、更可控。
在训练好 后,要得到一个可渲染的表面,常见的方式还是在网格上采样 ,再使用等值面提取得到网格:
具体的渲染方式有基于表面的渲染与基于体的渲染:
- 基于表面的渲染:使用 定义表面,再求射线与表面的交点,得到交点位置与法向,再使用 BRDF/着色模型渲染。
- 基于体的渲染:如果将 的输出解释成密度等体渲染量,那么渲染可以写成沿射线的积分形式,这种积分形式可以做成可微,允许仅使用 2D 图像误差反传到 3D 表示参数。
NeRF
可以使用连续函数表示几何,而连续函数还能用于表示外观等,并且使用一套可微的体渲染方程将 3D 场到 2D 图像连接起来,使得训练可以只依赖于多视图图像与相机的位姿,而不需要显式的 3D 真实数据。
NeRF 学习的是一个连续函数:
其中 是空间位置, 为视线方向, 是体密度(density / volume opacity 的微分形式),而 为颜色,通常依赖方向 用来表达非朗伯反射/高光等视角相关外观。
NeRF 的训练需要的监督是一组图像 与每张图像对应的相机内参 与外参 (即位姿),采用的基本计算单位是射线, 对一张图像里的某个像素 ,通过相机模型确定一条从相机光心出发的射线:
其中 是射线起点(相机中心), 是射线方向(由像素坐标与相机参数决定), 是近远裁剪范围(near/far bounds)。
NeRF 的渲染过程就是沿着每条射线采样一系列点,查询网络得到每点的 与 ,然后做体渲染积分得到像素颜色。
连续的体渲染可以写成积分的形式,而 NeRF 采用离散采样近似,得到可实现、可反传的表达。首先在射线上采样 个深度 ,得到点
对每个点查询网络 ,定义采样间隔 ,而每点的 alpha(该小段对光线的“不透明度”)近似为 ,射线到达第 点前仍未被吸收的透射率为 ,因此第 点对最终像素颜色的贡献权重是:,像素预测颜色为:,若考虑背景颜色 ,还会加上剩余透射率项:,关键点在于: 对 , 是可微的,而 , 又来自网络 所以可以从像素级误差反传到 3D 场参数 。
最基本的训练目标就是让渲染颜色匹配真实像素颜色,因此可以使用 L2 距离来进行优化。
由于每个像素对应一条射线,每条射线需要查询 次网络;如果一张图像有百万像素,直接渲染会非常慢。训练时虽然只采样部分像素,但总体仍要进行大量 MLP 查询与采样。
3DGS
NeRF 的效果好但是很慢,因为其沿着每条射线做了很多次 MLP 查询以及在空空间中进行了无效的采样,3DGS 采取的思路是更换一种表示方法,不再学习一个连续的 MLP 场 ,而是显式维护 个高斯几何基元:
每个高斯 通常带这些可学习参数:
- 中心位置: 。
- 协方差/形状: (常用可分解参数化表示为各向异性椭球)。
- 不透明度: 。
- 颜色/外观: (常用球谐系数 SH 来表达视角相关颜色,而不是简单常数 RGB)
对应的 3D 高斯密度可以写成:
3DGS 的核心是:把每个 3D 高斯通过相机投影到图像平面后,会变成一个 2D 椭圆高斯斑点(因为 3D 椭球在透视投影下对应屏幕空间的椭圆形影响域)。然后对每个像素,把所有覆盖到该像素的高斯按深度排序做颜色叠加(类似体渲染的前向合成,但计算结构更稀疏、更局部)。
Anatomy of a Structure-Aware Representation
以上内容都在解决高保真表示与渲染几何的问题,但是在真正理解、编辑、生成时,很多任务并不只关心表面的细节,而是更关心结构,例如一张椅子由哪些部件组成、部件之间如何连接、哪些部件重复、哪些关系受对称/支撑/功能约束。
- Segmented Geometry:将一个完整的 Mesh 切割成有语义的片段,并给每个片段打上标签。例如,把椅子的 Mesh 切开,标记哪部分是“腿”,哪部分是“背”。但是这种方式下训练得到的生成模型只能吐出一堆标记了的碎片,但无法保证它们拼起来是一个合理的物体,并且零件之间没有约束。生成时可能会出现“椅子腿长在座垫上面”这种不符合物理逻辑的情况。
- Part Sets:不再从整体切分,而是直接将物体表示为一组独立的“部件”的集合,这保证了每个零件本身的完整性,但是由于集合是无序且无连接信息的,模型不知道部件之间的相对位置关系。生成的椅子腿可能会漂浮在空中,或者互相穿插,因为没有连接的约束。
- Relationship Graphs:使用图 来表示物体。节点 表示部件,边 代表部件之间的关系。但是在机器学习领域,生成图比生成图像或序列要难得多。如何一次性预测出正确的节点数和复杂的边连接仍然是一个开放性难题。
- Hierarchies:为了简化图生成的难度,引入了树结构。将物体组织成一棵树,其中根节点是椅子,中间节点是底部部件和上部部件,叶子节点是具体的腿、轮子、扶手。树生成模型在计算机科学中研究得比较透彻,比生成任意图要容易控制。但是并非所有物体的结构都是完美的树形。有些关系是横向的,例如四条腿之间的对称关系,在树结构中很难自然表达(它们属于不同的树枝,距离很远)。
- Hierarchical Graphs:将层级图和关系图结合起来,宏观上是层级,每一层的内部是图,同层级的兄弟节点之间有边连接。这样将生成一个巨大的复杂图,分解为生成许多个小的、简单的图,且既有层级的建模,又有横向的对称/约束关系。
- Program:用一段计算机代码或形状语法来描述物体,其包含了上述所有表示法。一段程序可以生成网格、体素或层级图,且自然地表达了自由度,通过改变代码中的变量,可以无限生成同一类型的不同变体。
参考如下:
https://cs231n.stanford.edu/index.html
