图宾根-ML4360-计算机视觉笔记-全-

图宾根 ML4360 计算机视觉笔记(全)

001:课程介绍与组织方式 🎯

在本节课中,我们将了解计算机视觉的基本概念以及本课程的组织与学习方式。

什么是计算机视觉?

计算机视觉旨在让机器复现人类卓越的感知能力。简而言之,我们关注如何将转化为意义

例如,给定一张二维图片,我们希望检测或分割其中的物体。或者,给定一组图像,我们希望通过处理和分析三维世界在二维*面上的投影,来重建世界的三维结构。

一个令人惊叹的例子

为了让大家对计算机视觉的能力有一个直观感受,请看以下视频。这项名为“Nerf in the wild”的工作,正是关于如何从无结构的二维图像集合中重建三维世界。

该系统以一个场景(例如柏林的勃兰登堡门)的无约束照片集作为输入,并能够输出该场景的新视角图像,其中摄像机可以移动,场景的外观也可以改变。

从视频中可以看到,仅使用无结构的图像集合作为输入,系统就能为这些场景生成高质量的新视角渲染图。这非常神奇。在本课程中,我们将一起探索其背后的原理。

课程组织:翻转课堂模式 🏫

上一节我们介绍了计算机视觉的宏伟目标,本节中我们来看看本课程的具体组织方式。

本课程采用“翻转课堂”模式进行教学。这意味着,我不会在实体课堂时间内直接讲授材料,而是会提前提供讲座视频供大家观看。

在观看视频后,我们将参加“直播课”。在直播课中,我们将有大量时间讨论特定讲座中有趣或困难的内容。

以下是本课程学习流程的具体说明:

  • 课前准备:你的任务是在实际直播课前观看YouTube上的讲座视频,并记下你的问题,带到直播课中。
  • 小组学习:我们鼓励你与同学组成学习小组,提前讨论课程内容和材料。
  • 课前测验:我们提供了讲座测验,这有两个目的:一是帮助你自我评估;二是你可以为期末考试赢得少量加分。同时,测验也能帮助我们了解哪些是难点,以便在直播课中重点讲解。

练习与支持 💪

除了讲座,我们还会持续以练习的形式提供作业。

如果你对视频内容或练习有疑问,可以在我们提供的聊天区中提问。特别是对于练习,我们每周会提供一次在线的练习辅导课,我们强烈建议你参加。

同样,我们也为练习提供了测验,用于自我评估、自我激励,并帮助我们了解困难的主题。

典型的一周学习流程

以下是你在典型一周内需要完成的事项:

  1. 观看教学视频
  2. 完成相关练习
  3. 通过聊天区、学习小组或练习辅导课,与老师及其他同学互动交流。
  4. 完成测验
  5. 参加直播课,在讲堂中共同讨论主题和难点。讨论形式可能包括我向你提问,你向我提问,或者我们一起完成一些小任务。

总结

本节课中,我们一起学习了计算机视觉的核心目标——将光转化为意义,并了解了本课程采用的翻转课堂组织模式。你需要课前观看视频、完成练习和测验,并积极参与直播课讨论和各种学习支持活动

我非常期待在我们的第一次直播课上与大家见面。到时见!

002:引言与挑战

在本节课中,我们将介绍计算机视觉的定义,并探讨该领域面临的一些核心挑战。

概述

计算机视觉是人工智能的一个重要分支,其核心目标是让机器能够通过“看”来理解世界。我们将从定义出发,探讨其与相关领域的关系,并深入分析为何视觉感知是一个如此困难的问题。

计算机视觉的定义与背景

上一节我们介绍了课程的整体框架,本节中我们来看看计算机视觉的具体定义及其在更广阔领域中的位置。

计算机视觉通常被视为人工智能的一个方面。人工智能先驱约翰·麦卡锡将其定义为:“试图找到让机器使用语言、形成抽象概念、解决目前人类专属的各类问题,并进行自我改进的方法。” 这当然也包括对环境的视觉感知。

人工智能的子领域包括机器学习、计算机视觉、计算机图形学、自然语言处理、机器人学等。这些领域相互关联,正如我们将在本课程中看到的那样。

例如,如果我们想构建一个机器人系统,该系统必须感知世界或环境,并相应地更新其对世界的内部表征,以便做出适当的决策来最小化某个目标。

计算机视觉可以非常概括地描述为 “将光转换为意义”。这种意义可以是几何上的(重建场景的几何结构),也可以是语义上的(识别我们所见的某些方面)。但本质上,计算机视觉接收的输入仅仅是对光模式的一种特定采样。

视觉的本质

那么,什么是“看”?大卫·马尔在其著名的视觉著作中写道:“普通人(和亚里士多德)的答案会是:通过看来知道‘什么’在‘哪里’。” 这正是计算机视觉的常见定义:我们希望计算机通过看来知道什么在哪里

用我们的话说,就是从图像中发现世界中存在什么、事物在哪里、正在发生什么动作,并预测和预知世界中的事件。这更偏向机器人学方面,为了执行动作,我们需要预测周围正在发生什么,也需要对未来做出预测。

计算机视觉的应用与关联领域

计算机视觉有众多应用,其中许多已经商业化。

以下是部分应用领域:

  • 机器人学:环境感知与交互。
  • 医学:医学影像分析。
  • 媒体管理:构建3D模型、整理照片集。
  • 自动驾驶:环境理解与决策。
  • 移动设备与无障碍技术:人脸识别、场景描述等。

正如前面提到的,计算机视觉领域与许多邻*领域有联系。

  • 神经科学与生物视觉:许多计算机视觉算法从生物视觉中获得灵感。事实上,人类大脑超过50%的处理能力都用于视觉信息,这说明了该任务的重要性和难度。
  • 计算机图形学:这是计算机视觉的“逆问题”。计算机图形学是给定一个由物体、材质、语义、姿态和运动构成的3D场景,渲染出该场景的逼真2D图像。而计算机视觉则试图解决逆问题:从2D图像中恢复出原始的3D场景信息。因此,视觉是一个病态逆问题,大量原始信息在投影过程中丢失,需要被恢复。
  • 图像处理:图像处理关注图像的底层操作,如颜色调整、边缘检测、去噪、图像变形等,这些都发生在2D层面。计算机视觉在早期就与图像处理分道扬镳,因为它更关注获得更整体的场景表征和理解,特别是恢复世界潜在的3D结构。
  • 机器学习:机器学习工具在当今计算机视觉的各个领域被广泛使用,并使其在现实应用中取得成功。反过来,计算机视觉也为机器学习提供了强大的动机、范例和用例,极大地推动了机器学习(包括语言处理等其他领域)的研究突破。

深度学习的革命性影响

在过去的十年里,深度学习彻底改变了计算机视觉,同时计算机视觉也构成了深度学习革命的基础。

一个典型的例子是ImageNet图像分类问题的进展。该数据集包含100万张图像,分为1000个类别,目标是将每张图像分类到正确的类别。在2010年之前,这个问题的进展一度停滞,直到首次证明深度学习可以显著提升其性能。到2015年,算法在该问题上的表现已经超越了人类水*(尽管这对人类来说也非易事)。错误率(Top-5错误率)自2011-2012年以来急剧下降。

计算机视觉开始在相关问题上的有效应用,也增加了该领域的关注度并加速了其发展。例如,顶级会议CVPR的投稿和接收论文数量在过去十年左右急剧增长,参会人数也从2008-2009年左右的约1000人增长到现在的上万人。

由于一些任务现在可以通过计算机视觉解决,围绕计算机视觉已经形成了一个庞大的产业,相关算法被用于各种问题。

为什么视觉感知如此困难?

在许多领域,其难度在最初都被低估了。有一个著名的例子是西蒙·派珀特提出的“夏季视觉项目”,他计划用一个夏天的时间让实习生们基本解决计算机视觉问题。事实证明,我们今天仍在研究这个问题,因为它并不容易。问题无法完全分解为独立的子问题,且每个子问题都比最初预期的要困难。

为什么视觉感知很难?对人类来说它似乎很容易,婴儿能快速学习与环境互动。一个关键原因是:当我们人类看一张图片时,能在几毫秒内立即理解图片中发生了什么;而计算机看到的只是一个像素矩阵。我们需要解释这个像素矩阵,才能得出关于图像内容的假设,而这种解释是困难的。

挑战之一已经提到:当我们把一个3D场景投影成图像,然后想从图像中重建那个3D场景时,大量信息在投影过程中丢失了。我们面对的是一个病态逆过程,单个2D图像对应着许多可能的3D解释

爱德华·阿德尔森和彭特兰的“工作室隐喻”论文很好地阐释了这一点。为了解释一张2D图像在反射率、光照和形状方面的成因,画家、灯光设计师和雕塑家可能会给出三种不同但都合理的解决方案。画家可能直接在2D*面上作画;灯光设计师可能创建一组光源,将光投射到白墙上,形成完全相同的轮廓和阴影;雕塑家可能创作一个雕塑,通过其相对于入射光方向的不同倾斜角度来呈现图片中的阴影。事实上,存在无限多种解决方案,这正是计算机视觉问题如此困难和病态的原因。

以下是视觉感知面临的其他具体挑战:

  • 视角变化:同一物体,视角不同,像素矩阵会发生巨大变化。算法需要恢复这种不变性,识别出这是同一个物体。
  • 形变:许多物体是非刚性变形的,会产生新的像素组合。目标仍然是能够解释这仍是同一个物体。
  • 遮挡:物体部分被遮挡,使得识别变得困难。
  • 光照变化:光照与材质之间存在复杂的相互作用。同一场景、同一视角,在不同光照下会产生完全不同的图像,我们对场景的理解也会完全不同。
  • 运动:运动会产生模糊,使物体更难识别。同时,运动本身也是我们希望恢复的有用线索。
  • 感知与测量的差异:人类感知到的与物理测量结果可能大相径庭。例如“棋盘阴影错觉”中,A和B方格看起来颜色不同,但测量显示它们灰度值完全相同。还有“卡尼萨三角形”等错觉,表明我们需要整体地、而非局部地观察轮廓来解释场景。
  • 局部歧义与上下文:局部特征可能是模糊的,但结合整体上下文就变得清晰。有时仅从局部无法区分物体是什么,但纵观整个场景就一目了然。这也说明了我们对场景的先验知识非常强大,甚至可能导致我们在模糊图像中“看到”并不存在的物体。
  • 类内差异:同一类别的物体外观差异可能很大(例如各式各样的椅子)。算法需要将所有这些差异巨大的个体正确归类到同一类别下。
  • 类别数量庞大:世界上存在并可命名的物体类别数量极其庞大(估计在1万到3万个高级类别),如果考虑更细粒度的分类,则数量更多,这使得分类问题极具挑战性。

总结

本节课我们一起学习了计算机视觉的基本定义,它作为人工智能的核心组成部分,旨在让机器理解视觉世界。我们探讨了其广泛的应用场景以及与神经科学、计算机图形学、图像处理和机器学习等领域的紧密联系。更重要的是,我们深入分析了视觉感知之所以困难的诸多根本原因,包括病态逆问题、视角、光照、遮挡、形变等变化,以及感知与测量的差异、上下文依赖和庞大的类别数量等挑战。理解这些挑战是设计有效计算机视觉算法的第一步。

003:计算机视觉简史 📜

在本节课中,我们将简要回顾计算机视觉领域在过去约50年里的发展历程。这是一个高度浓缩且带有个人视角的总结,但希望能为你提供一些关于该领域从何而来、又将走向何方的直觉。

计算机视觉的“史前”时期

在计算机发明之前,人类感知的研究早已开始。例如,透视投影过程在15世纪就由达·芬奇描述过。约翰·海因里希·朗伯(Lambertian反射以其命名)为光度学领域做出了重要贡献。卡尔·弗里德里希·高斯则贡献了最小二乘法,这是一个在包括计算机视觉在内的所有科学领域都非常有用的工具。19世纪,查尔斯·惠斯通研究了立体视觉和产生立体图像的问题。

以下是几个重要的“史前”里程碑:

  • 达·芬奇的透视仪:一种通过在玻璃表面作画来精确捕捉透视效果的工具。
  • 达盖尔银版法(1839年):路易·达盖尔发明的首个公开可用的摄影工艺。
  • 印度大三角测量:一项持续数十年的项目,通过三角测量和手动“光束法*差”等技术,精确测量了整个印度次大陆,并证明了珠穆朗玛峰是世界最高峰。

计算机视觉研究的发展浪潮

上一节我们了解了计算机诞生前的视觉研究。现在,让我们进入更*的历史。计算机视觉研究的发展可以大致分为几个阶段:

  • 1960年代:早期方法,检测线条并拟合简单几何块来理解世界,但很快发现低级视觉比预想的更困难。
  • 1970年代:兴趣转向低级视觉研究,立体视觉、光流、从明暗恢复形状等技术得到发展。
  • 1980年代:反向传播算法的发明使神经网络复兴,首个自动驾驶模型被提出。
  • 1990年代:马尔可夫随机场和概率图模型流行,用于解决立体视觉等任务中的歧义问题。
  • 2000年代:SIFT等特征描述子和检测器出现,实现了真正的大规模运动恢复结构和三维重建。
  • 2010年代至今:神经网络在拥有大数据集的任务上超越传统方法,成为主导技术,推动了领域的快速发展和商业化。

1950-1960年代:早期探索与过高期望

上一节我们概述了发展脉络,本节我们将具体看看早期的重要工作。1957年,出现了首个立体图像相关的模拟实现,用于从航拍图像恢复数字高程模型。1958年,罗森布拉特发明了感知机,这是一个使用感知机算法训练的简单线性分类器,能够分类简单模式(如区分男女)。然而,当时对其期望过高,预言十年内将出现能行走、交谈、有意识的计算机,这并未实现。

1963年,拉里·罗伯茨在其博士论文中研究了“三维固体的机器感知”,旨在从图像线条的拓扑结构恢复物体的三维结构,以用于机器人操作。这标志着计算机视觉与机器人学的早期结合。然而,该系统非常脆弱,仅适用于简单场景。1966年,明斯基和佩珀特在麻省理工学院的暑期项目中试图“解决”计算机视觉问题,但低估了其挑战性。

1970年代:聚焦低级视觉与内在图像

上一节我们看到早期系统非常脆弱。因此,研究重点转向了更鲁棒的低级视觉方法。1970年,麻省理工学院的研究人员开发了“复制积木”演示,使用积木世界感知算法让机器人复制一组积木的排列。这促使人们认识到需要改进低级视觉(如边缘检测)。

1971年,霍恩发表了关于从明暗恢复形状的著名技术报告,研究如何从单张二维图像的 shading 信息恢复三维形状。这是一个病态问题,需要*滑性约束来正则化。公式可以表示为寻找表面法向 n 和深度 z,使得图像强度 I(x, y) 符合反射模型,例如朗伯模型:I = ρ (n · l),其中 ρ 是反射率,l 是光源方向。

1978年,内在图像被提出作为一种中间表示。其思想是将图像分解为不同的本征成分(如反射率、阴影),形成不同的二维图层,以帮助下游任务(如目标检测)对光照变化更鲁棒。

1980年代:几何基础、优化与神经网络复兴

上一节我们讨论了从单图像恢复形状的挑战。本节我们来看看利用多视图几何和优化方法的重要进展。1980年,伍德拉姆提出了光度立体视觉,通过使用多张已知或未知光源位置的图像,无需重度*滑约束即可恢复表面法向。假设朗伯表面,对于每个像素,至少需要三个不同光照方向的观测 I₁, I₂, I₃,可以求解表面法向 n

1981年,朗格-希金斯重新引入了本质矩阵,论文为《从两个投影重建场景的计算机算法》。本质矩阵 E 定义了双视图几何,将一个图像上的点映射到另一个图像上的对极线,是立体视觉技术的基石。其性质是:对于对应点 xx',满足 x'ᵀ E x = 0

同样在1981年,早期立体匹配方法通过引入动态规划(如维特比算法)来沿扫描线添加*滑性和遮挡约束,以克服歧义,但会导致扫描线间的条纹伪影。同年,霍恩和申克发表了光流领域最著名的论文《确定光流》,提出了第一个变分算法,将先验约束整合到数学框架中,以恢复稠密光流场。

1984年,离散马尔可夫随机场被用作编码立体匹配或光流等问题先验知识的方法,催生了变分推断、置信传播、图割等多种优化算法。

1980年代也是基于部件模型(如1986年的超二次曲面)流行的时期,这些模型用少量参数表示基本三维形状部件。同时,1986年,鲁梅尔哈特和威廉姆斯推广了用于训练神经网络的反向传播算法,它通过动态规划高效计算损失函数对百万级参数的梯度,至今仍是深度学习的主力算法。代码概念如下:

# 反向传播核心思想:链式法则
def backward(loss, parameters):
    grads = compute_gradient(loss, parameters) # 通过链式法则计算梯度
    update_parameters(parameters, grads) # 使用梯度更新参数

1986年,首个自动驾驶汽车在欧洲的普罗米修斯项目中得到演示,时速达40公里。1988年,卡内基梅隆大学的ALVINN成为首个使用神经网络进行自动驾驶的汽车,它直接将输入图像映射为转向控制。

1990年代:运动恢复结构、三维重建与特征提取

上一节我们看到了80年代在几何、优化和神经网络方面的基础工作。进入90年代,这些思想催生了更强大的三维视觉技术。1992年,托马斯和坎纳德发表了著名的因子分解法论文,允许从静态场景的二维图像序列中估计三维结构,在仿射情况下可通过奇异值分解求解。

1992年,迭代最*点算法被提出,用于配准两个点云,通过迭代优化刚体或非刚性变换使点云对齐。目标是最小化对应点之间的距离。

1996年,体积融合技术被引入计算机图形学,通过将表面隐式表示为空间离散场的零水*集,并聚合多个观测,来融合物体的多个局部视图。

1998年,福赛斯和卡托尔提出了基于水*集方法的多视图立体视觉,将立体视觉表述为直接优化三维表面(表示为水*集)的重建误差,并考虑了可见性,支持灵活的拓扑结构。

同样在1998年,图割算法开始流行,它是一种能有效求解包含一元(单像素)和二元(像素间)项的马尔可夫随机场能量最小化问题的算法,实现了全局推理,相比逐行扫描方法结果更一致。

1998年,莱坎等人提出了卷积神经网络,通过卷积和池化实现空间不变性,并权重共享减少参数量。但当时仅在MNIST数据集上表现良好,未引起计算机视觉社区足够重视。

1999年,布莱恩和维特实现了可变形模型用于单视图三维人脸重建,他们基于200个激光扫描人脸建立子空间模型,并拟合新图像的几何和外观。同年,尺度不变特征变换被提出,这是一种检测和描述图像中显著局部特征的算法,为图像拼接、三维重建等应用奠定了基础。

2000年代:互联网规模的重建与数据集的兴起

上一节我们看到了SIFT等特征如何赋能三维重建。本节我们来看看这些技术如何扩展到互联网规模。2006年,斯内夫利和塞利斯基的“照片旅游”论文展示了从网络照片进行大规模三维重建,关键因素是SIFT特征、强大计算资源和巧妙的大规模光束法*差管线。

2007年,Furukawa和Ponce的PMVS(基于块的多视图立体)论文首次展示了各种物体高质量、高鲁棒性的三维重建。2009年,“一日建成罗马”项目实现了从数万张网络照片重建整个城市地标的三维模型。

2011年,微软Kinect相机上市,这是一个廉价的主动式深度传感设备,虽在消费市场未完全成功,但极大地推动了机器人和视觉研究。

2012年,ImageNet大规模视觉识别挑战赛以及AlexNet的突破性表现,证明了深度神经网络在复杂真实世界数据集上的有效性,点燃了计算机视觉和深度学习的研究热潮。数据集的创建变得至关重要。以下是一些著名数据集:

  • ImageNet:用于图像分类。
  • PASCAL VOC:用于目标检测、分割。
  • MS COCO:用于目标检测、分割、字幕生成。
  • KITTI:用于自动驾驶场景理解。

2010年代至今:深度学习的统治与新兴挑战

上一节我们看到了大数据集如何推动深度学习革命。本节我们将探讨深度学习带来的具体进展和当前挑战。2014年,辛顿等人展示了深度神经网络容易被对抗样本愚弄,即对输入添加微小扰动就能导致错误分类,这引发了对模型鲁棒性的研究。

同年,生成对抗网络和变分自编码器的提出,实现了无监督学习下的逼真图像生成。随后的StyleGAN等模型在图像生成质量上达到新高。

2014年,DeepFace等模型展示了人脸识别性能达到甚至超越人类水*,这得益于传统技术与深度学习的结合。

2015年,DeepMind展示了通过深度强化学习直接从图像像素学习玩视频游戏。同年,加特伊等人的论文“使用卷积神经网络进行图像风格迁移”展示了如何将一幅图像的内容与另一幅图像的风格结合。

语义分割任务(为每个像素分配类别标签)在2015年后因全卷积网络等模型而性能大幅提升。实例如Mask R-CNN,能够同时进行目标检测和实例分割。

2017年左右,图像描述和视觉问答等新任务兴起,模型能够为图像生成句子或回答关于图像的问题,但仍存在对数据集偏差敏感和缺乏常识的问题。

三维视觉也深度融入深度学习。从使用点云、体素发展到最新的神经隐式表示,这些模型能够从单张图像预测完整的三维模型,包括几何、材质、光照和运动。

应用与未来挑战

计算机视觉技术已广泛应用于日常生活和商业产品中,例如:

  • 智能手机的人像模式。
  • Skydio 2等自主导航无人机。
  • 自动驾驶汽车(仍在发展中)。
  • 虚拟现实/增强现实设备(如HoloLens),用于头部追踪、物体检测和定位。
  • 人脸识别在安防等领域的应用。

尽管取得了巨大进展,许多挑战依然存在:

  • 数据:获取大规模、高质量标注数据集成本高昂,推动了对自监督、半监督和交互式学习的研究。
  • 准确性:在自动驾驶等安全关键领域,需要达到并超越人类的鲁棒性和准确性。
  • 可解释性:理解深度学习黑盒模型内部的运作机制。
  • 效率:许多模型,特别是三维模型,对内存和计算要求高,需要更高效的算法和表示。
  • 伦理与法律:随着技术商业化,相关的伦理、隐私和法律问题日益重要。

总结

本节课我们一起回顾了计算机视觉从早期几何方法、到低级视觉研究、再到特征工程和优化方法,最终进入以数据驱动的深度学习时代的发展简史。我们看到,许多经典思想在今天与深度学习结合后重新焕发生机。同时,领域仍面临数据、鲁棒性、可解释性、效率和伦理等诸多挑战,等待未来的研究者去探索和解决。

004:图像形成 - 基本图元与变换 🖼️➡️📐

在本节课中,我们将要学习计算机视觉的基础:图像形成过程。具体来说,我们将探讨三维场景如何投影到二维图像上。为了建立数学模型来描述这个过程,我们首先需要理解一些基本的几何图元和变换。本节课将介绍这些核心概念,特别是齐次坐标这一强大工具,它能够极大地简化几何关系的表达和计算。

基本图元与变换

上一节我们概述了图像形成的整体流程。本节中,我们来看看描述三维形状所需的基本构建块——几何图元,以及如何对它们进行变换。我们将重点介绍点、线和*面,并讨论在二维和三维空间中最基本的变换。

二维点

二维点可以用传统的非齐次坐标表示,它是一个包含两个实数标量的二维向量,用于描述图像域中的坐标。

为了更优雅地处理几何问题,我们引入齐次坐标表示。齐次坐标通过增加一个维度来扩展向量空间。对于二维点,这意味着我们使用一个三维空间,但移除了零向量,这个空间称为投影空间 P²

一个二维非齐次坐标点 x 可以转换为齐次坐标 ,方法是在其末尾添加一个 1:

x = [x, y]ᵀ  ->  x̃ = [x, y, 1]ᵀ

我们使用波浪号(~)表示这是一个齐次坐标向量。所有仅相差一个缩放因子的齐次向量被认为是等价的(即属于同一个等价类)。这意味着齐次坐标只定义到尺度

为什么需要这种看似复杂的表示?因为它带来了诸多好处:可以方便地表示无穷远点、表达*行线的交点、将多个变换组合为线性操作,并且能线性化表示对三维计算机视觉至关重要的投影变换。

要将齐次坐标 x̃ = [x̃, ỹ, w̃]ᵀ 转换回非齐次坐标,只需用前两个分量除以最后一个分量:

x = [x̃/w̃, ỹ/w̃]ᵀ

当齐次向量的最后一个分量 w̃ = 0 时,该点被称为理想点无穷远点,它无法用非齐次坐标表示。

二维线

在齐次坐标中,二维线也可以简洁地表示。一条线可以用一个齐次向量 l̃ = [a, b, c]ᵀ 表示。线上所有点 x̄ = [x, y, 1]ᵀ(即增广向量)满足以下方程:

l̃ᵀ x̄ = ax + by + c = 0

这其实就是我们熟悉的直线方程。我们可以将 归一化,使得 l = [nₓ, nᵧ, d]ᵀ,其中 n 是垂直于直线的单位法向量,d 是原点到直线的距离。

一个特殊的线是无穷远线 l̃∞ = [0, 0, 1]ᵀ,它穿过所有的无穷远点。

点与线的交互

齐次坐标的一个强大之处在于,可以非常简洁地表达点与线之间的关系。

以下是两个关键操作:

  • 两条线的交点:两条线 l̃₁l̃₂ 的交点 可以通过叉积计算:
    x̃ = l̃₁ × l̃₂
    
  • 连接两点的线:两个点 x̃₁x̃₂ 所确定的线 也可以通过叉积计算:
    l̃ = x̃₁ × x̃₂
    

这里的叉积可以表示为斜对称矩阵与向量的乘法。例如,向量 ab 的叉积 a × b 可以写为 [a]ₓ b,其中 [a]ₓa 对应的斜对称矩阵。

示例:求两条线 y=1x=2 的交点。

  • 线向量分别为 l̃₁ = [0, 1, -1]ᵀl̃₂ = [1, 0, -2]ᵀ
  • 计算叉积:x̃ = l̃₁ × l̃₂ = [2, 1, 1]ᵀ
  • 由于最后一个分量为1,可以直接读出非齐次坐标为 (2, 1),这正是两线的交点。

对于*行线,例如 x=1x=2,其交点计算结果为 [0, -1, 0]ᵀ,最后一个分量为0,表示交点在无穷远处,符合预期。

从二维到三维

三维点的表示是二维的自然延伸。

一个三维非齐次点 X = [X, Y, Z]ᵀ 对应的齐次坐标为 X̃ = [X, Y, Z, 1]ᵀ,它位于投影空间 中。同样,所有仅相差一个标量因子的齐次向量是等价的。转换方式与二维相同:

X = [X̃/Ẃ, Ỹ/Ẃ, Z̃/Ẃ]ᵀ

三维*面也可以用齐次坐标表示。一个*面由齐次向量 ṁ = [A, B, C, D]ᵀ 表示,*面上所有点 X̄ = [X, Y, Z, 1]ᵀ 满足:

ṁᵀ X̄ = AX + BY + CZ + D = 0

同样可以归一化,使得 n = [A, B, C]ᵀ 是单位法向量,D 是原点到*面的距离。无穷远*面穿过所有无穷远点。

三维线的表示稍复杂,一个常见但非最小化的表示是使用线上的两个点 PQ 进行参数化:L(λ) = (1-λ)P + λQ。它有4个自由度,但用了6个参数。更高效的表示法(如两*面交线或普吕克坐标)可在相关教材中找到。

二次曲面

三维空间中,二次曲面(如球体、椭球体、抛物面、双曲面)可以用齐次坐标下的二次方程表示:

X̃ᵀ Q X̃ = 0

其中 Q 是一个4x4的对称矩阵。改变 Q 可以得到不同的二次曲面。这些曲面在多视图几何中很有用,也可作为紧凑的基元来建模和理解复杂场景。

二维变换

理解了基本图元后,我们来看看如何对它们进行变换。变换在计算机视觉中至关重要,用于描述相机运动、图像配准等。我们将从最简单到最复杂,介绍一个变换层次结构。

所有变换都可以用作用于齐次坐标的矩阵来表示,这使得变换的组合和求逆变得非常容易。

以下是主要的二维变换类型:

  1. *移变换

    • 描述:将物体移动到新位置。
    • 自由度:2 (tₓ, tᵧ)。
    • 矩阵形式
      [ I   t ]
      [ 0   1 ]
      
      其中 I 是2x2单位矩阵,t 是*移向量。
    • 保持性质:欧氏距离、角度、*行性、直线性。
  2. 欧氏变换(刚体变换)

    • 描述:*移 + 旋转。
    • 自由度:3 (旋转角 θ, tₓ, tᵧ)。
    • 矩阵形式
      [ R   t ]
      [ 0   1 ]
      
      其中 R 是2x2旋转矩阵(RᵀR = I, det(R)=1)。
    • 保持性质:欧氏距离、角度、*行性、直线性。
  3. 相似变换

    • 描述:*移 + 旋转 + 均匀缩放。
    • 自由度:4 (s, θ, tₓ, tᵧ)。
    • 矩阵形式
      [ sR   t ]
      [ 0    1 ]
      
    • 保持性质:角度、*行性、直线性(不保持距离)。
  4. 仿射变换

    • 描述:*移 + 线性变换(可包含缩放、剪切、旋转)。
    • 自由度:6 (一个任意的2x2矩阵 A 的4个元素 + tₓ, tᵧ)。
    • 矩阵形式
      [ A   t ]
      [ 0   1 ]
      
    • 保持性质:*行性、直线性(不保持角度和距离)。
  5. 投影变换(单应性变换)

    • 描述:最一般的线性齐次变换。
    • 自由度:8 (3x3齐次矩阵,定义到尺度)。
    • 矩阵形式
      H = [ h₁₁ h₁₂ h₁₃ ]
          [ h₂₁ h₂₂ h₂₃ ]
          [ h₃₁ h₃₂ h₃₃ ]
      
      变换为:x̃‘ = H x̃
    • 保持性质:直线性(不保持*行性、角度、距离)。

这个变换集合形成了一个嵌套群结构,更严格的变换(如欧氏变换)是更一般变换(如仿射变换)的子集。所有变换都保持其下方变换所保持的性质。

共向量的变换

我们知道了如何变换点(x̃‘ = H x̃)。那么像直线这样的共向量如何变换呢?

设一条直线由 定义,变换后的直线为 l̃’。对于变换后的点 x̃’,它仍在变换后的线上,满足 l̃’ᵀ x̃’ = 0。代入 x̃’ = H x̃,得到 l̃’ᵀ H x̃ = 0。由于变换前有 l̃ᵀ x̃ = 0,因此可以推导出:

l̃’ = H⁻ᵀ l̃

即,直线(或法向量等共向量)的变换矩阵是点变换矩阵的逆的转置

单应性矩阵估计

在实际应用中,我们经常需要从图像对应点中估计变换矩阵。我们以最一般的投影变换(单应性)为例。

给定两组二维点之间的对应关系 {xᵢ ↔ xᵢ’},它们通过一个单应性矩阵 H 相关联:x̃ᵢ’ = H x̃ᵢ。由于 H 有8个自由度,而每个点对应提供两个约束(x和y坐标),因此我们至少需要4组非共线的对应点来求解。

为了处理齐次向量的尺度不确定性,我们将方程改写为叉积形式:

x̃ᵢ’ × (H x̃ᵢ) = 0

这确保了向量方向一致,而不关心其长度。这个方程可以转化为关于 H 元素的线性方程组。每个点对应 i 贡献两个线性方程。将所有方程堆叠起来,形成一个形如 A h = 0 的方程组,其中 h 是将 H 矩阵按行展开成的9维向量。

我们需要在约束 ||h|| = 1 下最小化 ||A h||²。这可以通过求解奇异值分解(SVD) 来解决:h 是矩阵 A最小奇异值对应的右奇异向量(即 A = UDVᵀV 的最后一列)。这种方法称为直接线性变换(DLT)算法

应用示例:图像拼接
我们可以利用单应性估计来创建全景图。假设从同一视点拍摄了两张有重叠区域的图像:

  1. 在两幅图像中手动或自动选取至少4组对应点。
  2. 使用DLT算法估计将第一幅图像映射到第二幅图像坐标系的单应性矩阵 H
  3. 利用 H 对第一幅图像进行透视变换(扭曲),使其与第二幅图像对齐。
  4. 将变换后的图像与第二幅图像融合,得到更宽视野的全景图。这是智能手机全景拍照功能的基本原理。

本节课中我们一起学习了计算机视觉中图像形成的几何基础。我们首先介绍了齐次坐标这一核心概念,它通过升维和尺度等价性,优雅地表示了点、线、面等基本图元,并能处理无穷远元素。接着,我们探讨了从*移、欧氏变换到投影变换的层次结构,了解了它们各自的矩阵表示和几何不变性。最后,我们学习了如何从点对应关系中估计单应性矩阵,并将其应用于图像拼接等实际任务。掌握这些基本的几何图元和变换,是理解后续更复杂的相机模型和三维重建技术的基石。

006:光度图像形成 📸

在本节课中,我们将要学习光度图像形成过程。我们已经讨论了光线如何在空间中传播,现在我们将探讨光线到达传感器*面后,如何最终形成我们看到的像素强度和颜色图像。

从场景到图像

当我们拍摄一个场景时,我们从一个特定的视点(即相机的位置)观察一个光场。这个光场是光线在场景中传播的结果:光线从光源(如灯泡或太阳)发出,穿过场景,照射到物体表面,从表面反射,最终到达传感器*面。

为了精确地建模光线从表面反射的过程,我们使用一个称为渲染方程的数学工具。这是计算机图形学中最基础的方程之一。

理解渲染方程

为了理解这个方程的基础,我们定义几个变量:

  • P 为一个三维表面点。
  • V 为观察方向(从表面点指向相机的方向)。
  • ω_i 为入射光方向。
  • n 为该表面点处的法线。

渲染方程描述了从所有可能方向到达点 P 的、波长为 λ 的光线,有多少被反射到了观察方向 V 中。

其核心公式如下:

L_o(P, V, λ) = L_e(P, V, λ) + ∫_Ω f_r(P, ω_i, V, λ) L_i(P, ω_i, λ) (n · ω_i) dω_i

让我们分解这个公式:

  • L_o(P, V, λ):从点 P 沿方向 V 出射的、波长为 λ 的光的辐射亮度。
  • L_e(P, V, λ):点 P 自身沿方向 V 发射的光(例如,如果该点本身是光源)。
  • ∫_Ω:对以点 P 法线为中心的上半球面 Ω 上所有可能的入射方向 ω_i 进行积分。
  • f_r(P, ω_i, V, λ)双向反射分布函数。它决定了在点 P,对于给定的入射方向 ω_i 和出射方向 V,波长为 λ 的光有多少被反射。这是描述材料反射特性的核心函数。
  • L_i(P, ω_i, λ):从方向 ω_i 入射到点 P 的、波长为 λ 的光的辐射亮度。
  • (n · ω_i):法线 n 与入射方向 ω_i 的点积。这个项模拟了衰减效应:当光线以非常浅的角度照射表面时,单位面积接收到的光能更少;当光线垂直照射时,接收到的光能最多。

双向反射分布函数

BRDF 描述了材料如何反射光线。典型的 BRDF 包含两个主要分量:漫反射镜面反射

以下是这两种反射特性的说明:

  • 纯漫反射表面:入射光线被均匀地反射到所有方向。这导致 shading(明暗)随着表面法线的变化而*滑变化。例如:石膏、粗糙的墙面。
  • 纯镜面反射表面:入射光线像镜子一样,被反射到一个特定的方向(即理想镜面反射方向)。例如:完美的镜子。
  • 真实表面:通常是漫反射和镜面反射的混合。例如:光滑的塑料、上了清漆的木头,它们既有均匀的底色(漫反射),也有高光点(镜面反射)。

BRDF 可以非常复杂,它们可能在物体表面不同位置变化(空间变化),并且可能包含像菲涅尔效应这样的现象。菲涅尔效应是指,从表面反射的光量取决于观察角度(例如,看水面时,远处反射强像镜子,*处则能看清水底)。

全局光照

光线在场景中通常不会只反射一次。它可能从一个表面反射到另一个表面,然后再进入相机。模拟这种多次反射的效果被称为全局光照。全局光照对于生成真实感图像至关重要,它能产生柔和的阴影、颜色渗透(例如,红墙旁边的白墙会略带红色)等效果。没有全局光照的渲染看起来会不自然且生硬。

上一节我们介绍了光线与表面交互的基本原理,本节中我们来看看相机如何捕捉这些光线。

为什么需要镜头?

我们讨论过针孔相机模型,它也是带镜头相机的良好*似。但为什么相机不直接用针孔,而要用复杂的镜头系统呢?

原因在于权衡:针孔大小直接影响成像质量。

  • 针孔非常小:进光量极少,需要极长的曝光时间,导致运动模糊或相机抖动模糊。此外,过小的孔还会产生衍射效应,同样导致图像模糊。
  • 针孔稍大:一个物点发出的多条光线会通过针孔的不同部位,在像*面上形成一个弥散斑,导致图像模糊

因此,为了在合理曝光时间内获得足够亮且清晰的图像,我们需要镜头来汇聚光线。

薄透镜模型

最基本的镜头模型是薄透镜模型。它假设透镜很薄,且两面为球面。这个模型常用来*似更复杂的真实镜头系统。

薄透镜有几个关键特性:

  1. 透镜两侧各有一个焦点 F
  2. *行于主光轴的光线,穿过透镜后汇聚于另一侧的焦点。
  3. 穿过透镜中心的光线,方向不变。

利用这些特性和相似三角形原理,我们可以推导出最重要的透镜公式之一:

1 / d_o + 1 / d_i = 1 / f

其中:

  • d_o:物距(物体到透镜的距离)。
  • d_i:像距(透镜到清晰成像*面的距离)。
  • f:透镜的焦距。

这个公式建立了物距、像距和焦距之间的关系。对于给定的镜头(固定 f)和对焦距离(d_o),我们可以计算出需要将传感器放在多远(d_i)才能获得清晰图像。反之亦然。

当物距趋于无穷远时,d_i ≈ f。这就是为什么焦距为 f 的镜头,可以*似看作位于传感器前 f 距离处的针孔。

景深与光圈

如果传感器*面不在公式计算出的正确像距上,一个物点就会在传感器上形成一个模糊的圆斑,称为弥散圆。当弥散圆的大小超过一个像素时,图像就会显得模糊。

控制弥散圆大小(从而控制清晰范围)的一个关键部件是光圈。光圈是镜头内部一个可调节大小的孔。

以下是光圈的影响:

  • 光圈大小:用F 值表示,F 值 = 焦距 / 光圈孔径直径。F 值越小,光圈孔径越大
  • 景深:图像中看起来清晰的距离范围。
    • 大光圈:F 值小(如 f/1.4),景深,背景虚化效果强。
    • 小光圈:F 值大(如 f/16),景深,前景和背景都更清晰。
  • 曝光:大光圈进光多,曝光时间可缩短;小光圈进光少,需要更长的曝光时间。

镜头像差

真实镜头并不完美,会产生各种像差,影响图像质量。两种常见的像差是:

  1. 色差:由于玻璃的折射率随光的波长(颜色)而变化,不同颜色的光会被折射到略微不同的方向。这导致它们无法聚焦在同一个*面上,结果在图像边缘产生彩色镶边和模糊。

    • 解决方案:使用由多片不同材质、不同形状透镜组成的复合镜头来校正。
  2. 暗角:图像边缘比中心暗的现象。它由两部分原因造成:

    • 自然暗角:由于光线以更大角度入射到传感器边缘,导致有效进光量减少。
    • 机械暗角:镜头筒或内部元件遮挡了射向传感器边缘的部分光束。
    • 解决方案:可以在后期处理中通过校准来减轻或消除暗角。

本节课中我们一起学习了光度图像形成的核心概念。我们从渲染方程开始,理解了光线如何与表面交互,包括漫反射镜面反射,以及全局光照的重要性。然后,我们转向相机内部,探讨了为什么需要镜头,学习了薄透镜模型及其成像公式。最后,我们分析了影响成像质量的关键因素:景深光圈的控制,以及色差暗角等常见镜头像差。这些知识是理解数字图像如何从真实世界的光线中产生的基石。

008:运动恢复结构 - 预备知识 🎥

在本节课中,我们将学习如何从多张图像中重建三维模型。这是计算机视觉中的一个核心任务,称为“运动恢复结构”。作为开始,我们需要掌握两个重要的预备知识:相机校准和特征检测与描述。

上一节我们讨论了图像形成过程,即三维点如何投影到二维传感器*面。本节中,我们将利用这些知识,从观察同一静态场景的多张图像中构建三维模型。

相机校准 📷

运动恢复结构技术,特别是希望获得度量重建时,相机校准是一个基本前提。为了知道光线如何从相机中心发出或如何投影到相机图像*面,首先需要了解相机的参数。

相机校准是寻找相机内参和外参的过程。最常用的方法是使用已知的校准目标,例如棋盘格图案。

以下是相机校准的基本工作流程:

  1. 准备与采集:打印棋盘格并将其粘贴在非常*坦的表面上。然后,以不同姿态拍摄该棋盘格,确保棋盘格始终完全可见,并能覆盖足够的姿态空间以获得良好的观测数据。
  2. 特征检测:对于每一张图像,检测棋盘格的角点,并使用亚像素精度算法对其进行细化。
  3. 参数估计:估计相机的内参和外参。这里的外参指的是棋盘格相对于相机坐标系的姿态。这是一个可行的优化问题,因为观测数据(每个角点提供X和Y两个坐标观测值)远多于待估计的参数数量。

直接非线性优化所有参数是通过最小化重投影误差完成的:将当前估计的三维点投影到图像上,并计算其与图像中检测到的点之间的欧几里得距离,然后尝试最小化这个距离。然而,不能随机初始化所有参数,否则容易陷入局部最小值。因此,需要一个良好的初始化。

例如,张正友等人提出的“一种灵活的新相机标定技术”论文,通过从观测数据构建线性系统,为焦距和主点提供了粗略但优于随机猜测的初始化估计。以此为基础,可以推导出棋盘格姿态的良好初始估计。这些共同构成了非线性优化过程的初始化值,通常使用像Levenberg-Marquardt这样的基于梯度的技术来优化所有参数。

备注:存在多种用于不同设置和镜头模型的校准技术。这些方法在算法、假设和使用的校准目标类型上各不相同。但最常见的技术是使用棋盘格或类似图案的方法。

现在我们已经校准了相机,接下来看看如何在不同图像中找到对应的点。

特征检测与描述 🔍

为了获得三维重建,我们首先需要在图像中找到彼此对应的点。我们需要找到显著的、独特的、并且能在另一张图像中轻松检测到的点,这些被称为点特征。

点特征描述了图像中局部显著区域的外观。它们可用于描述和匹配从不同视角拍摄的图像。

以下是理想特征应具备的属性:

  • 不变性:特征应对透视效应和光照变化具有不变性。这意味着即使视角或光照条件改变,同一物理点的特征描述也应保持相似。
  • 区分性:特征应具有高度的区分性。同一物理点的特征向量应非常相似,而不同点的特征向量应有明显差异。

简单的RGB或强度图像块不具备这些属性。因此,我们需要特征检测和描述方法。其中最著名的方法之一是SIFT(尺度不变特征变换)。

SIFT通过构建尺度空间来实现尺度不变性。它迭代地用高斯滤波器模糊图像,形成尺度金字塔。然后,计算相邻模糊图像之间的差异,得到高斯差分图像。在高斯差分尺度空间中寻找极值点(与周围空间邻域和尺度邻域比较),这些点对应于图像中的斑点(blob),并在多个尺度上被检测到。

检测到兴趣点及其对应尺度后,SIFT会计算该尺度区域的梯度,并根据主导梯度方向对齐描述符区域,从而实现旋转不变性。接着,在旋转后的区域内划分子区域,计算每个子区域内的梯度方向直方图,并将这些直方图连接成一个128维的特征向量。使用直方图使得特征对光照变化和轻微的透视变形(如*移)更具鲁棒性。

继SIFT之后,还提出了多种特征检测器和描述符,如SURF、BRISK、FAST以及*年来的基于深度学习的方法。然而,SIFT因其不变性和鲁棒性具有开创性意义,至今仍被广泛使用。

特征匹配 🤝

当我们有两张图像并在其中检测到特征后,就可以进行特征匹配。通常使用高效的最*邻搜索技术(如构建搜索树)来为第一张图像中的每个查询特征,在第二张图像的特征描述子向量空间(如128维空间)中寻找L2距离最*的匹配。

由于匹配可能存在歧义,通常通过计算最*邻距离与次*邻距离的比值来过滤模糊匹配。如果该比值很大(例如接*0.8),表明最*邻匹配可能并不正确,因为次优匹配的质量几乎一样好。比值越接*1,歧义性越大。

在本节中,我们介绍了运动恢复结构所需的两项关键预备知识:相机校准与特征检测、描述及匹配。相机校准帮助我们了解成像几何,而稳定的特征及其匹配则是后续估计场景几何的基础。下一节,我们将利用这些匹配好的特征点,开始探讨两帧之间的运动恢复结构。

009:双视图运动恢复结构(Structure-from-Motion)教程 🎥

在本节课中,我们将要学习双视图运动恢复结构。这是最基础的设置,我们仅有两张从不同视角拍摄的图像,目标是找出两个相机之间的相对运动,以及图像中观测到的投影点所对应的三维空间点的位置。

极线几何基础

上一节我们介绍了特征匹配,本节中我们来看看如何利用匹配的特征点来恢复相机姿态和三维结构。所需的关系由双视图极线几何描述。

如上图所示,我们有两个相机。C1C2 分别是第一和第二相机的光心,RT 表示两个相机之间的相对姿态(旋转和*移)。一个三维点 X 被投影到左图像上的像素 x̄₁ 和右图像上的像素 x̄₂

三维点 X 和两个相机光心 C1C2 共同构成了一个*面,称为极*面。由于投影是线性的,像素点 x̄₁x̄₂ 也恰好位于这个极*面上。

极线几何的一个重要性质是,它极大地简化了特征点匹配的搜索空间。如果我们已知极线几何,要为左图像中的某个特征点 x̄₁ 在右图像中寻找对应点,我们无需在整个二维图像域中搜索,而只需沿着一条特定的线——即极线——进行搜索。这条极线是极*面与右图像*面的交线。反之亦然。

一旦我们通过相机标定知道了相机的内参矩阵 K,以及通过某种方法恢复了相对姿态 RT,寻找对应点就变得容易得多。然而,为了恢复极线几何本身,我们首先需要在不知道几何关系的情况下,在全图范围内进行特征匹配,这是一个更困难的问题。

所有可能的极线都会通过图像*面上的一个特殊点,称为极点。左图像和右图像各有一个极点,它们是相机基线(连接两个光心的线)与各自图像*面的交点。

极线约束与本质矩阵

现在的问题是,我们如何用数学公式表达这种关系,并从中恢复出几何参数?

我们从已知相机的内参矩阵 K₁K₂ 开始。对于一个像素坐标 (齐次坐标),我们可以通过乘以内参矩阵的逆来得到该像素在相机坐标系下的射线方向

x̃ = K⁻¹ x̄

这个射线方向与三维点 X 的方向是成比例的:X ∝ x̃

同一个三维点 X 在两个相机坐标系下的坐标 X₁X₂ 通过刚体变换相关联:

X₂ = R X₁ + T

结合射线方向的表达式,并经过一系列的数学推导(包括叉乘和点乘运算),我们可以得到一个核心约束,即极线约束

x̃₂ᵀ E x̃₁ = 0

其中,矩阵 E 被称为本质矩阵,其定义为:

E = [T]ₓ R

这里 [T]ₓ 是*移向量 T 的反对称矩阵。这个公式描述了左右图像中对应点的射线方向必须满足的关系。

本质矩阵 E 将一个图像中的点映射到另一个图像中的极线。具体来说:

  • 左图像中点 x̃₁ 在右图像中对应的极线为:l₂ = E x̃₁
  • 右图像中点 x̃₂ 在左图像中对应的极线为:l₁ = Eᵀ x̃₂

极点也可以通过本质矩阵求得:

  • 右图像的极点 e₂E 的左零空间向量(对应奇异值为0的左奇异向量)。
  • 左图像的极点 e₁E 的右零空间向量(对应奇异值为0的右奇异向量)。

从对应点恢复本质矩阵

那么,我们如何从图像对应点中恢复本质矩阵 E 呢?

假设我们有 n 对通过SIFT等特征匹配得到的对应点 (x̄₁⁽ⁱ⁾, x̄₂⁽ⁱ⁾)。对于每一对对应点,我们都可以根据极线约束得到一个方程:

(x̄₂⁽ⁱ⁾)ᵀ F x̄₁⁽ⁱ⁾ = 0

这里我们暂时使用像素坐标和基础矩阵 F。当我们已知相机内参时,基础矩阵 F 与本质矩阵 E 的关系为:

F = K₂⁻ᵀ E K₁⁻¹

如果我们已经对图像坐标进行了归一化(即 x̃ = K⁻¹ x̄),那么我们就可以直接使用本质矩阵的约束 x̃₂ᵀ E x̃₁ = 0

将方程展开,我们会得到一个关于 E 的9个元素的线性齐次方程。由于 E 是齐次的(尺度不确定),我们可以通过约束其Frobenius范数为1来固定尺度。以下是求解步骤:

  1. 构建线性系统:对于每一对归一化后的对应点 (x̃₁, x̃₂),根据方程 x̃₂ᵀ E x̃₁ = 0 可以写出一个形如 A e = 0 的方程,其中 e 是将 E 矩阵按行堆叠成的9维向量。
  2. 使用SVD求解:将所有 n 对点对应的方程堆叠起来,形成一个 n×9 的矩阵 A。我们对 A 进行奇异值分解:A = U Σ Vᵀ
  3. 取最小奇异值对应的右奇异向量:方程 A e = 0 在约束 ||e||=1 下的解,就是 V 的最后一列(对应最小奇异值,理想情况下应为0),将其重塑为 3×3 的矩阵 E
  4. 强制本质矩阵的秩为2:由于噪声,上一步得到的 E 可能满秩。我们对其再次进行SVD:E = U Σ Vᵀ,然后将奇异值矩阵 Σ 修正为 diag(σ₁, σ₂, 0),最后重构本质矩阵:E‘ = U Σ’ Vᵀ

重要提示:在实际应用中,直接使用像素坐标会导致数值不稳定。Hartley提出的归一化八点算法建议先将图像坐标归一化(*移使其均值为0,缩放使其各方向方差为1),再进行上述计算,最后将结果反归一化。这能显著提高算法的鲁棒性。

本质矩阵有5个自由度(旋转3个,*移方向2个),因此理论上最少只需要5对匹配点即可求解,但八点算法因其简单和稳定性而被广泛使用。

从本质矩阵恢复旋转和*移

在得到本质矩阵 E 后,我们可以从中分解出旋转矩阵 R 和*移向量 T 的方向(尺度无法确定)。

  1. 恢复*移方向 T:*移向量 T 的方向 (单位向量)是 E 的左零空间向量,即SVD分解 E = U Σ Vᵀ 中,U 的最后一列(对应最小奇异值)。
  2. 恢复旋转矩阵 R:旋转矩阵 R 的恢复稍复杂,通常有两种可能的 R 和两种可能的 T 方向组合,共四种解。需要通过三角化一个点并检查其深度(是否在两个相机前方)来选出唯一正确的物理解。具体公式和推导可参考相关教材(如Hartley & Zisserman 的 Multiple View Geometry)。

三角化:恢复三维点坐标

在恢复了相机的相对姿态 (R, T) 和内参 K 之后,我们就可以通过三角化来恢复三维空间点的坐标 X

理想情况下,从两个相机光心出发的射线 C₁x̄₁C₂x̄₂ 应该在三维空间相交于一点 X。但由于特征点定位存在噪声,这两条射线通常并不严格相交。

因此,我们的目标是找到一个三维点 X,使得它投影回两个图像上的位置,与观测到的特征点位置之间的重投影误差最小。

以下是两种主要方法:

1. 直接线性变换法
对于每个相机,投影方程可以写为:λ x̄ = P X,其中 P = K [R|T] 是投影矩阵,λ 是深度尺度因子。
通过叉乘消去尺度因子 λ,可以得到两个关于 X 的线性方程。对于两个视图,我们可以得到四个方程,构成一个齐次线性系统 A X = 0。通过对 A 进行SVD,取最小奇异值对应的右奇异向量作为 X 的解。此方法快速,但不是最优的(在重投影误差意义下)。

2. 最小化重投影误差(黄金标准)
这是最优的方法,通过求解以下非线性最小二乘问题来估计 X

minₓ Σᵢ || π(Pᵢ, X) - x̄ᵢ ||²

其中 π(P, X) 是将三维点 X 用投影矩阵 P 投影到图像上的函数。这个问题可以使用迭代优化算法(如Levenberg-Marquardt算法)求解,能得到在测量噪声为高斯分布时的最大似然估计。

三角化的精度受相机相对姿态的影响很大。以下是两种典型情况:

  • 基线宽:相机视角差异大,三角化精度高(不确定性区域小),但特征匹配困难。
  • 基线窄:相机视角相似,特征匹配容易,但三角化精度低(不确定性区域呈细长状)。

基础矩阵

如果相机内参 K 未知,我们就不能使用本质矩阵 E,而需要使用基础矩阵 F。基础矩阵直接关联两个图像像素坐标之间的关系:

x̄₂ᵀ F x̄₁ = 0

基础矩阵 F 与本质矩阵 E 的关系为:F = K₂⁻ᵀ E K₁⁻¹。基础矩阵也是一个 3×3 的秩为2的矩阵。我们可以使用与八点算法类似的方法直接从像素对应点中估计 F

然而,仅凭基础矩阵只能得到一个投影重建,即三维结构恢复到一个未知的投影变换(射影变形)之下,而不是真实的度量重建。如果需要度量重建,必须额外知道相机的内参信息。

总结

本节课中我们一起学习了双视图运动恢复结构的核心流程:

  1. 特征提取与匹配:获取两幅图像之间的对应点。
  2. 估计极线几何
    • 若已知内参,估计本质矩阵 E,并分解得到相对旋转 R 和*移方向 T
    • 若未知内参,估计基础矩阵 F,得到投影重建。
  3. 三角化:利用恢复的相机姿态和对应点,通过最小化重投影误差来重建三维点的坐标。

我们了解了极线几何如何将对应点搜索从二维降低到一维,掌握了通过SVD求解本质矩阵/基础矩阵的归一化八点算法,并学习了从这些矩阵中恢复运动参数以及通过三角化恢复结构的基本原理。这些概念是后续学习多视图立体视觉和密集三维重建的基础。

010:运动恢复结构 - 矩阵分解法 🧩

在本节课中,我们将要学习一种名为“矩阵分解法”的经典技术,用于从多张图像中同时恢复相机运动和三维结构。这种方法由Tomasi和Kanade提出,在正射投影的简化假设下,能提供一个优雅的闭式解。

到目前为止,我们讨论了如何从两个视图获得对极几何。然而,理想情况下,我们希望通过对场景的多个视图进行联合优化,来同时获得相机姿态和三维重建,以最小化重投影误差。这正是我们接下来要探讨的内容。

问题设定与核心思想

首先,我们来看看如何利用超过两个视图进行运动恢复结构。假设我们有一个测量矩阵 W,它包含了被追踪特征点的图像坐标。具体来说,我们有 n 个帧(或相机)和 p 个特征点。例如,我们可能有100个特征点,它们被10个相机连续追踪到。我们假设所有特征点在所有相机中都是可见的(即完整的特征轨迹)。

给定这些观测值,我们的目标是在正射投影的假设下,同时恢复相机运动和三维结构(即与观测轨迹对应的三维点集)。事实证明,对于这种具有完整特征轨迹的正射投影简化设置,我们可以找到一个闭式解。

下图展示了这个过程:在底部,我们有一个图像序列,我们检测并追踪特征点(例如使用光流法),从而在二维空间中得到这些特征轨迹。然后,我们重建出正射相机的相机*面和三维点结构。

正射投影模型

那么,这是如何工作的呢?在正射投影下,一个三维点 X_p 映射到第 i 帧图像中的一个像素,其方式如下:

首先,我们取该三维点(在世界坐标系中表示),并减去相机坐标系相对于世界原点的*移 T_i。这样,我们就将该点表达在了相机坐标系中。然后,我们只需将该点投影到该坐标系的 x 轴和 y 轴上,即可得到像素的 xy 坐标。

为了消除尺度模糊性,我们不失一般性地假设三维点云是围绕世界坐标系中心分布的(即点云中心在原点)。这是一个我们做出的假设。

构建测量矩阵

现在,让 x_ipy_ip 表示特征点 p 在第 i 帧中的二维位置。我们对每帧图像中的特征点进行中心化处理(使其均值为零),并将它们收集起来,形成所谓的测量矩阵

我们不仅对要恢复的三维点进行中心化以消除模糊性,还在处理之前对图像坐标中的点进行中心化。中心化后的坐标表示为:

  • $\tilde{x}{ip} = x - \frac{1}{p} \sum_{q=1}^{p} x_{iq}$
  • $\tilde{y}{ip} = y - \frac{1}{p} \sum_{q=1}^{p} y_{iq}$

然后,我们将这些测量值堆叠成一个大矩阵 (注意:这里的波浪号表示中心化坐标,不是齐次坐标):

  • 是一个 2n × p 的矩阵。
  • 上半部分是所有帧中所有点的 x 坐标。
  • 下半部分是所有帧中所有点的 y 坐标。

线性关系与低秩性

根据正射投影公式和中心化假设,我们可以推导出一个简单的线性关系。中心化的图像 x 坐标满足:
$\tilde{x}_{ip} = \mathbf{u}_i^T \mathbf{X}_p$
其中,$\mathbf{u}i$ 是第 i 个相机坐标系 x 轴的方向向量(单位向量)。类似地,对于 y 坐标有:
$\tilde{y}
= \mathbf{v}_i^T \mathbf{X}_p$
其中,$\mathbf{v}_i$ 是第 i 个相机坐标系 y 轴的方向向量。

因此,整个测量矩阵可以写为一个矩阵乘积:
$\mathbf{\tilde{W}} = \mathbf{R} \mathbf{X}$
其中:

  • $\mathbf{R}$ 是一个 2n × 3 的矩阵,其行由所有相机的 $\mathbf{u}_i$ 和 $\mathbf{v}_i$ 向量堆叠而成。这代表了相机运动(旋转)。
  • $\mathbf{X}$ 是一个 3 × p 的矩阵,其列是所有三维点 $\mathbf{X}_p$。这代表了场景结构。

这是一个非常简洁的线性关系。在无噪声的情况下,矩阵 R(秩最多为3)和 X(秩最多为3)的乘积,因此其秩最多为 3,是一个低秩矩阵。

处理噪声与奇异值分解

然而,在实际观测中,由于存在噪声,测量矩阵 Ŵ(我们实际得到的)通常是满秩的。因此,我们需要从满秩的 Ŵ 中找到一个秩为3的最佳*似矩阵

这可以通过对 Ŵ 进行奇异值分解 来实现。我们对 Ŵ 进行SVD分解:
$\mathbf{\hat{W}} = \mathbf{U} \boldsymbol{\Sigma} \mathbf{V}^T$
然后,我们只保留最大的三个奇异值及其对应的奇异向量,构造出秩为3的*似矩阵:
$\mathbf{\tilde{W}} \approx \mathbf{U}_3 \boldsymbol{\Sigma}_3 \mathbf{V}_3^T$
其中 $\mathbf{U}_3$、$\boldsymbol{\Sigma}_3$、$\mathbf{V}_3$ 是仅包含前三个分量的截断矩阵。

由此,我们可以得到初始的运动和结构估计:
$\mathbf{\hat{R}} = \mathbf{U}_3 \boldsymbol{\Sigma}_3^{1/2}$
$\mathbf{\hat{X}} = \boldsymbol{\Sigma}_3^{1/2} \mathbf{V}_3^T$

解决模糊性:度量约束

然而,上述分解不是唯一的。存在一个任意的 3×3 可逆矩阵 Q,使得:
$(\mathbf{\hat{R}} \mathbf{Q}) (\mathbf{Q}^{-1} \mathbf{\hat{X}}) = \mathbf{\hat{R}} \mathbf{\hat{X}} = \mathbf{\tilde{W}}$
即,我们得到的是同一个 ,但 RX 被一个未知的变换 Q 所扭曲。

为了找到正确的 Q,我们需要利用相机运动矩阵 R 的内在几何约束。回想一下,R 的行是相机坐标轴的方向向量 $\mathbf{u}_i$ 和 $\mathbf{v}_i$。它们满足以下度量约束

  1. 每个轴都是单位向量:$|\mathbf{u}_i| = 1$, $|\mathbf{v}_i| = 1$。
  2. 同一相机的两个轴相互正交:$\mathbf{u}_i \cdot \mathbf{v}_i = 0$。

这些约束可以转化为关于矩阵 $\mathbf{G} = \mathbf{Q} \mathbf{Q}^T$ 的线性方程组。以下是具体步骤:

  • 对于每个相机 i,我们有:
    • $(\mathbf{\hat{r}}{2i-1} \mathbf{Q}) (\mathbf{Q}^T \mathbf{\hat{r}}^T) = 1$ (对应 $|\mathbf{u}_i| = 1$)
    • $(\mathbf{\hat{r}}{2i} \mathbf{Q}) (\mathbf{Q}^T \mathbf{\hat{r}}^T) = 1$ (对应 $|\mathbf{v}_i| = 1$)
    • $(\mathbf{\hat{r}}{2i-1} \mathbf{Q}) (\mathbf{Q}^T \mathbf{\hat{r}}^T) = 0$ (对应 $\mathbf{u}_i \cdot \mathbf{v}_i = 0$)
  • 这里 $\mathbf{\hat{r}}_k$ 是矩阵 $\mathbf{\hat{R}}$ 的第 k 行。

通过求解这些方程,我们可以得到 $\mathbf{G}$,然后通过乔列斯基分解得到 $\mathbf{Q}$。最后,我们得到正确的解:
$\mathbf{R} = \mathbf{\hat{R}} \mathbf{Q}$
$\mathbf{X} = \mathbf{Q}^{-1} \mathbf{\hat{X}}$

算法总结与评价

以下是Tomasi-Kanade矩阵分解法的步骤总结:

  1. 输入:包含噪声的完整特征轨迹测量矩阵 Ŵ(2n × p)。
  2. 中心化:对每帧图像中的特征点坐标进行中心化,得到
  3. SVD与低秩*似:对 进行奇异值分解,并保留前三个奇异值和向量,得到秩为3的*似。
  4. 初始分解:计算 $\mathbf{\hat{R}} = \mathbf{U}_3 \boldsymbol{\Sigma}_3^{1/2}$ 和 $\mathbf{\hat{X}} = \boldsymbol{\Sigma}_3^{1/2} \mathbf{V}_3^T$。
  5. 求解度量约束:利用 $\mathbf{\hat{R}}$ 行的单位向量和正交约束,建立并求解关于 $\mathbf{G} = \mathbf{Q}\mathbf{Q}^T$ 的线性方程组,进而通过分解得到 $\mathbf{Q}$。
  6. 消除模糊性:计算最终解 $\mathbf{R} = \mathbf{\hat{R}} \mathbf{Q}$ 和 $\mathbf{X} = \mathbf{Q}^{-1} \mathbf{\hat{X}}$。
  7. 输出:相机运动矩阵 R 和三维结构矩阵 X

该算法的优点

  • 是闭式解,计算速度快。
  • 没有局部极小值问题。
  • 解确定到一个全局旋转(这是所有运动恢复结构问题的固有模糊性)。

该算法的局限性

  • 假设正射投影,这在真实透视相机中是一个*似。
  • 要求完整的特征轨迹,即每个特征点必须在所有帧中都可见。在实际中,由于遮挡或移出视野,这很难满足。
  • 对于大规模场景重建,视角覆盖有限,此假设尤其不成立。

扩展与现代方法

尽管有这些限制,矩阵分解法仍然非常重要:

  • 处理缺失数据:可以通过迭代的矩阵补全技术,应用于特征轨迹不完整的场景。
  • 扩展到透视投影:存在一些扩展算法(如Christoph H.的算法),先进行正射重建,然后迭代地校正透视效应。
  • 作为初始化:分解法的结果可以为非线性优化方法(如光束法*差)提供一个良好的初始值,后者是运动恢复结构的“金标准”。

然而,在现代大规模运动恢复结构系统(如下一单元将讨论的COLMAP)中,通常不直接使用这种全局多帧重建方法。相反,它们采用增量式光束法*差

  1. 从精心选择的两帧开始重建。
  2. 迭代地将新图像添加到重建中。
  3. 通过新图像中检测到的特征与已重建部分中存在的特征之间的匹配,逐步扩展重建。
    这种方法更适合特征可见性不完整的大规模场景。

本节课中,我们一起学习了经典的Tomasi-Kanade矩阵分解法。我们了解了它如何在正射投影和完整轨迹的假设下,通过奇异值分解和度量约束,优雅地同时求解出相机运动和三维结构。虽然其假设在现实中较为严格,但它阐明了运动恢复结构问题的核心数学原理,并为更复杂、更鲁棒的现代方法奠定了基础。

011:从运动恢复结构与光束法*差 🎯

在本节课中,我们将要学习计算机视觉中的一个核心算法——光束法*差。这是一种通过联合优化所有相机参数和三维点位置,来最小化重投影误差的“黄金标准”算法。我们将了解其原理、面临的挑战以及在实际大规模三维重建系统中的应用流程。

光束法*差原理

上一节我们介绍了从两视图恢复三维结构的基础。本节中我们来看看如何通过优化所有视图和所有三维点来获得更精确的结果,这就是光束法*差。

光束法*差的目标是最小化重投影误差,即图像中观测到的特征点与三维点投影到图像*面上的位置之间的距离。通过联合优化所有三维点的位置和所有相机的位姿(包括内参和外参),我们可以得到最优的三维重建结果。

下图左侧是一组具有挑战性的图像,右侧是通过光束法*差恢复出的三维点云和相机位姿(由小三角形表示)。

光束法*差可以形式化地定义为以下优化问题:

目标:找到最优的相机参数集合 {π_i} 和三维点集合 {X^W_p},以最小化所有观测的重投影误差之和。

公式

min_{π_i, X^W_p} Σ_i Σ_p w_ip * || x^s_ip - π_i(X^W_p) ||^2

其中:

  • π_i:第 i 个相机的投影函数,包含了相机的内参(如焦距、畸变)和外参(旋转 R_i、*移 t_i)。
  • X^W_p:第 p 个三维点在世界坐标系中的坐标。
  • x^s_ip:第 p 个三维点在第 i 个相机图像*面上的实际观测坐标。
  • w_ip:一个指示权重(通常为0或1),表示第 p 个点是否在第 i 个图像中被观测到。

投影函数 π_i 的具体计算过程为:首先将三维点 X^W_p 通过刚体变换(R_i, t_i)转换到第 i 个相机的坐标系,然后通过内参矩阵 K_i 投影到图像*面,最后通过除以齐次坐标的最后一维得到二维图像坐标。

面临的挑战

虽然光束法*差是优化三维重建的黄金标准,但它也面临两大主要挑战。

1. 初始化问题

这个优化问题的能量函数(目标函数)是高度非凸的,因此一个良好的初始估计至关重要。如果初始值离全局最优解太远,优化过程很容易陷入局部最优。

在实践中,通常采用增量式策略来初始化:首先精心选择两幅图像进行初始重建,然后迭代地添加新的图像和相机,逐步扩展重建范围。这种方法比直接对所有视图进行联合初始化要稳定得多。

2. 优化规模与效率问题

一个大规模场景可能包含成千上万个相机和数百万个三维点,这意味着优化变量数量极其庞大,计算非常耗时。非线性优化的复杂度通常与未知数的数量呈超线性关系。

幸运的是,这个问题通常是稀疏的:并非每个三维点都在每个相机中可见。我们可以利用高效的稀疏求解器(例如 Ceres Solverg2o)来显著加速计算。尽管如此,对于超大规模的重建,光束法*差仍可能需要数小时才能完成。

增量式运动恢复结构流程

为了应对上述挑战,现代大规模运动恢复结构系统通常采用一个精心设计的增量式流水线。以下以著名的 COLMAP 重建流水线为例进行说明,该流程至今仍能提供最先进的结果。

整个流程主要分为两个阶段:

  1. 特征匹配阶段:在所有输入图像中寻找并匹配稳健的二维特征。
  2. 增量重建阶段:从两视图开始,逐步添加图像,进行三角测量和光束法*差,迭代地完善重建结果。

以下是该流程的详细步骤:

第一阶段:特征匹配

以下是特征匹配阶段的核心步骤:

  1. 特征提取与描述:在所有输入图像中检测关键点(如SIFT特征)并计算描述符。
  2. 特征匹配:在所有图像对之间进行特征匹配,建立对应关系。
  3. 几何验证:对匹配对进行几何验证(例如,通过估计基础矩阵或本质矩阵),剔除不符合极线几何约束的错误匹配(外点)。这能确保初始匹配的可靠性。
  4. 构建匹配图:图像作为节点,如果两幅图像之间有足够多的正确匹配,则在它们之间建立一条边。最终形成一个匹配图,其中连接紧密的簇是开始重建的理想起点。

第二阶段:增量重建

以下是增量重建阶段的核心步骤:

  1. 初始化:从匹配图中选择一个连接紧密的图像对,计算它们之间的本质矩阵,并进行三角测量,得到一个初始的两视图三维重建(包括两个相机位姿和一组三维点)。
  2. 图像注册:寻找一幅与当前已重建模型有足够多特征对应的新图像。利用这些三维点-二维观测的对应关系,通过求解 PnP(Perspective-n-Point) 问题来估计新相机的位姿。在实践中,常使用 RANSAC 算法配合 P3P 等最小解算方法来鲁棒地估计位姿并剔除外点。
  3. 三角测量新点:使用新注册的相机和已有相机,对新的特征匹配进行三角测量,得到新的三维点。
  4. 局部光束法*差:由于增量添加只影响模型局部,因此通常只对受影响的相机和三维点进行局部光束法*差,以快速优化。
  5. 外点过滤:剔除重投影误差过大的观测点或位姿异常(如视场角过大、畸变异常)的相机。
  6. 迭代与全局优化:重复步骤2-5,不断添加新图像。每隔一段时间(例如添加了较多图像后),对整个模型进行一次全局光束法*差,以获得整体最优解。

应用与成果

光束法*差及相关技术已催生出许多令人印象深刻的应用。

  • 大规模城市重建:例如“一日建成罗马”项目,使用从网络爬取的数万张无序照片,自动重建了整个城市的稀疏三维模型,展示了从互联网图片集进行三维重建的潜力。
  • COLMAP:该开源软件包进一步提升了重建的精度和完整性,其稀疏重建和后续的密集重建(多视图立体视觉)能生成非常清晰、噪声较少的三维点云。
  • 照片浏览与旅游:如 Photo Tourism 系统,允许用户在三维空间中交互式地浏览大型照片集,系统自动将照片对齐到其拍摄的三维位置,提供了直观的探索体验。
  • 增强现实与机器人:实时运动恢复结构技术使得机器人能够实时跟踪自身位姿并构建环境地图,从而在真实场景中叠加虚拟物体,实现增强现实效果。
  • 电影工业:该技术被称为“匹配移动”,可以从实拍的电影序列中恢复出相机运动轨迹,从而将计算机生成的虚拟物体精确地合成到实拍画面中,曾获得艾美奖。

总结

本节课中我们一起学习了计算机视觉中的核心优化技术——光束法*差。我们了解到,它通过联合优化所有相机参数和三维点来最小化重投影误差,是三维重建的黄金标准。同时,我们也认识到其面临初始化困难和计算规模庞大的挑战,而增量式重建流水线(如COLMAP所采用的)是解决这些挑战的有效方案。最后,我们看到了这项技术在从城市数字化到电影特效等众多领域的革命性应用。掌握光束法*差的原理和流程,是深入理解现代三维视觉系统的关键。

012:立体视觉重建 - 预备知识 👁️

在本节课中,我们将要学习密集立体视觉重建的基础知识。我们将从如何从图像中恢复三维结构的一般性问题出发,重点介绍双目立体视觉的核心原理,并详细讲解图像校正这一关键预处理步骤。

上一讲我们讨论了基于稀疏特征点的三维重建技术。本节中,我们来看看如何利用已知相机参数的两张图像,进行更密集的三维重建。

从单张图像中恢复三维的线索

从单张图像恢复三维结构是一个不适定问题,但存在多种视觉线索。

以下是几种主要的深度线索:

  • 遮挡:如果一个物体遮挡了另一个物体,我们可以推断被遮挡的物体位于更远的位置。艺术家常利用此原理。
  • 视差:当观察者或物体移动时,*处物体相对于远处物体移动得更快。这在立体视觉中被核心利用。
  • 透视:*行线在图像中汇聚于消失点,这提供了关于场景方向和深度的信息。
  • 对焦/模糊:人眼或相机镜头需要调整焦距以看清特定物体,导致焦*面外的区域模糊。这种模糊程度(景深)可以暗示深度。
  • 立体视觉:这是本节课的重点。它利用三角测量原理,从两个不同视点拍摄同一场景,通过观察对应点的位移(视差)来恢复三维结构。

双目立体视觉的优势

大多数生物拥有两只眼睛,这表明双目系统是感知深度的一种稳健且高效的最小配置。其优势在于,通过增大两个相机中心之间的距离(基线),可以提高深度估计的精度。基线越长,三角测量的结果越确定。

密集立体视觉的任务与流程

我们的目标是:从两张(基本)静态场景的图像中,重建一个密集的三维模型

以下是典型的处理流程:

  1. 相机标定:获取相机的内参(K)和外参(R, t)。
  2. 图像校正:将图像变换到一种标准配置,使匹配搜索简化为一维。
  3. 计算视差图:为参考图像(如左图)中的每个像素,在另一图像(右图)的对应极线上寻找最佳匹配点,计算其水*位移(视差 d)。
  4. 剔除异常值:通过一致性检查或遮挡检测移除错误的匹配。
  5. 从视差计算深度:利用相机参数和三角测量公式将视差转换为深度(Z)。
  6. 构建三维模型:将带有深度和颜色信息的点云融合成完整的三维模型(如网格)。

立体视觉在三维重建管线中的角色

在一个完整的多视图三维重建系统中,密集立体匹配是核心步骤之一。

以下是典型的系统流程:

  1. 输入一组图像。
  2. 使用增量式光束法*差等技术估计所有相机的位姿。
  3. 对于相邻的视图对,利用已知的极线几何进行密集立体匹配,为每个视图生成深度图。
  4. 使用如截断符号距离函数融合等算法,将所有深度图融合成一个统一、连贯的三维网格模型。

仅使用两个视图称为双目立体匹配;使用多于两个视图则称为多视图立体。双目方法更快,但可能不如多视图方法精确。

极线几何回顾

极线几何是立体视觉的数学基础。对于已标定的相机,其核心约束方程为:

x2^T * E * x1 = 0

其中 E 是本质矩阵,x1x2 是归一化相机坐标下的对应点。

最重要的性质是:左图像中的一点 x1,其在右图像中的对应点 x2 必然位于对应的极线 l2。这将对对应点的搜索从整个二维图像域简化到一维极线上,极大提升了效率。

图像校正

为了进一步简化匹配,我们希望极线是水*且*行的。这要求两个图像*面共面且*行于基线。这种配置称为校正后的配置。

在实际中,相机很难精确满足此配置。因此,我们通过图像校正来达成:计算一个旋转矩阵,将两个相机虚拟地旋转到一个共面且*行于基线的姿态。由于这是绕相机中心的旋转,我们可以通过单应性变换来重投影图像,而无需知道场景的三维结构。

在校正后的配置中:

  • 极点位于无穷远处。
  • 所有极线变为水*且*行。
  • 对应点位于左右图像的同一行上。

这使得匹配算法只需沿图像行进行搜索,实现起来非常简单高效。

以下是计算左相机校正旋转矩阵 R_rect 的一种常用方法:

  1. 将新的 X 轴 (r1) 设为归一化的基线方向(指向另一相机中心)。
  2. 新的 Y 轴 (r2) 为原始相机 Z 轴与 r1 的叉积。
  3. 新的 Z 轴 (r3) 为 r1r2 的叉积。

最终,R_rect = [r1^T; r2^T; r3^T]。对右相机需要额外考虑其相对于左相机的旋转。

在实际操作中,我们通常计算从校正后图像坐标到原始图像坐标的逆变换,并通过插值来填充校正后的图像,以避免空洞。

从视差到深度

在校正后的理想配置下,深度 Z 与视差 d 存在简单的反比关系。通过相似三角形原理,可以推导出:

Z = (f * B) / d

其中:

  • Z 是深度(物体到相机*面的距离)。
  • f 是相机的焦距(以像素为单位)。
  • B 是两个相机中心之间的距离,即基线
  • d 是估计出的视差x_left - x_right)。

这个公式表明:

  • 视差 d 越大(物体在左右图像中移动越多),物体离相机越*(Z 越小)。
  • 视差 d 越小,物体离相机越远(Z 越大)。
  • 深度估计的误差随距离的*方增长,因此对于远处的物体,深度估计精度较低。

本节课中我们一起学习了立体视觉重建的预备知识。我们回顾了从图像获取三维信息的多种线索,明确了密集双目立体视觉的任务与整体流程,并深入讲解了极线几何的核心作用以及图像校正这一关键步骤。最后,我们推导出了在校正配置下,从视差计算深度的核心公式,为后续学习具体的立体匹配算法打下了坚实的基础。下一节,我们将开始探讨最基础的立体匹配算法——块匹配。

013:立体重建 - 块匹配 👁️

在本节课中,我们将学习立体视觉中的一个核心问题:如何从一对已校正的立体图像中计算视差图。我们将重点介绍一种基础且直观的方法——块匹配,并探讨其工作原理、实现步骤以及在实际应用中的局限性。

从视差到深度

上一节我们介绍了如何通过视差值计算深度值。本节中,我们来看看一个更根本的问题:在一个已校正的立体视觉系统中,我们如何首先确定每个像素的视差值?

块匹配的基本思想

给定左图和右图,我们需要为参考图像(通常是左图)中的每个像素确定一个视差值。这个值代表了该像素在另一幅图像(右图)中沿极线移动的距离。

实现这一目标最简单的方法是块匹配。其核心思想是:对于左图中的每个像素,取其周围的一个小图像块(patch),然后在右图的对应极线上滑动,寻找一个看起来最相似的图像块。

如何衡量相似性?

如何判断两个图像点是否对应?直观上,它们看起来应该相似。但“相似”具体指什么?如果只比较单个像素的RGB值,会因为噪声和颜色歧义导致大量错误匹配。

因此,在实践中,我们比较的是以该像素为中心的一个小图像区域。这能更好地利用局部结构信息,减少歧义。

块匹配算法流程

为了更好地理解块匹配,我们以著名的Middlebury立体视觉基准数据集中的一个场景为例。该数据集的优势在于为每个像素提供了精确的视差真值,便于算法评估。

以下是块匹配的工作流程示意图:

  1. 确定搜索范围:对于左图中位于坐标 (x1, y) 的像素,由于图像已校正,其在右图中的对应点必然位于同一水*扫描线(y 坐标相同)上。并且,由于视差始终为正,我们只需在右图中从 x1 位置向左搜索(即向 x 坐标减小的方向)。
  2. 提取与比较图像块:在左图,以 (x1, y) 为中心提取一个 K x K 的图像块。在右图,对于每一个候选视差 d,在以 (x1 - d, y) 为中心的位置提取一个同样大小的图像块。
  3. 计算相似度得分:使用某种相似性度量,计算左图块与每个右图候选块之间的匹配分数。
  4. 选择最佳匹配:通常采用“赢家通吃”策略,即选择相似度得分最高的那个候选位置,其对应的视差 d 即为该像素的估计视差。

相似性度量方法

我们将 K x K 的图像块展*为向量,记为 W_L(左图块)和 W_R(右图块)。以下是两种常用的相似性度量:

  1. 零均值归一化互相关:该方法先对图像块进行零均值、单位方差归一化,再计算向量点积。它对光照变化有一定鲁棒性。

    • 公式ZNCC = ( (W_L - mean(W_L)) / std(W_L) ) · ( (W_R - mean(W_R)) / std(W_R) )
  2. *方差和:计算两个图像块向量对应元素差值的*方和。值越小,表示越相似。

    • 公式SSD = Σ (W_L[i] - W_R[i])^2

不同的度量方法各有优劣。若想深入了解,推荐查阅相关文献,如Scharstein和Szeliski的论文,其中系统比较了多种度量在辐射差异图像上的性能。

完整的块匹配算法与结果

完整的块匹配算法步骤如下:

  1. 设定要搜索的视差范围 [0, d_max]
  2. 对于参考图像(如左图)中的每个像素,遍历所有可能的视差值 d,计算其与右图中对应块的相似度。
  3. 为每个像素独立地选择相似度最优的视差值(赢家通吃策略)。

我们也可以交换参考图像的角色,计算以右图为参考的视差图。这样做的一个巨大优势是能够进行左右一致性检查,以剔除错误匹配(外点)。

块匹配的局限性与挑战

观察块匹配生成的视差图,我们会发现一些典型问题:

  1. 半遮挡区域:场景中某些区域只在其中一幅图像中可见。例如,位于图像最左侧的物体,从右相机视角看可能完全不可见。对于这些像素,无法找到正确的对应点,因此无法估计视差,在视差图中显示为黑色区域。

  2. 前端*行假设的违反:块匹配的一个核心假设是:所比较的图像块内,所有像素都具有相同的视差(即经历了相同的*移)。这仅在场景中的*面与图像*面*行(前端*行)时才严格成立。对于倾斜或弯曲的表面,当视角变化时,图像块会发生透视形变,而不仅仅是*移,这会导致匹配错误。

  3. 窗口大小的权衡:选择图像块(窗口)大小时面临一个根本矛盾:

    • 小窗口:对细节保持更好,更少违反前端*行假设,但包含的纹理信息少,容易因匹配歧义而产生噪声。
    • 大窗口:包含更多纹理信息,匹配更鲁棒,结果更*滑,但会严重违反前端*行假设,导致边界膨胀效应——前景物体的视差会“渗入”背景区域,使得物体边界处的视差不准确。

改进策略:左右一致性检查

为了缓解上述问题并剔除外点,一个有效的方法是执行左右一致性检查。其原理是:

  1. 分别计算以左图为参考的视差图 D_L 和以右图为参考的视差图 D_R
  2. 对于左图中的像素 p,其视差为 D_L(p)。根据此视差,在右图中找到对应的像素 q
  3. 查看右图中像素 q 的视差 D_R(q)。根据 D_R(q) 应该能将我们带回到左图中的原始像素 p 或其附*。
  4. 如果 |D_L(p) - D_R(q)| 超过一个阈值,则认为 p 点的视差估计不一致,可能是错误的,予以剔除。半遮挡区域非常容易被这种方法检测出来。

总结

本节课中我们一起学习了立体视觉中的基础匹配算法——块匹配。我们了解了其通过比较图像块相似性来估计视差的基本流程,介绍了ZNCC和SSD两种相似性度量方法。同时,我们也深入探讨了块匹配的局限性,包括半遮挡问题、违反前端*行假设以及窗口大小选择的权衡。最后,我们介绍了左右一致性检查这一有效工具,用于提升视差图的质量并检测遮挡区域。块匹配虽然简单直观,但其面临的挑战促使了后续更复杂的立体匹配算法的发展。

014:立体匹配中的孪生网络 🧠

在本节课中,我们将学习如何利用深度神经网络从数据中学习相似性度量,以改进立体匹配中的块匹配方法。上一节我们讨论了简单的手工相似性度量,本节我们将看到如何通过学习来获得更优的度量。

动机与核心思想

手工设计的特征和相似性度量无法全面考虑所有相关的几何、辐射度不变性以及遮挡模式。深度学习已经革新了识别任务,例如,过去使用手工设计的SIFT描述符,而现在所有特征都是学习得到的。我们希望在此应用相同的原理,但依然保持在块匹配的框架内,即使用相似的匹配算法,只是希望获得更好的相似性度量。世界过于复杂,难以手工指定,因此需要学习。

一篇开创性论文指出,匹配代价的计算实际上可以视为一个图像分类问题。其背后的思想很简单:如果我们从左图像和右图像中各取一个图像块,并且已知真实的视差(这需要一个带有视差标注的数据集),我们就可以根据真实视差给这些图像块打标签。例如,如果位移正确,则图像块相似,视为“好匹配”;如果视差略有偏差,则视为“坏匹配”。这样,我们就可以将其转化为一个分类问题:对于一个特定的左图像块,尝试对右图像中所有可能的右图像块进行分类,分类器应能告诉我们哪个是正确的匹配。

方法概述 🧩

该方法假设存在一个大型标注数据集。早期的大型标注视差数据集之一是KITTI数据集(2012和2015年),它提供了超过200张标注图像以及更多带有真实视差的原始图像,可用于训练模型。需要说明的是,本节讨论的孪生网络相比我们将在最后一节讨论的端到端立体估计技术,仍然更加标签高效和数据高效,因为它们只学习特征和相似性矩阵,但仍需要相当数量的数据进行训练。

训练好这样一个“图像块分类器”后,我们可以使用这个学习到的模型为左右两幅图像计算特征,然后使用简单的点积或更复杂的多层感知机来关联这些特征以比较图像块。接着,我们可以为每个像素找到最大值(即上一节讨论的“赢家通吃”策略),或者如论文中所做,为了获得稍好的性能,可以运行一个结合了问题*滑性假设的全局优化算法(这将在下一节讨论)。

因此,在本节中,我们仍然专注于块匹配的设置。

网络架构

原始论文提出了两种用于此匹配问题的架构。

1. 学习相似性架构
在这种架构中,我们取左图像的一个块和右图像的一个块,通过卷积计算特征,然后将这些特征拼接起来,再输入一个全连接的多层感知机,由该MLP输出这两个块的相似性分数。它仍然是孪生网络(两个分支相同且共享参数),但随后需要这个昂贵的MLP部分进行计算。

2. 余弦相似性架构
更简单的方法是移除这个MLP,将所有相似性度量的计算负担转移到特征上。具体做法是:使用卷积网络为两幅图像的所有像素计算特征(推理时可重用计算,速度很快),然后对所有像素在通道维度上进行归一化,最后计算这两个归一化特征向量之间的简单点积,该点积直接作为相似性分数,这被称为余弦相似性。

这两种架构在推理时,孪生分支部分(共享权重)可以快速在整个图像上运行。而点积操作(需要计算 W × H × D 次)比运行一个MLP要快得多。因此,整个评估过程比“学习相似性”模型快大约两个数量级。有趣的是,这并没有导致性能显著下降,两种架构性能大致相当。由于其速度快,后续许多工作都采用了这种架构。

训练过程 🔄

这些模型的训练集由图像块三元组构成,并使用一种特殊的损失函数。

一个三元组包含:

  • 一个来自左图像的块(参考块)。
  • 一个来自右图像的负样本块(不正确的块)。
  • 一个来自右图像的正样本块(正确的块,根据真实视差精确位移得到)。

这里的 x 是二维坐标,即左右图像中的图像坐标。

关键问题是如何选择正负样本。这篇论文采用了难负样本挖掘。原因是,如果只是随机选择非正样本的块作为负样本,会导致分类问题过于简单,因为大多数块与正确块看起来非常不同。我们需要寻找那些与正确样本相似但不正确的负样本。

具体做法是:

  • 负样本:中心坐标取为 (x_left - 视差d) + 偏移量O_neg,其中偏移量O_neg从一个均匀分布中采样,范围在 [负样本低阈值, 负样本高阈值] 内(例如论文中使用-6到-3和+3到+6像素)。
  • 正样本:中心坐标取为 (x_left - 视差d) + 偏移量O_pos,其中偏移量O_pos从一个更小的范围采样(例如论文中使用-1到+1像素)。

这种策略使得分类器需要区分那些看起来很接*但略有偏移的“难”样本,从而学习到更具判别力的特征。

损失函数

我们训练模型来预测相似性分数(回归任务,而非分类),使用的是合页损失

公式
损失 = max(0, 边际值M + S_负 - S_正)

其中:

  • S_负 是网络对(参考块,负样本块)的相似性评分。
  • S_正 是网络对(参考块,正样本块)的相似性评分。
  • M 是一个可调的超参数(论文中通常使用0.2)。

我们希望正样本的相似性分数 S_正 高于负样本的分数 S_负 至少一个边际值 M。当 S_正 > S_负 + M 时,损失为零。这种合页损失和边际值的设计,可以防止那些已经分离得很好的正负样本对继续产生梯度,让模型能够专注于那些难以区分的“难”样本。

结果与性能

“赢家通吃”策略的结果显示,在KITTI 2012数据集上,孪生网络的结果比标准块匹配的结果噪声更少、质量更好。这表明学习确实提高了相似性度量的质量。

如果在此基础上运行全局优化(下节内容),可以获得更优的视差图。通过对左右图像分别计算视差并进行一致性检查,可以移除异常值并基于遮挡关系进行着色(例如,半遮挡区域显示为绿色),从而得到非常清晰的视差图。

该算法的原始版本使用CUDA和Lua/Torch 7实现,在一块Titan X GPU上运行。

  • 训练:使用了4500万个训练样本(小图像块),训练16个周期,耗时约5小时。
  • 推理:对于一对图像,简单(余弦相似性)架构约需6秒,复杂(学习相似性)架构由于需要为每个视差假设评估MLP,约需100秒。

总结

本节课我们一起学习了如何利用孪生网络从数据中学习立体匹配的相似性度量。我们了解了两种主要的网络架构(学习相似性和余弦相似性),探讨了使用难负样本挖掘的三元组训练方法以及合页损失函数。这种方法在保持块匹配框架高效性的同时,显著提升了匹配质量,为后续的全局优化步骤奠定了更好的基础。

016:端到端立体视觉重建 🧠

在本节课中,我们将学习端到端学习的立体视觉重建算法。这些算法不仅学习匹配代价,而且直接将整张图像作为输入,通过深度神经网络直接输出视差图。我们将了解这一领域的关键模型、训练策略、数据集挑战以及最新的技术进展。


模型架构演进

上一节我们回顾了传统的立体匹配方法。本节中,我们将重点介绍完全由数据驱动的端到端深度学习方法。

DispNet:开创性的端到端模型

第一个推动该领域发展的模型是 DispNet。它是一个端到端训练的深度神经网络,用于立体视觉。

  • 输入:一对左右立体图像。
  • 架构:采用类似U-Net的编码器-解码器结构,包含下采样卷积、跳跃连接和上卷积操作,以恢复高分辨率细节。
  • 输出:直接回归预测出视差图。
  • 关键特性:在网络的较低分辨率层,引入了一个相关层,用于在特征级别进行匹配,这借鉴了传统块匹配的思想。网络在此之后合并为单分支。

训练细节

  • 损失函数:采用多尺度损失,不仅在最终层计算预测视差与真实视差的差异,也在中间层对下采样后的真实值计算损失。
  • 课程学习:为防止过拟合,采用课程学习策略。模型首先在简单场景、低分辨率数据上训练,然后逐步增加数据集的难度,直至达到目标数据集的复杂度。

数据挑战与解决方案

训练这些深度模型需要大量带标注的数据,但获取真实世界的立体图像及其精确视差真值非常困难。

以下是解决数据问题的关键方法:

  1. 真实数据集(如KITTI):使用激光雷达扫描获取深度信息,但制作成本高、场景特定(主要是自动驾驶)。
  2. 合成数据集:通过渲染3D资产生成图像和对应的深度图,标注成本极低。尽管合成数据与真实数据在外观上差异巨大,但模型仍能表现出良好的泛化能力。常用的合成数据集包括 FlyingThings3DMonkaa

模型先在大型合成数据集上进行预训练,然后在较小的真实数据集(如KITTI)上进行少量迭代的微调,即可获得不错的效果。


性能提升:GC-Net

在DispNet之后,GC-Net 通过一个关键改进获得了更好的性能。

  • 核心思想:显式构建一个视差代价体积(类似于传统方法),然后对其应用3D卷积进行滤波和优化。
  • 与DispNet的区别:DispNet在相关层后主要使用2D卷积;而GC-Net在构建代价体积后,使用3D卷积和3D反卷积来处理这个三维空间中的匹配信息。
  • 输出形式:GC-Net将视差估计视为分类问题,为每个像素的每个候选视差级别预测一个匹配代价,然后通过softmax将其转换为概率分布,最终取期望值作为该像素的预测视差。
    • 公式预测视差 = Σ (每个视差候选值 d * 其概率 P(d))
    • 其中,P(d) = softmax( - 代价(d) )
  • 缺点:3D卷积非常消耗内存,限制了可用的批处理大小和输入分辨率。


前沿进展:立体混合密度网络

现有模型存在两个主要问题:内存消耗大导致难以处理高分辨率图像,以及神经网络固有的*滑性会导致物体边缘出现“模糊”或“出血”的伪影。

立体混合密度网络 旨在解决这些问题:

  1. 混合密度预测:不再为每个像素回归单个视差值,而是预测一个多模态的视差分布(例如,双模态拉普拉斯混合分布)。这允许模型在物体边界处表示两个截然不同的视差模式,从而能够建模尖锐的视差不连续性。
    • 代码概念:模型输出每个像素的分布参数(如均值、尺度、混合权重)。
  2. 连续查询头:在标准骨干网络之上,增加一个SMD头部(一个多层感知机)。它可以通过双线性插值,在图像的任意连续坐标位置查询特征,并预测该位置的混合分布参数。这实现了任意空间分辨率的训练和推理。

效果:相比传统方法(如HSMNet),该方法能预测更清晰的物体边界,并且能以远高于输入图像的分辨率(例如从HD到128兆像素)输出视差图,同时避免了边缘伪影。


本节课中,我们一起学习了端到端立体视觉重建的发展历程。我们从开创性的DispNet模型开始,了解了其U-Net架构和课程学习策略。接着,探讨了训练这些模型所面临的数据集挑战以及合成数据的解决方案。然后,我们分析了性能更优的GC-Net,它通过3D卷积处理代价体积。最后,我们介绍了最新的立体混合密度网络,它通过预测多模态视差分布和实现连续空间查询,显著提升了视差图在边界处的锐度和整体分辨率。这些进展展示了深度学习在立体视觉领域的强大能力和持续创新。

017:概率图模型与结构化预测 📊

在本节课中,我们将学习概率图模型的基本概念,特别是它们在解决计算机视觉中“结构化预测”问题时的应用。我们将从问题设定开始,逐步介绍马尔可夫随机场、因子图等核心模型,并了解如何利用它们整合先验知识来解决如立体匹配等存在歧义的问题。

从立体匹配到结构化预测 🔍

在上一讲中,我们介绍了立体匹配算法,特别是基于块匹配的方法。这类方法的核心假设是:左右图像中对应的图像块应该看起来相似。然而,在许多情况下,这个相似性假设会失效。

以下是几个典型的失败场景:

  • 纹理缺失区域:图像区域缺乏可区分的纹理,导致无法唯一匹配。
  • 重复纹理区域:大量图像块外观相似,造成匹配歧义。
  • 遮挡区域:前景和背景的变化不一致,导致匹配块的外观发生剧烈改变。
  • 非朗伯表面:例如存在反射的表面,其外观并不随我们希望测量的几何形状而移动。

为了克服这些歧义,我们可以尝试整合关于真实世界的先验知识。在立体匹配中,这意味着了解深度图或视差图的统计特性。例如,布朗大学范围图像数据库的统计表明,除了在物体边界处,深度或视差的变化通常是缓慢的。我们希望将这种“空间*滑”的统计知识整合到匹配算法中,这个过程称为空间正则化

那么,如何整合这种关于视差图统计特性的知识呢?我们可以将问题构建为在概率图模型中进行推断。这被称为一个结构化预测问题,因为我们不再是独立地预测每个像素的视差,而是通过考虑相邻像素之间的局部相互作用(先验知识),一次性预测整个视差图。

这种在规则网格上连接相邻像素(如上、下、左、右)的图结构,可以写成一个能量函数的形式,从而产生一个吉布斯分布。我们的目标是在所有可能的视差图空间中,进行最大后验概率推断,以找到在给定数据约束(匹配成本)和先验*滑约束下最可能的视差图。

什么是概率图模型? 🤔

概率图模型采用概率论的视角,对问题的依赖关系结构进行建模。它试图为整个待推断对象(如完整的视差图)建立概率分布,然后在该模型上进行推断。

在深度学习革命之前,图模型在许多计算机视觉领域占主导地位。它们特别适用于训练数据较少的场景,并且允许灵活地整合先验知识。解决计算机视觉中病态问题的歧义性有两种主要思路:一是整合大量(标注)数据并用深度学习进行端到端训练;二是在数据有限但拥有先验知识时,利用图模型整合这些知识。值得注意的是,图模型的思想也可以与深度学习结合,我们将在第7讲中看到相关例子。

以下是概率图模型的优缺点分析:

优点:

  • 可整合先验知识:能够将领域知识(如深度图统计)编码到模型中。
  • 参数相对较少:可以从有限的数据中估计参数。
  • 可解释性强:图结构中的组件通常具有明确的含义,便于理解模型的推断过程。

缺点:

  • 建模能力有限:许多复杂现象难以用简单的图结构准确建模。为了保持推断的可处理性,通常只能使用成对依赖等简单结构,这可能引入误差。
  • 难以利用大数据集:相关技术通常不够快速,且即使对于简单情况,推断也常常是*似的(例如,在带环的图中进行精确推断是NP难问题)。

结构化预测的定义 📐

我们已经提到在图模型中进行推断是一种结构化预测。那么,什么是结构化预测呢?

形式上,结构化预测与传统分类和回归问题相对。在分类或回归中,我们试图建模一个从复杂输入空间(如图像、文本)到单个离散(分类)或连续(回归)数值的函数。而在结构化预测中,输入同样是复杂的、高维的对象,但输出也是复杂的结构化对象。输出可以是图像、文本、蛋白质折叠结构、计算机程序等高维数据。

例如,在立体匹配中,使用孪生网络对每个像素独立计算视差得分,这本质上仍是独立的分类。而在结构化预测中,我们希望一次性推断整个视差图,并考虑像素间的结构关系。另一个简单例子是车辆车道跟踪:输入是含噪声的观测序列,输出是每个时间步车辆所在车道(左、中、右)的状态序列。通过整合“车辆不太可能瞬间跨越车道”这样的先验约束,并将其构建为图模型进行推断,我们就能进行结构化预测。

因此,概率图模型推断具有图像输出的深度神经网络都属于结构化预测模型的范畴。但在本课程中,当我们提及结构化预测时,通常特指基于概率图模型的方法。

课程路线图与图模型概览 🗺️

图模型种类繁多,有专门的课程讲授。在本课程中,我们将用三讲(第5、6、7讲)的时间来介绍其核心思想,并聚焦于对计算机视觉应用非常重要的一类模型——无向图模型,也称为马尔可夫网络或马尔可夫随机场。

以下是这三讲的内容概览:

  • 本讲(第5讲):介绍概率图模型基础,涵盖马尔可夫随机场、因子图以及用于求解边缘概率和最大后验解的推断算法——信念传播。
  • 第6讲:探讨图模型在立体视觉、光流和多视图重建等具体计算机视觉任务中的应用。
  • 第7讲:讨论图模型中的参数学习(估计),以及如何将图模型与深度学习相结合。

如果你想深入了解图模型,推荐阅读Sebastian Nowozin和Christoph Lampert的教程(附有免费在线书籍),以及Barber的著作(同样可在线获取)。


本节课中,我们一起学习了结构化预测问题的由来及其重要性,了解了概率图模型如何通过建模变量间的依赖关系来整合先验知识以解决此类问题。我们明确了结构化预测与分类/回归的区别,并概览了本课程中关于图模型部分的学习路线。下一节,我们将深入探讨我们的核心工具——马尔可夫随机场。

018:马尔可夫随机场 🎲

在本节课中,我们将要学习概率图模型中的一种重要模型——马尔可夫随机场。我们将从概率论的基础知识开始回顾,然后深入探讨马尔可夫随机场的定义、性质及其在图模型中的核心作用。

概率论回顾

在深入马尔可夫随机场之前,让我们先简要回顾一下概率论的基础知识。

在概率论中,我们讨论的是随机变量,我们会在这些变量上定义分布。本课程,特别是本讲座中,我们主要考虑两种类型的随机变量:离散随机变量和连续随机变量。

对于离散随机变量,变量可以取 C 个值(可以将 C 理解为分类问题中的类别)。变量 x 取值为 c 的概率记为 P(x = c)。请注意,对于离散分布,我们通常使用大写字母 P,但为了简便,这里我们统一使用小写 p。

如果 x 是连续随机变量,我们可以写出 x 取值于某个集合的概率。如果这是一个一维随机变量,那么这个集合就是实数空间 R 的一个子集。变量 x 取值于集合 X 的概率记为 P(x ∈ X)。变量 x 的分布可以简写为 p(x),这里我们同样不区分离散和连续,为简便起见统一使用小写 p。

现在,有一些关于概率分布的重要性质需要了解,我们将在本讲座中广泛使用这些性质。以下是两个基本规则:求和规则与乘积规则。

求和规则定义了变量的边缘化。当我们有一个联合分布 p(x, y) 时,可以通过对想要从分布中移除的变量 y 进行求和(或积分)来得到 x 的边缘分布。公式如下:
p(x) = Σ_y p(x, y) (离散变量)

p(x) = ∫ p(x, y) dy (连续变量)

另一个重要规则是乘积规则。联合分布 p(x, y) 等于条件分布 p(y|x) 乘以 x 的概率,即:
p(x, y) = p(y|x) * p(x)
或者等价地,
p(y|x) = p(x, y) / p(x)

作为乘积规则的一个直接推论,我们得到了著名的贝叶斯规则:
p(y|x) = p(x|y) * p(y) / p(x)

马尔可夫随机场简介

在快速回顾之后,让我们深入探讨马尔可夫随机场。

为了定义马尔可夫随机场,我们首先需要定义什么是势函数。一个势函数 φ_i(x)φ(x) 是其自变量 x 的一个非负函数。在本讲座的上下文中,x 通常是一个单变量。一个联合势函数 φ(x1, ..., xT) 是一组变量的非负函数。通常,所有变量也可以是高维的,但本讲座中,我们考虑每个单独的 x_i 为一维随机变量。势函数是非负的,但不需要归一化。

马尔可夫随机场,简称 MRF,也称为马尔可夫网络,定义如下:对于一组变量 X = {x1, ..., xT},一个马尔可夫随机场被定义为在无向图 G 的所有极大团(或所有团)上的势函数的乘积。公式如下:
p(X) = (1/Z) * ∏_{c∈C} φ_c(X_c)
其中,C 是图 G 中的团(或极大团)集合,X_c 是团 c 中包含的变量子集。Z 是归一化常数,称为配分函数,它确保整个表达式是一个正确的概率分布(即对所有状态求和或积分为 1)。

如果图中的团大小均为 1 或 2(即没有连接超过两个变量的团),我们称之为成对马尔可夫随机场。我们在立体视觉中简要展示过的马尔可夫随机场就是一个例子,它包含一元势函数和成对势函数,但没有连接超过两个变量的势函数。

如果所有势函数都严格为正,则称之为吉布斯分布。

图、团与极大团

我们谈到了团、极大团和无向图,这些概念具体指什么呢?让我们看一个例子。

这是一个包含 7 个顶点和 11 条边的无向图。图中的每个顶点对应一个随机变量,因此我们有 7 个随机变量。边则对应这些随机变量之间的依赖关系或联系。例如,x2 和 x4 直接相关,而 x2 和 x5 则不直接相关,它们只能通过 x4 间接联系。

团是图中顶点的一个子集,该子集内的所有顶点都两两相连(完全连接)。例如,图中绿色的 {x1, x3} 是一个团,因为 x1 和 x3 相连。红色的 {x1, x2, x3, x4} 也是一个团,因为子集内每两个变量之间都有边连接。类似地,{x4, x5, x6} 和 {x5, x6, x7} 也是团。但 {x4, x5, x6, x7} 不是团,因为缺少 x4 到 x7 的连接。

极大团是指无法通过添加任何其他顶点来扩展的团。在上图中,只有红色的团是极大团。例如,团 {x1, x2, x3, x4} 是极大的,因为无法添加 x5 等顶点而不破坏团的完全连接性质。而团 {x1, x3} 不是极大的,因为可以添加 x2 形成更大的团 {x1, x2, x3},而这个团仍然不是极大的,因为还可以添加 x4。

这就是无向图模型的基本概念:顶点对应随机变量,边对应关系,以及团和极大团的概念。

马尔可夫随机场的性质

现在,让我们通过一个只有三个随机变量的简单例子来看看马尔可夫随机场的一些性质。这个图的连接关系是:A 与 C 相连,C 与 B 相连,但 A 与 B 之间没有直接连接。

如前所述,马尔可夫随机场被定义为无向图上团的势函数的乘积。在这个例子中,我们有两个团(同时也是极大团):{A, C} 和 {C, B}。因此,这个 MRF 指定的联合分布为:
p(A, B, C) = (1/Z) * φ1(A, C) * φ2(B, C)
其中 Z 是配分函数,用于归一化。

第一个性质是:如果我们对变量 C 进行边缘化(求和),那么原本没有直接连接的 A 和 B 会变得相互依赖。我们可以通过证明在边缘化 C 后,p(A, B) ≠ p(A) * p(B) 来证实这一点。我们通过构造一个反例(使用二元变量和特定的势函数定义)证明了这一点,表明在一般情况下,该等式不成立。

第二个性质是:如果我们对变量 C 进行条件化(给定 C 的值),那么 A 和 B 会变得条件独立。这可以更简洁地写为:A ⊥ B | C。其证明可以通过证明 p(A, B|C) = p(A|C) * p(B|C) 来完成,方法与第一个性质的证明类似。

在这个简单的三节点 MRF 中,我们看到:边缘化一个变量会使其相邻变量变得依赖;而条件化一个变量会使其相邻变量变得条件独立。

全局与局部马尔可夫性质

后一个陈述(条件独立性)可以推广为所谓的全局马尔可夫性质。

为了定义全局马尔可夫性质,我们首先需要定义分离。考虑一个图,一个顶点子集 S 将子集 A 与子集 B 分离,如果从 A 中任一成员到 B 中任一成员的所有路径都必须经过 S。换句话说,S 屏蔽了 A 和 B 之间的直接相互影响。

全局马尔可夫性质陈述如下:对于不相交的变量子集 A、B 和 S,如果 S 将 A 与 B 分离,那么给定 S 的条件下,A 条件独立于 B。这意味着,通过定义分离属性,我们可以从任何具体的图中推导出一系列条件独立性关系。

从全局马尔可夫性质,我们可以非常简单推导出局部马尔可夫性质。局部马尔可夫性质指出:当条件于其所有邻居时,一个随机变量 X 与图中所有其他变量条件独立。用数学语言表达:
p(x | X{x}) = p(x | Neighbors(x))
其中,X{x} 表示除 x 之外的所有变量集合。变量 x 的邻居节点集合被称为 x 的马尔可夫毯,因为它像毯子一样将 x 与图中其他变量屏蔽开来。这个性质不仅适用于单个变量,也适用于变量集合。

哈密尔顿-克利福德定理

我们讨论了基于极大团的因子分解,也讨论了通过分离从图中推导条件独立性质。这两者之间的关键联系由哈密尔顿-克利福德定理所概括。

该定理指出:一个具有严格正概率质量或密度的概率分布,满足关于一个无向图 G 的马尔可夫性质,当且仅当它是一个吉布斯随机场,即其密度可以按图 G 的极大团进行因子分解。

这个定理意味着,我们从图中读取条件独立性质的方式,与通过极大团势函数乘积定义分布的方式,是等价的。满足图中所有条件独立性质的分布,与按图因子分解定义的分布是同一回事。

另一种看待图模型的方式是过滤器视角。我们可以将图模型视为一个过滤器,只有那些能够基于图中定义的团进行因子分解的概率分布(或者等价地,只有那些尊重该图定义的马尔可夫性质的分布)才能通过这个过滤器。根据哈密尔顿-克利福德定理,我们知道这两组分布实际上是相同的。

总结

在本节课中,我们一起学习了马尔可夫随机场的核心概念。我们从概率论基础回顾开始,然后定义了势函数和马尔可夫随机场本身。我们探讨了无向图中的团、极大团以及它们如何用于定义分布的因子分解形式。通过一个三变量例子,我们分析了 MRF 的关键性质:边缘化可能导致依赖,而条件化则产生条件独立。我们进一步将这些性质推广到全局和局部马尔可夫性质,并理解了如何从图结构读取条件独立关系。最后,我们介绍了哈密尔顿-克利福德定理,它建立了图表示的因子分解形式与条件独立性之间的等价关系,这是理解概率图模型表达能力的基石。

019:概率图模型 - 因子图 🧩

在本节课中,我们将学习一种比马尔可夫随机场更精确的图模型表示方法——因子图。我们将了解为什么需要它,如何构建它,以及它如何清晰地表达概率分布的具体分解形式。

概述

上一节我们介绍了马尔可夫随机场。虽然可以直接在马尔可夫随机场上进行推断,但本节我们将讨论一种比简单的马尔可夫随机场或马尔可夫网络更精确的图模型,这被称为因子图。

为什么需要因子图?

让我们再次考虑马尔可夫随机场。考虑以下通过势函数进行的分解,其中我们有一个联合分布:

公式P(A, B, C) = (1/Z) * φ₁(A, B) * φ₂(B, C) * φ₃(C, A)

其中 Z 是归一化常数。这个分布由三个不同的势函数定义:一个作用于变量 AB,一个作用于 BC,一个作用于 CA

对应的马尔可夫网络或马尔可夫随机场的图表示是什么?显然,ABBCCA 之间必须有连接。因此我们得到一个像这样的全连接图,将随机变量 ABC 两两相连。

然而,这个马尔可夫网络中的最大团是三元团 {A, B, C}。因此,存在另一种由该网络表示的分解,它实际上代表了(正如我们现在所知)相同的一组条件独立属性。所以,在条件独立属性方面,这是同一类分布。这个分解如下:

公式P(A, B, C) = (1/Z) * φ(A, B, C)

现在,第二种分解更通用。通过拥有这个三元势函数,我们可以建模所有可能的 φ(A, B, C),而这仅通过查看成对关系或双变量函数的乘积是无法实现的。因此,它比第一种分解更丰富。

但是,就马尔可夫网络而言,它们没有区别,因为两者都遵循相同的条件独立假设,尽管第二种更强大。因此,在马尔可夫随机场的情况下,势函数的分解并不是由图唯一指定的。

为了消除这种歧义,我们在图中引入一种额外的节点。这种新的表示方法就是因子图。这种额外类型的节点,我们将使用正方形来将其与随机变量节点(圆形)区分开来。每个这样的正方形被称为一个因子

现在我们可以区分之前的两种情况。中间的因子图表示只有一个团(三元团)的分解。右边的因子图表示有三个团(每个团包含两个变量)的分解。

这两个因子图在条件独立假设方面对应于同一个马尔可夫网络。但是,它们区分了可以表达的不同类型的分布,因此通过使分解形式显式化,允许我们区分不同的分解。

因子图的定义

现在,与之前非常相似,我们定义一个因子图,只是将之前使用的势函数 φ 替换为现在的因子 f,并且我们使用这种更精确的图形表示。

给定一组随机变量 X = {x₁, ..., xₙ} 和这些随机变量的子集集合 C(这些子集类似于团或势函数的作用域),每个子集是 X 的一个子集。我们定义一个函数 F,它是所有随机变量的乘积:

公式F(X) = ∏_{k=1}^{K} f_k(C_k)

其中 K 是因子数量,C_k 是第 k 个因子作用的变量子集。对于每个子集,我们定义一个函数,现在称为因子,并使用 f 来明确表示它是一个因子。

因子图(简称 FG)是一个二分图,其中:

  • 每个因子 f_k 对应一个方形节点。
  • 每个变量 x_i 对应一个圆形节点。

它是二分图,意味着因子节点之间没有连接,变量节点之间也没有连接。所有连接都只存在于因子节点和变量节点之间,即存在于不同类型的节点之间。

以下是将一个图转换为二分图的示例。在一边我们有变量,在另一边我们有因子,连接只从上(变量)到下(因子)或反之,而不是在变量之间或因子之间,这就是为什么它被称为二分图。

因此,因子图是一个二分图,每个因子 f_k 对应一个方形节点,每个变量 x_i 对应一个圆形节点。我们试图在图形上区分因子(它们是函数)和变量。

与之前类似,通过对 F 进行归一化,我们得到一个分布:

公式P(X) = (1/Z) * F(X)

其中配分函数 Z 只是对所有随机变量的整个状态空间求和(或连续情况下积分)F(X)

从因子图读取分布

现在,从因子图读取分布以及反之根据分布写出因子图都变得很容易。

那么,这个因子图的分布是什么?我们可以直接读取哪些因子连接到哪些变量,并且可以直接写出因子图(直到归一化常数)。所以我们只需写出:

公式P(X) ∝ f_A(x₁, x₂) * f_B(x₁, x₂) * f_C(x₂, x₃) * f_D(x₃)

因为 f_A 连接到 x₁x₂f_B 也连接到 x₁x₂,依此类推。f_D 只连接到 x₃

类似地,我们可以看一个特定的分解,并问:如果我指定了一个像下面这样的分布,对应的因子图是什么?

公式P(x₁, x₂, x₃) = P(x₁) * P(x₂ | x₁) * P(x₃ | x₁, x₂)

答案是,这些单独的分布项(如 P(x₁)P(x₂|x₁))都是其自变量的函数。因此,我们可以简单地将它们写成因子 f。所以我们有:

  • f_A(x₁) 对应 P(x₁),连接到 x₁
  • f_B(x₁, x₂) 对应 P(x₂ | x₁),连接到 x₁x₂
  • f_C(x₁, x₂, x₃) 对应 P(x₃ | x₁, x₂),连接到 x₁x₂x₃

总结

本节课中,我们一起学习了因子图。因子图通过引入显式的因子节点,提供了一种比马尔可夫随机场更精确的概率分布分解表示方法。它消除了马尔可夫网络中分解形式不唯一的歧义,使得分布的因子化结构一目了然。因子图是一个二分图,清晰地分离了变量和函数(因子),便于我们直接从图读取分布,或根据分布构建图,为后续的概率推断提供了更清晰的基础。

020:概率图模型 - 信念传播 🧠

在本节课中,我们将学习如何在概率图模型中进行推理,即如何回答诸如“某个变量子集的边缘分布是什么?”或“在给定概率模型下,随机变量的最可能配置(最大后验解)是什么?”这类问题。我们将重点介绍一种名为信念传播的高效算法,它通过消息传递机制,避免了直接计算的指数级复杂度。

概述

我们首先会看到,在链式结构的因子图上进行推理。然后,我们将信念传播算法推广到更一般的树状结构图上。最后,我们会讨论当图结构存在环路时,如何应用*似的环状信念传播算法。核心思想是利用动态规划,通过局部计算和消息传递来高效求解全局问题。


链式结构推理 🔗

上一节我们介绍了概率图模型的基本概念。本节中,我们来看看如何在最简单的链式结构上进行推理。

考虑一个简单的链式因子图,其对应的概率分布为:

P(A, B, C, D) = f1(A, B) * f2(B, C) * f3(C, D)

如果我们想计算变量 AB 的联合边缘分布 P(A, B),就需要对变量 CD 求和:

P(A, B) = Σ_C Σ_D f1(A, B) * f2(B, C) * f3(C, D)

如果所有变量都是二元的,直接计算需要求和 2^2 = 4(C, D) 的组合。对于长度为 N 的链,复杂度为 O(2^N),这在 N 很大时是不可行的。

我们可以利用因子分解的结构来优化计算。观察上述求和式,发现因子 f3(C, D) 只依赖于 CD,而 f1f2 不依赖于 D。因此,我们可以先将求和操作“拉”到只涉及 D 的因子上:

P(A, B) = Σ_C [ f1(A, B) * f2(B, C) * ( Σ_D f3(C, D) ) ]

我们定义 μ_{D→C}(C) = Σ_D f3(C, D),这是一个从变量 D 发送到变量 C消息,它是一个关于 C 的函数(对于离散变量,可以看作一个向量)。

接着,我们可以对 C 进行类似操作:

P(A, B) = Σ_C [ f1(A, B) * f2(B, C) * μ_{D→C}(C) ] = f1(A, B) * ( Σ_C f2(B, C) * μ_{D→C}(C) )

定义 μ_{C→B}(B) = Σ_C f2(B, C) * μ_{D→C}(C),这是从 C 发送到 B 的消息。

最后,计算 P(A) 时:
P(A) = Σ_B f1(A, B) * μ_{C→B}(B) = μ_{B→A}(A)

通过这种方式,我们将一个全局的求和问题,分解为一系列沿着链传递的局部消息计算。对于长度为 N 的链,计算复杂度从 O(2^N) 降为 O(N * K^2)(假设每个变量有 K 个状态),实现了指数级到线性级的优化。


树状结构与信念传播算法 🌳

上一节我们看到了链式结构上的消息传递。本节中,我们将其推广到更一般的树状结构因子图上。

树状结构图没有环路,但可以有分支。此时,消息不仅需要在变量之间传递,还需要在变量因子之间传递。这使我们能更清晰地描述算法。

考虑一个树状因子图,其概率分布为:
P(A, B, C, D, E) = f1(A, B) * f2(B, C, D) * f3(D, E)

假设我们要计算边缘分布 P(A, B),即对 C, D, E 求和。我们可以通过以下步骤传递消息:

  1. 叶子节点初始化:从图的边缘开始。例如,变量节点 E 只连接因子 f3,它发送给 f3 的消息初始化为 1(均匀分布)。因子节点 f1 只连接变量 AB,它发送给 B 的消息就是它本身 f1(A, B)
  2. 消息传递:消息分为两种:
    • 从变量到因子:变量将其从其他因子收到的所有消息的乘积,发送给目标因子。
      μ_{x→f}(x) = Π_{g∈Neighbor(x)\{f\}} μ_{g→x}(x)
    • 从因子到变量:因子对除目标变量外所有关联变量的状态求和(或积分),将因子值与所有来自其他变量的消息的乘积发送出去。
      μ_{f→x}(x) = Σ_{y∈Neighbor(f)\{x\}} [ f(Neighbor(f)) * Π_{z∈Neighbor(f)\{x\}} μ_{z→f}(z) ]
  3. 收集消息计算边缘分布:当所有消息传递完毕(对于树,从叶子到根,再从根到叶子各一次即可),变量 X 的边缘分布(未归一化)正比于所有指向它的消息的乘积:
    P̃(x) ∝ Π_{f∈Neighbor(x)} μ_{f→x}(x)
    最后进行归一化:P(x) = P̃(x) / Σ_{x'} P̃(x')

以下是算法步骤的简要总结:

  • 初始化:将叶子变量节点到其唯一邻居因子的消息设为 1。将叶子因子节点到其唯一邻居变量的消息设为该因子本身。
  • 迭代更新:从叶子节点开始,按照变量→因子、因子→变量的顺序,根据上述公式计算并传递消息,直到所有消息不再变化(对于树,两轮即可)。
  • 读取边缘分布:根据公式计算每个变量的边缘分布。

最大和积算法与MAP推理 🎯

上一节我们学习了用于计算边缘分布的和积算法。本节中,我们来看看另一个密切相关的问题:最大后验概率推理,即寻找使联合概率最大的变量配置 (A*, B*, C*, ...)

解决MAP问题的算法称为最大和积算法(Max-Product Algorithm),它与和积算法结构完全相同,只是将求和操作 Σ 替换为求最大值操作 max

对于链式例子:
max_{A,B,C,D} P(A,B,C,D) = max_A max_B max_C max_D f1(A,B) * f2(B,C) * f3(C,D)

同样,我们可以通过传递消息来高效计算:

  1. 定义消息:
    μ^{max}_{D→C}(C) = max_D f3(C, D)
    μ^{max}_{C→B}(B) = max_C f2(B, C) * μ^{max}_{D→C}(C)
    μ^{max}_{B→A}(A) = max_B f1(A, B) * μ^{max}_{C→B}(B)
  2. 最终,最大概率值为 max_A μ^{max}_{B→A}(A)

但我们需要的是具体的配置 (A*, B*, C*, D*)。这需要通过回溯来获得:

  • 首先,A* = argmax_A μ^{max}_{B→A}(A)
  • 然后,将 A* 代入,求 B* = argmax_B f1(A*, B) * μ^{max}_{C→B}(B)
  • 依次类推,求出 C*D*

在树状图上,最大和积算法的消息传递公式与和积算法类似,只需将 Σ 换为 max。计算完成后,从根节点开始回溯,即可得到全局最优的MAP配置。


环状图与*似推理 🔄

到目前为止,我们假设图是树或链,没有环路。然而,在计算机视觉中(如图像网格),图通常包含环路。

我们可以直接将信念传播算法应用于带环的图,这被称为环状信念传播。但由于环的存在,消息会循环传递,算法可能不收敛,或者收敛到一个*似解,而不再是精确解。

尽管失去了精确性的保证,环状信念传播在许多实际问题中表现得出奇地好。通常的更新策略是:

  1. 并行更新所有从因子到变量的消息。
  2. 并行更新所有从变量到因子的消息。
  3. 重复上述步骤,直到消息变化小于某个阈值或达到最大迭代次数。

数值计算与算法总结 📝

在实际实现中,直接计算消息的乘积可能导致数值下溢(值太小)或上溢(值太大)。标准的解决方案是使用对数域进行计算。

定义对数消息:λ_{i→j} = log(μ_{i→j})

  • 变量到因子的消息计算从乘积变为求和:λ_{x→f}(x) = Σ_{g∈Neighbor(x)\{f\}} λ_{g→x}(x)
  • 因子到变量的消息计算涉及对数求和指数(Log-Sum-Exp),需要一些技巧来稳定数值。
  • 此外,定期对消息向量进行归一化(例如减去其均值)有助于保持数值稳定性。

以下是和积信念传播算法(对数域)的概要步骤:

  1. 输入:变量集合、因子集合(定义图模型)。
  2. 初始化:将所有消息 λ 初始化为 0(对应均匀分布)。
  3. 迭代更新
    a. 对于每个因子 f 和其邻居变量 x,按公式更新 λ_{f→x}
    b. 对于每个变量 x 和其邻居因子 f,按公式更新 λ_{x→f}
    c. (可选)对更新后的消息进行归一化(如减去均值)。
  4. 收敛判断:重复步骤3,直到消息变化很小或达到迭代上限。
  5. 输出边缘分布:对于每个变量 x,计算 log P̃(x) = Σ_{f∈Neighbor(x)} λ_{f→x}(x),然后取指数并归一化得到 P(x)
  6. 输出MAP配置(若使用最大和积):对于每个变量 x,计算 log φ(x) = Σ_{f∈Neighbor(x)} λ^{max}_{f→x}(x),然后 x* = argmax_x φ(x)。注意,对于最大和积,通常需要回溯才能获得一致的全局最优配置,但在许多情况下,直接选取每个变量的最大“边际”状态也能得到很好结果。

总结

本节课中,我们一起学习了概率图模型中的核心推理算法:

  1. 信念传播(和积算法):用于高效计算变量的边缘分布。它通过变量与因子之间的消息传递,将全局求和分解为局部计算,极大降低了复杂度。
  2. 最大和积算法:用于求解最大后验概率配置。其框架与和积算法相同,但将求和换为求最大值,并通过回溯获得最优解。
  3. 环状信念传播:将上述算法应用于带环路的图,虽为*似方法,但在实践中非常有效。
  4. 实现细节:使用对数域计算消息归一化来保证数值稳定性是实际应用中的关键。

这些算法构成了在结构化概率模型(如马尔可夫随机场、条件随机场)中进行概率推理的基础,在图像分割、立体视觉、去噪等计算机视觉任务中有着广泛应用。

021:概率图模型示例 🧩

在本节课中,我们将通过两个简单的例子来学习概率图模型的实际应用。我们将看到如何将先验知识(例如物理约束或图像*滑性)整合到模型中,从而得到比仅依赖观测数据更合理、更可靠的推断结果。

上一节我们介绍了概率图模型的基本概念和推断算法。本节中,我们来看看这些模型如何应用于具体问题。

车辆定位示例 🚗

第一个例子是车辆定位问题。我们的目标是在10个连续的时间点上,估计车辆所在的车道位置。

我们有10个随机变量,分别对应每个时间点(T1 到 T10)。每个变量可以取三个状态:车道1、车道2或车道3。下图展示了一种可能的变量配置。

除了这些变量,我们还有观测数据。观测数据以连续的概率分数形式给出,表示在每个时间步,感知模型认为车辆位于各个车道的置信度。例如,在第一个时间步,模型有70%的把握认为车辆在车道1,20%的把握在车道2,10%的把握在车道3。

如果我们简单地、独立地在每个时间步选择观测概率最高的状态,可能会得到物理上不可行的结果(例如车辆瞬间跨越多个车道)。因此,我们需要利用图模型整合先验知识。

以下是该问题的图模型表示:

  • 一元势函数 (Unary Potentials, F1...F10):由感知模型的观测概率直接确定。例如,对于第一个时间步,势函数值为 [0.7, 0.2, 0.1]
  • 成对势函数 (Pairwise Potentials, G):连接相邻时间步的变量(如X1-X2,X2-X3),用于编码先验知识(例如,车辆更可能保持在原车道或仅变换到相邻车道)。

该模型的概率分布可以分解为:
P(X) ∝ ∏_i F_i(x_i) * ∏_{(i,j)∈E} G(x_i, x_j)

其中,成对势函数 G 是一个3x3的矩阵。理想情况下,我们应该从训练数据中学习这个矩阵的参数(这将在第7讲中介绍)。在本讲中,我们假设它已给定。一个合理的设置是:停留在原车道的概率最高,变换到相邻车道有一定概率,而跨越两个车道的概率为零。

当我们使用这个结合了一元项和成对项的模型进行概率推断(如计算边缘分布)时,得到的结果会整合先验知识。例如,某个时间步下“车道3”的概率可能会根据相邻时间步的信息发生显著变化。

如果我们应用最大积算法来寻找最大后验概率解,就会得到一条物理上更合理的车辆轨迹,它虽然可能在个别时间步上与观测的“最可能”状态不符,但整体上更符合我们对车辆运动规律的认知。

图像去噪示例 🖼️

第二个例子是图像去噪。假设我们有一个质量不佳的黑白相机,它拍摄的10x10像素图像噪声很大。我们的目标是从噪声图像中恢复出干净图像。

我们可以利用与立体匹配类似的特性:相邻像素更可能具有相同的值(颜色)。如果我们只用一元势函数建模,模型会直接输出噪声图像,因为每个像素独立地选择了观测值。

为了整合先验知识,我们需要在模型中添加约束。具体来说,我们观察到在干净图像中,大多数相邻像素对(边)的颜色是相同的。例如,在一张示例图像中,总共有180条邻接边,其中只有34条边连接了不同颜色的像素,而有146条边连接了相同颜色的像素。这意味着颜色保持不变的边是颜色变化的边的4.3倍。

我们可以利用这一点,引入一个*滑性假设。模型现在包含:

  • 一元势函数:鼓励像素值与观测值一致。对于观测为黑色的像素,如果推断值也是黑色,则势函数值高(例如为1),否则低(例如为0)。我们通常使用对数势函数表示:θ_i(x_i) = log(1_{x_i = y_i}),其中 y_i 是观测值。
  • 成对势函数:定义在四连通网格上,鼓励相邻像素取值相同。其形式通常为:
    θ_{ij}(x_i, x_j) = α * 1_{x_i = x_j}
    其中 1_{x_i = x_j} 是指示函数(两者相等时为1,否则为0),α 是一个超参数,控制*滑先验的强度。

整个模型的(对数)概率分布为:
log P(X) = ∑_i θ_i(x_i) + ∑_{(i,j)∈E} θ_{ij}(x_i, x_j) - log C

现在,推断算法需要在两个目标之间进行权衡:

  1. 拟合观测数据:让每个像素的推断值尽量接*观测值。
  2. 满足*滑先验:让相邻像素的推断值尽量相同。

超参数 α 控制着这个权衡。如果 α 设为0,则先验失效,输出就是噪声图像。如果 α 设置得过大,*滑约束过强,可能导致整张图像变成同一种颜色。通过调整 α,我们可以得到不同程度的去噪效果。

本节课中我们一起学习了概率图模型在两个经典问题中的应用:车辆定位和图像去噪。我们看到,通过在图模型中引入一元势函数(对应观测数据)和成对势函数(对应先验知识,如运动*滑性或图像局部一致性),并利用推断算法进行优化,可以得到比单纯依赖观测更合理、更鲁棒的解决方案。下一讲,我们将探讨图模型在更复杂问题(如立体匹配、多视图重建)中的应用,那里会涉及更大的标签集和更高阶的势函数。

022:图模型应用 - 立体重建 🏔️

在本节课中,我们将学习如何将图模型应用于计算机视觉中的经典问题——立体重建。我们将看到,通过引入马尔可夫随机场,可以有效地整合关于场景*滑性的先验知识,从而克服局部立体匹配中的歧义性问题。

在上一讲中,我们介绍了图模型以及一种称为信念传播的推理算法,它可以帮助我们计算最大后验解或边缘概率。本节中,我们将具体探讨图模型在密集立体重建问题中的应用。

局部立体匹配的挑战

首先,让我们回顾一下局部立体匹配或块匹配所面临的困难。这些问题主要源于多种歧义性。

以下是导致匹配歧义的主要因素:

  • 无纹理表面:在另一幅图像中,无纹理区域可能与许多其他无纹理区域匹配。
  • 图像中的重复结构:场景中重复的图案会导致多个潜在的匹配点。
  • 遮挡:一个物体遮挡了另一个物体,导致某些像素在另一视图中不可见。
  • 非朗伯表面:如镜面或光泽表面,其外观随视角变化,违反了亮度恒常性假设。

为了克服这些歧义,我们需要整合关于真实世界统计特性的先验知识。例如,从布朗距离图像数据集等数据集中,我们可以发现深度图的一个关键统计特性:深度在物体边界处变化剧烈,但在其他区域变化缓慢。这反映在深度梯度的概率分布上,即大部分概率质量集中在零附*(*滑区域),但也存在远离零的“长尾”(物体边界)。

马尔可夫随机场模型

我们希望将上述统计特性整合到模型中,这可以通过马尔可夫随机场来实现。下图展示了一个四连通网格结构的图模型,对应一个图像。

在这个模型中:

  • 每个圆圈代表一个变量,即我们想要推断的该像素的视差值。
  • 一元因子(图中连接单个变量的方块)代表匹配代价,可以通过块匹配或孪生网络计算。
  • 成对因子(连接相邻变量的边)则整合了我们对视差图*滑性的先验知识。

这是一个非常简单的图模型,可以表述为一个标准的无向马尔可夫网络或马尔可夫随机场,也可以方便地表述为因子图。

我们的目标是求解整个视差图,而不仅仅是单个像素的视差。因此,我们对所有可能的视差图空间建模一个概率分布。这个概率正比于一元因子和成对因子的乘积:

$$
P(\mathbf{D}) \propto \prod_{i} \phi_{\text{data}}(D_i) \prod_{(i,j) \in \mathcal{N}} \psi_{\text{smooth}}(D_i, D_j)
$$

其中,$\mathbf{D}$ 代表整个视差图,$\mathcal{N}$ 表示相邻的像素对。

能量最小化公式

我们可以将上述概率最大化问题转化为等价的能量最小化问题,这通常更方便。通过取负对数,我们得到吉布斯能量:

$$
E(\mathbf{D}) = \sum_{i} \Phi_{\text{data}}(D_i) + \lambda \sum_{(i,j) \in \mathcal{N}} \Psi_{\text{smooth}}(D_i, D_j)
$$

其中:

  • $\Phi_{\text{data}}(D_i) = -\log \phi_{\text{data}}(D_i)$ 是数据项(匹配代价)。例如,可以使用*方差和(SSD):$\Phi_{\text{data}}(D_i) = \sum_{\mathbf{p} \in W} (I_L(\mathbf{p}) - I_R(\mathbf{p} - D_i))^2$,值越小越好。
  • $\Psi_{\text{smooth}}(D_i, D_j) = -\log \psi_{\text{smooth}}(D_i, D_j)$ 是*滑项。一个简单的形式是惩罚相邻像素视差不同的情况。更接*真实统计的是截断 L1 惩罚:$\Psi_{\text{smooth}} = \min(|D_i - D_j|, \tau)$,它在视差差异小于阈值 $\tau$ 时进行线性惩罚,大于阈值时则保持恒定,从而允许在物体边界处存在大的不连续性。
  • $\lambda$ 是正则化强度或权重参数,用于控制*滑先验的强度。如果 $\lambda = 0$,则退化为标准的“赢家通吃”块匹配算法;如果 $\lambda$ 过大,则会导致视差图过度*滑。

推理与结果

现在,我们可以使用上一讲中学到的最大乘积信念传播算法来求解这个 MRF,从而获得最大后验解,即该模型下最可能的视差图(*似)。其他算法如图割也可以用于最小化此能量。

下图展示了在 Middlebury cones 场景上使用 MRF 进行推理的结果。

可以看到,与单纯的局部块匹配算法相比,使用 MRF 推理得到的结果有了显著改善。这也解释了为什么在许多现代立体匹配方法(如 Sponar 和 Laoon 的孪生网络)中,由深度网络计算的局部匹配代价通常会辅以 MRF 推理,以克服歧义并进一步提升估计结果。

引入更强先验:物体级知识

上面讨论的是一个非常简单的 MRF。我们还可以构建更复杂的图模型,整合更多关于世界的约束,甚至是非局部先验。

在某些具有挑战性的场景(如存在强烈反射)中,简单的局部成对*滑项可能无法处理假设的严重违反。这时,我们需要引入更强的假设。

一种方法是不仅从像素层面推断深度或视差,还从物体层面进行推断。例如,在街景中,我们知道场景中包含许多汽车,并且大致了解汽车的形状。我们可以尝试联合推断视差图和物体信息。

这可以通过在能量函数中增加额外的项来实现:

  1. 语义项:使推断出的物体的语义与从图像中推断出的语义相似。
  2. 一致性项:使推断出的 3D 物体与视差图保持一致。

通过整合这种物体级的先验知识,可以进一步正则化问题,得到更好的结果。下图展示了引入物体级知识后,对反射区域等异常值的改善。

总结

本节课中,我们一起学习了如何将图模型应用于立体重建问题。

  • 块匹配 容易受到之前讨论过的匹配歧义影响,并且由于 Lecture 4 中讨论的权衡问题,窗口大小的选择非常棘手。
  • 整合运动约束 可以解决部分歧义,并允许选择更小的窗口。通过使用图模型整合*滑性约束,我们可以选择更小的窗口,同时增加*滑性参数,从而减少“渗色”伪影。
  • 公式化 这可以表述为离散 MRF 中的最大后验推理。之前展示的所有结果都是使用最大乘积算法(信念传播算法)推断得到的。图割或其他离散图模型推理算法也可以用于求解。
  • 更强先验 我们还看到,整合识别线索(如检测物体并尝试与视差图联合推断物体)可以进一步正则化问题,帮助克服非常强的歧义性。

通过本讲,我们理解了图模型为整合先验知识、解决视觉中的不适定问题提供了一个强大而灵活的框架。

023:基于图模型的多视角三维重建应用 🏗️

在本节课中,我们将学习图模型的第二个应用:密集多视角立体视觉三维重建。我们将探讨如何利用概率图模型,从多个视角的图像中重建完整的三维场景,并显式地处理重建过程中的不确定性。

概述

上一节我们介绍了图模型的基本概念。本节中,我们将看看如何将其应用于一个具体的计算机视觉问题——从多张图像中重建三维场景。与仅使用两张图像的稀疏重建相比,多视角重建能提供更多约束,从而更好地解决歧义性问题,并实现完整的三维重建,而不仅仅是2.5D的深度图表示。

问题定义与挑战

我们的目标是:给定一组输入图像(实践中通常使用50到100张),推断出场景的完整三维体素表示或深度图。

然而,即使使用更多相机,基于图像的三维重建仍然可能是一个高度不适定的问题。例如,在纹理缺失的区域,由于所有像素颜色相*,从不同视角观察时,可能存在多个看似合理的表面,导致重建存在大量歧义。虽然可以通过引入先验(如假设区域是*坦的)来消除部分歧义,但先验越强,假设被违反时可能导致的错误也越大。因此,处理并显式地表达不确定性至关重要。

概率图模型表示

我们能否利用概率图模型的力量,以概率化的方式构建密集多视角三维重建问题?答案是肯定的。

以下是我们将要使用的表示方法:

  1. 体素化:我们将考虑的三维空间离散化为一个离散的体素集合。每个小立方体就是一个体素。在实践中,我们通常使用分辨率高达 1000 x 1000 x 1000 的体素网格。
  2. 随机变量:为每个体素关联两个随机变量:
    • 体素占用率 O:一个二元随机变量。O = 1 表示该体素被占据(有物体),O = 0 表示该体素为空。
    • 体素外观 A:一个实数标量,表示该体素在图像中呈现的亮度(灰度值)。为简化,我们这里仅考虑灰度图像,但可以扩展为三维向量以表示颜色。
  3. 光线表示法:我们引入一个简写符号来帮助后续建模。对于相机图像*面上的一个像素,其与相机中心定义了一条穿过三维空间的光线 R。对于每条光线 R,我们定义:
    • O_R:按光线穿过的顺序,收集该光线相交的所有体素的占用率变量 O_i
    • A_R:按光线穿过的顺序,收集该光线相交的所有体素的外观变量 A_i

图像形成模型

为了解决这个不适定问题,我们首先需要理解图像形成过程。

直观上,对于一个固体物体,特定像素(对应特定光线 R)的颜色,就是该光线穿过的第一个被占据体素的颜色。从相机中心沿光线前进,遇到的第一个被占据体素的外观决定了像素值。

我们可以用以下公式精确描述这一过程:

I_R 表示像素 R 的强度(颜色),O_iA_i 是沿光线 R 排序的占用率和外观变量(i 从1到 N_RN_R 是该光线相交的体素数)。那么:

I_R = Σ_{i=1}^{N_R} [ (1 - O_1) * (1 - O_2) * ... * (1 - O_{i-1}) * O_i * A_i ]

这个公式的含义是:求和项中的乘积项 (1 - O_1)*...*(1 - O_{i-1})*O_i 仅在 O_i 是第一个被占据的体素时为1,否则为0。因此,整个求和的结果就是第一个被占据体素的外观 A_i

概率模型构建

我们希望构建一个概率模型来进行推理,从而显式地表达不确定性。

我们定义所有体素占用率变量(O)和外观变量(A)的联合概率分布 P(O, A)。我们将其分解为单点势函数和所谓的“光线因子”的乘积:

P(O, A) ∝ Π_{voxels} ψ_u(O_i) * Π_{rays R} ψ_R(O_R, A_R)

  • 单点势函数 ψ_u:表示关于场景占用率的一般先验知识。例如,可以是一个伯努利分布,其超参数 γ 控制我们认为体素被占据的先验概率(通常 γ 小于0.5,因为场景中大部分体素是空的)。这有助于清理模型推断出的一些离群点。
  • 光线因子 ψ_R:这是模型的核心,它建模了我们想要推断的三维重建与所有观测图像之间的一致性。这是一个高阶势函数,因为它连接了一条光线上所有的 OA 变量(可能多达数百个)。

光线因子基于我们的图像形成模型构建:

ψ_R(O_R, A_R) = N(I_R; A_k, σ²)

其中,k 是第一个满足 O_k = 1 的索引。N 表示高斯分布,均值是第一个被占据体素的外观 A_k,方差 σ² 是一个可调超参数,用于允许由于噪声和模型简化假设而带来的外观微小偏差。

这个势函数的意义在于:对于所有相机中的所有光线,如果三维重建中每条光线上第一个被占据体素的外观 A_k 与对应像素的观测值 I_R 越接*,那么整个联合概率 P(O, A) 的值就越大。多视角的约束共同作用,使得我们可以推断出与所有图像一致的三维重建,并减少不确定性。

概率推理:计算深度分布

我们使用和积算法在该模型中进行概率推理。

一个最简单的推理问题是:对于场景中的任意一条光线(可以是输入视角的,也可以是新视角的),沿着这条光线到第一个被占据体素的深度是多少?如果我们能回答这个问题,就能重建深度图,进而提取网格等。

设光线 R 上第 k 个体素到相机中心的距离为 d_k。沿该光线的深度 D 定义为到第一个被占据体素的距离,因此 D 取值于集合 {d_1, d_2, ..., d_{N_R}}

在贝叶斯推理和风险最小化的框架下,最优深度估计 D* 是使期望损失(风险)最小的那个值:

D* = argmin_{d'} E_{P(D)} [ L(D, d') ]

其中,P(D) 是沿光线的深度 D 的边际分布。如果我们选择损失 L 为*方误差,则最优估计是深度分布的均值;若选择绝对误差,则是中位数。

因此,问题的关键在于计算边际深度分布 P(D)。这正是和积算法可以计算的量。

推理过程的简化

由于光线因子是高阶的,直接计算消息传递非常复杂,具有指数级复杂度。幸运的是,在这个特定设置下,公式可以大幅简化。

通过一系列推导(具体细节可参考相关论文),计算深度 D 等于 d_k 的概率 P(D = d_k) 的表达式可以简化为:

P(D = d_k) ∝ [Π_{i=1}^{k-1} μ_{O_i→ψ_R}(0)] * μ_{O_k→ψ_R}(1) * ∫ N(I_R; a_k, σ²) * μ_{A_k→ψ_R}(a_k) da_k

这个表达式的直观解释很清晰:

  • 第一部分(红色):表示前 k-1 个体素都必须为空(O_i = 0),这样第 k 个体素才可能是第一个被占据的。
  • 第二部分(绿色):表示第 k 个体素被占据(O_k = 1)且可见。
  • 第三部分(蓝色):表示这第一个被占据体素的外观 a_k 应该与观测到的像素值 I_R 接*。

这个简化后的表达式不再需要对巨大状态空间进行求和与积分,只需要计算一个一维积分和若干项的乘积,复杂度降为线性。

公式中的 μ 代表在和积算法中传递的消息。这些消息通过迭代式的信念传播进行计算:消息从光线因子传递给体素变量,再从体素变量传递给光线因子,直至收敛。

虽然从高阶势函数传回变量的消息计算最初看起来也很复杂,但利用类似的简化技巧,同样可以将其计算复杂度降至线性时间。具体推导较为技术性,在此省略。

实现挑战与解决方案

将信念传播应用于多视角立体视觉面临几个挑战:

  1. 混合变量:模型包含离散(占用率 O)和连续(外观 A)变量。
  2. 高阶因子:光线因子是高阶的,且数量巨大(每个像素对应一个因子),计算量大。
  3. 计算效率:需要处理海量体素和光线。

相应的解决方案包括:

  • 连续信念传播:通过用高斯混合模型*似消息,并利用重要性采样进行更新,来处理连续变量。
  • 线性时间消息计算:利用模型结构的特殊性,推导出线性复杂度的精确消息更新公式。
  • GPU并行化:采用八叉树等高效数据结构,并在GPU上高度并行化地执行算法,以在合理时间内获得结果。

实验结果与扩展

在真实数据集(如Providence城市数据集)上的实验表明,这种概率化方法相比之前不显式处理不确定性的算法(如最大后验推理),性能有所提升,尤其是在纹理缺失区域。

更值得关注的是定性结果:算法不仅能重建几何和外观,还能通过不确定性图(如白色区域表示高不确定性)显式指出哪些区域的重建置信度低(例如镜面反射的玻璃幕墙)。

此外,该方法可以扩展以整合形状先验知识。例如,对于城市街景,可以从在线3D模型库中获取粗糙的建筑轮廓模型;对于室内场景,可以获取家具的CAD模型。通过将这些形状作为先验(通常表示为粒子集以建模位姿不确定性),并联合推断几何、外观和物体位姿,可以进一步改善在纹理缺失或具有歧义区域的重建效果。

总结与展望

本节课我们一起学习了基于概率图模型的多视角三维重建方法。

优点

  • 概率化公式是可行的,因为光线因子可以分解,避免了指数级复杂度。
  • 可以通过在2D和3D中进行联合推理来整合非局部约束。
  • 能够整合CAD模型等先验知识,帮助消除纹理缺失区域的歧义。
  • 能够处理大规模场景(如 1024^3 体素)。

局限性与未来方向

  • 由于使用带环的高阶马尔可夫随机场,只能进行*似推理。
  • 计算速度相对较慢(即使在GPU上也需要数分钟)。
  • 外观模型过于简化,未考虑非朗伯体反射、噪声和异常值。
  • 分辨率受限于离散体素表示。

在本课程后续内容中,我们将看到一些基于神经网络的隐式表示方法,它们能够解决离散体素表示的分辨率限制问题,并实现更高质量的重建。

024:光流应用 🎥

在本节课中,我们将要学习光流问题,并探讨如何将其表述为马尔可夫随机场中的推理问题。

光流被定义为视觉场景中物体、表面和边缘的视在运动,这种运动是由观察者与场景之间的相对运动引起的。例如,在飞行员降落的场景中,可以观察到扩张点,靠*观察者的点运动幅度较大,而远处的点运动幅度较小。这种像素在图像中的视在运动,可能是由场景中的物体运动或观察者自身运动引起的。在本例中,场景是静态的,但相机相对于场景运动,从而产生了运动场。

光流最初由心理学家 J. Gibson 在 20 世纪 50 年代研究,他分析了动物如何进行低级感知,并将这些想法用于帮助飞行员导航。光流当然与立体视觉有关,两者都是二维估计问题,但关键区别在于:立体视觉是在同一时间拍摄两张图像(或等效地对静态场景拍摄两张图像),而光流不做此假设,这两张图像是在两个时间步拍摄的,对场景没有任何限制。因此,立体视觉只涉及相机运动,而光流涉及相机和物体运动。立体视觉是一个一维估计问题,一旦找到极线几何,就可以沿极线进行一维搜索。而光流是一个完整的二维估计问题,第一幅图像中的一个像素可以位于第二幅图像中的任何像素位置,没有先验约束。此外,不同动物对这两种原理的利用程度也不同,例如,猴子和人类一样拥有前向视觉系统,重叠视野很大,因此深度感知能力很强;而松鼠拥有侧向视觉系统,重叠视野很窄,立体视觉能力不强,但能很好地感知 360 度范围内的运动。

在开始之前,需要定义两个术语:光流和运动场。运动场是我们真正想要测量的东西,它代表了场景中点的实际三维运动在图像*面上的二维投影运动。例如,假设有一个图像*面和相机中心,一个三维点从一处移动到另一处,并投影到图像*面的不同位置,这就是我们想要测量的运动场。但我们无法直接获取它,因为我们不知道这些投影点对应的是同一个物理点。我们只有二维图像投影,没有关于世界的任何三维结构或物理信息。光流则是描述图像中视在运动的二维速度场,这是我们实际可以测量的,即看起来相似的像素的位移。如果图像中有一个角点,其运动是明确的,那么我们可以通过光流匹配这两个角点,此时光流场与运动场相同。在大多数情况下,它们是一致的,因此估计光流是有用的,但并非总是如此。

光流场与运动场并不总是一致。让我们进行一个思想实验:考虑一个朗伯球体(无镜面反射材质),它围绕垂直轴在三维空间中旋转。其二维运动场会显示小球边缘的运动矢量。但由于它是无纹理的朗伯球体,尽管在旋转,其外观并未改变,因此光流场将为零,我们观察不到任何运动。相反,考虑一个静止的镜面球体,其表面有高光。如果我们不移动球体,而是移动光源,那么这个高光就会在球体表面移动。此时,球体是静态的,三维几何未变,因此运动场处处为零。但光流场不为零,因为高光在移动,光流算法会检测到这个高光的运动。这两个例子说明了运动场与光流场的区别。

因此,光流告诉我们关于世界三维结构、观察区域内物体运动以及观察者自身运动的一些信息,这些信息可能是模糊的。它是我们希望估计的运动场的一种替代,并且通常是一个相当准确的替代,除了上述极端情况。与立体视觉相比,我们不能对极线几何做任何假设,它是一个真正的二维估计问题,因此更困难,搜索空间也大得多。动物也利用光流,例如北方塘鹅,这种鸟在水面上方盘旋捕鱼。它需要精确计算入水时机,通过感知水面图案的运动速度(光流),在毫秒级精度内确定撞击水面的时间点,以便及时收拢翅膀。

当然,光流在计算机视觉中也有许多重要应用。其中一个应用是视频插值或帧率适配。如果我们知道两帧之间的图像运动(由光流场表示),就可以对第一帧图像进行扭曲,合成中间时刻的虚拟帧,从而创建人工慢动作效果。例如,在电影制作中,通过环绕演员放置多个摄像机,然后利用光流在摄像机视角之间插值,可以创建出虚拟的、*滑环绕拍摄的“子弹时间”特效。

光流也可用于视频压缩。为了压缩图像序列,我们可以使用光流场预测新帧,然后只存储光流和预测误差。由于光流场是*滑的,它们比单独存储第二幅图像更容易压缩。类似原理被应用于 MPEG 等视频压缩算法中。

在自动驾驶中,如果将视差(深度)与光流结合,可以得到三维运动,这被称为场景流。通过立体相机跟踪随时间变化的帧,可以推断出许多三维点的运动方向。

现在,光流面临一个问题,也许是最著名的问题:孔径问题。孔径问题描述如下:如果只有一个观测点(例如通过一个小孔观察场景),我们能否确定物体如何运动?例如,观察一个物体边缘的一小部分,我们可能无法确定其真实运动方向。一个经典的错觉是,通过小孔观察一条线的运动,可能被感知为斜向运动,而实际上整条线是水*移动的。这意味着单点观测不足以确定光流。从数学上讲,如果只观察单个像素的强度变化,我们无法确定光流,因为光流有两个未知数(x 和 y 方向的运动)。类似的效应也出现在理发店旋转灯柱的错觉中,其产生的光流图案与实际旋转方向垂直。

现在我们知道了光流是什么,接下来需要确定如何计算它。Horn 和 Schunck 的论文《Determining Optical Flow》是该领域的开创性工作,引发了大量后续研究。还有另一篇著名论文是 Lucas-Kanade 光流法,但那是局部光流方法,存在窗口效应。因为我们是在马尔可夫随机场的背景下考虑光流,而 Horn-Schunck 算法与此相关,因为它也做出了*滑性假设。

让我们从数学上表述这个问题。将图像 I 视为连续变量 X, Y, T 的函数,形成一个连续的时空体积。我们想要推断的是一个连续的流场,它由两个一维函数 U(x,y) 和 V(x,y) 表示,分别代表图像*面 x 和 y 方向的流动。这是一个变分问题,我们需要最小化一个能量泛函。在 Horn-Schunck 的原始公式中,能量泛函包含两项:第一项是亮度恒定假设的二次惩罚项,即一个像素根据光流 (U, V) 移动到下一帧时,其亮度应保持不变;第二项是流场变化的正则化项(*滑项),通过最小化流场梯度(U 和 V 的梯度)的*方来实现,这迫使光流在局部邻域内变化*缓。

直接最小化这个能量非常困难,因为能量高度非凸且有许多局部极小值。问题在于第一项中,光流场 U, V 是图像函数的参数,而图像本身高度非线性。解决方案是对亮度恒定假设进行线性化,即采用一阶泰勒*似。线性化后,第一项变成了 U 和 V 的二次项,从而使整个能量函数关于 U 和 V 是凸的(二次的),更容易求解。

当然,在计算机中我们需要离散化。将连续的积分变为对像素的求和,连续函数 U, V 变为离散矩阵。此时,能量函数是关于所有 U、V 变量的二次函数,因此存在唯一最优解,可以通过求解大型稀疏线性系统得到。由于变量数量巨大(与图像像素数相同),通常使用迭代求解器(如梯度下降、高斯-赛德尔迭代)。这种方法的一个问题是,线性化假设只对非常小的运动有效。为了解决大运动问题,通常采用由粗到精的估计策略:首先在低分辨率图像金字塔上估计光流,然后将估计结果上采样,作为下一级更高分辨率图像的初始值,并在此过程中对目标图像进行扭曲,从而逐步细化光流估计。

Horn-Schunck 算法的结果已经相当合理,但流场过于*滑。仔细观察会发现,不同物体之间的光流过渡不够锐利,出现了过度*滑。这是因为为了克服孔径问题和病态性,我们需要将正则化参数 λ 设置得相对较高,但这导致了过度*滑。问题的根源在于我们使用了二次惩罚项(L2 正则化),它对大的变化惩罚过重,不利于保持光流的不连续性(如物体边界处)。因此,需要使用更鲁棒的惩罚函数,使其更符合真实世界的统计特性。

这就将光流问题与 MRF 中的 MAP 推理联系了起来。我们可以将推导出的光流能量函数代入吉布斯分布,从而得到一个概率分布。在此分布上执行 MAP 推理等价于最小化该能量函数。由于此处的 U 和 V 是连续的(不同于立体匹配中的离散变量),我们使用梯度下降进行推理,而非置信传播。二次惩罚项对应于高斯分布假设,但这对于数据项和*滑项都是无效的,因为高斯分布(对应*方损失)对离群点(如遮挡、镜面高光)和流场不连续性不够鲁棒。

解决方案是使用鲁棒的数据项和*滑项惩罚函数。在概率公式中,我们用重尾的学生 t 分布代替高斯分布,这在能量域对应于柯西惩罚函数。学生 t 分布的负对数密度函数增长缓慢,对大的误差惩罚较轻,因此能更好地处理离群值和光流不连续性。与高斯分布相比,学生 t 分布与真实光流梯度等数据的经验分布更匹配。采用这种鲁棒惩罚函数(如 Black 和 Anandan 的方法)后,得到的光流结果边界更加锐利。

最后需要提及,光流不仅可以通过经典的图模型推理或变分技术解决,*年来也广泛采用深度学习。由于获取真实光流标注数据非常困难,深度学习在该领域的发展一度滞后。早期的 FlowNet 模型使用了大量合成数据进行有监督训练,其网络结构类似于 U-Net 或沙漏网络。后续的 FlowNet 2.0 通过堆叠多个网络处理不同尺度运动,在 2017 年达到了先进水*。更*期的研究表明,也可以通过无监督方式训练光流网络,其原理类似于经典方法:利用网络预测前向和后向光流,进行一致性检查,并施加类似于经典方法的数据损失和*滑损失。这种自监督学习方法将在第 12 讲中详细介绍。

总结来说,经典光流方法在 2016-2017 年前一直保持领先,此后深度学习方法达到并超越了经典方法。但深度方法需要大型模型、海量合成训练数据、强大的 GPU 算力和复杂的课程学习策略。目前,最先进的技术无疑是深度学习,因为有了更多更好的数据集(包括真实标注数据)。有趣的是,顶尖的深度学习方法也借鉴了许多经典方法的元素,如扭曲、迭代估计、由粗到精和代价体积等思想。

本节课中,我们一起学习了光流的定义、其与运动场的区别、经典的 Horn-Schunck 算法及其变分公式、由粗到精策略、与马尔可夫随机场的联系、使用鲁棒惩罚函数的重要性,以及深度学习在光流估计中的最新进展。

025:条件随机场与图模型学习 🧠

在本节课中,我们将学习图模型中的参数估计问题,即如何从数据中学习模型的参数。我们将重点介绍条件随机场这一关键概念,它是解决此类学习问题的基础框架。

在第五讲中,我们介绍了图模型和一种基本的推断算法——信念传播算法,用于求解变量的边缘分布或最大后验解。在第六讲中,我们看到了图模型的应用,以及如何将关于问题的先验知识(例如深度图的*滑性)编码到模型中。

到目前为止,我们所见的模型都包含一些参数,例如立体视觉中的*滑度参数 λ。在本讲中,我们将讨论如何根据数据集来估计这些参数。

从马尔可夫随机场到条件随机场 🔄

到目前为止,我们讨论的是马尔可夫随机场因子图。为了回顾,马尔可夫随机场定义了随机变量的联合概率分布。以一个图像去噪的简单MRF为例,我们有100个随机变量,其分布由一元势函数和相邻像素间的成对势函数之和的指数形式定义,并需要除以配分函数进行归一化。

我们之前讨论的是MRF中的推断问题,即估计变量的边缘分布 P(x_i) 或寻找最大后验解 argmax_{x} P(x)。前者在计算期望时很重要,后者在只需要一个最优估计点时很有用。

本节课我们将讨论学习问题:如何从数据集中估计模型参数?在简单例子中只有一个标量参数 λ,但我们可以有更多参数。

条件随机场的引入是因为学习需要从更大的数据集中进行,而不仅仅是针对一个特定实例。因此,我们需要以条件的形式来表述问题,这引出了结构化输出学习

在结构化输出学习中,我们学习一个带参数 W 的映射函数 F,它从输入空间 X 映射到输出空间 Y。关键点在于,输出 Y 是复杂的结构化对象,例如图像、语义分割图或文本。

条件随机场的定义 📝

在条件随机场中,我们显式地表达了输出 Y 对输入 X 和参数 W 的条件依赖。因此,概率分布写作 P(Y | X; W)

  • 输入 X: 例如一张带噪图像。
  • 输出 Y: 例如对应的去噪图像(即之前MRF中的 x)。
  • 参数 W: 需要学习的模型参数。

势函数现在同时是输入 X 和输出变量 Y 的函数。学习的目标是:给定一个由输入-输出对 (X_i, Y_i) 组成的数据集(例如带噪图像和干净图像对),估计最优参数 W,使得模型在面对新的、未见过的输入时能做出最佳预测。

条件随机场的一般形式 🧮

我们可以将CRF写成更一般的形式。假设模型包含一元、成对或更高阶的势函数,我们可以将所有势函数(特征函数)拼接成一个长的特征向量 Ψ(X, Y)。那么条件概率分布可以写为:

P(Y | X; W) = (1 / Z(X; W)) * exp( <W, Ψ(X, Y)> )

其中:

  • W 是参数向量。
  • Ψ(X, Y) 是特征向量,它将输入 X 和输出 Y 映射到一个 D 维特征空间。
  • < , > 表示内积运算。
  • Z(X; W) = Σ_{Y'} exp( <W, Ψ(X, Y')> ) 是配分函数,确保概率归一化。它对所有可能的输出 Y' 求和。

这种形式比单一参数灵活得多,因为 W 可以为模型定义的每个特征分配不同的权重。特征函数 Ψ(X, Y) 通常根据图模型的结构进行分解,例如,将所有一元特征和所有成对特征分别拼接起来。

学习的目标是:从标注数据集 {(X_1, Y_1), (X_2, Y_2), ..., (X_N, Y_N)} 中估计参数向量 W


本节课中,我们一起学习了图模型中的参数学习问题。我们首先回顾了马尔可夫随机场中的推断任务,然后引出了为进行基于数据集的学习而必须定义的条件随机场。我们明确了CRF将输出 Y 条件于输入 X 的建模方式,并给出了其从具体例子到一般形式的数学定义。下一节中,我们将探讨在这种线性或对数线性参数化下,如何具体求解这个学习问题。

026:条件随机场中的参数估计 📊

在本节课中,我们将学习如何估计条件随机场(CRF)的参数。我们将从最大似然估计的目标出发,推导出需要优化的损失函数及其梯度,并探讨如何利用图模型的结构和高效推理算法,使原本计算量巨大的参数学习过程变得可行。

概述

我们的目标是,在给定输入数据 x 的条件下,找到参数向量 W,使得模型预测输出 y 的似然概率最大化。这等价于最小化负对数似然损失函数。对于我们所考虑的局部线性模型,这是一个凸优化问题,因此梯度下降法可以找到全局最优解。

最大似然估计目标

首先,我们假设数据集中的样本是独立同分布的。因此,整个数据集的条件概率可以分解为各个样本条件概率的乘积。我们的目标是找到参数向量 W,使得模型分布尽可能接*数据分布。

数学上,我们希望找到最大似然估计参数 Ŵ_MLE

Ŵ_MLE = argmax_W P(Y | X, W)

由于对数函数是单调的,最大化似然等价于最小化负对数似然损失函数 L(W)

L(W) = -∑_n log P(yⁿ | xⁿ, W)

其中,n 遍历数据集中的所有样本。

损失函数与梯度推导

上一节我们明确了优化目标,本节中我们来看看损失函数的具体形式及其梯度。

将CRF的条件概率公式代入损失函数,并应用对数运算法则,我们可以得到:

L(W) = ∑_n [ -〈W, ψ(xⁿ, yⁿ)〉 + log Z_W(xⁿ) ]

其中,〈·, ·〉 表示内积,ψ 是特征函数,Z_W(xⁿ) 是配分函数,定义为:

Z_W(xⁿ) = ∑_y exp(〈W, ψ(xⁿ, y)〉)

接下来,我们需要计算损失函数 L(W) 关于参数 W 的梯度。梯度计算如下:

∇_W L(W) = ∑_n [ -ψ(xⁿ, yⁿ) + E_{y~P(y|xⁿ,W)}[ψ(xⁿ, y)] ]

梯度的直观解释是:它等于数据特征(来自标注样本 yⁿ)与模型期望特征(在当前参数 W 下,模型预测的特征期望值)之间的差值。当模型预测的特征期望与数据特征相匹配时,梯度为零,达到一个临界点。

优化方法与计算挑战

我们已经得到了损失函数和梯度的表达式,接下来需要考虑如何优化。最直接的方法是使用梯度下降法及其变种(如线搜索、共轭梯度法)。

然而,计算 L(W)∇_W L(W) 面临一个巨大的挑战:它们都涉及对输出空间 y 的求和。对于像图像分割这样的任务,y 的空间是指数级巨大的(例如,对于一个640x480的二进制分割图,有 2^(640*480) 种可能),直接计算是完全不可行的。

计算复杂度主要来自三个方面:

  1. 数据样本数 N:需要对所有训练样本求和。
  2. 输出空间大小 C^M:需要对所有可能的输出配置求和,这是主要瓶颈。
  3. 特征维度 D:需要计算高维特征向量的内积。

利用图模型结构实现高效计算

面对指数级的状态空间,我们必须利用图模型的结构来简化计算。关键在于,在CRF中,全局特征向量 ψ(x, y) 可以分解为多个局部势函数(因子)的拼接。

例如,在具有一元和二元势函数的模型中:
〈W, ψ(x, y)〉 = ∑_k 〈W_k, ψ_k(x, y_k)〉
其中,y_k 只涉及第 k 个势函数相关的少数变量(如单个像素或相邻像素对)。

这种分解带来了两个关键简化:

1. 高效计算配分函数:
配分函数 Z_W(x) 现在变成了对因子乘积的求和。对于结构简单的图模型(如树状结构或低团阶数的模型),我们可以使用置信传播等消息传递算法高效地计算边际概率,进而得到配分函数,而无需枚举所有状态。

2. 高效计算特征期望:
特征期望 E[ψ(x, y)] 由于期望的线性性质,可以分解为各个局部特征期望的和:
E[ψ(x, y)] = ∑_k E[ψ_k(x, y_k)]
而每个局部期望 E[ψ_k(x, y_k)] 只需要在很小的变量子集 y_k 上,利用已计算出的边际概率进行求和即可。

通过这种分解,计算复杂度从可怕的 O(C^M) 降低到了 O(K * C^F),其中 F 是最大因子的阶数(通常为2或3),K 是因子数量。这使得学习变得可行。

应对大规模数据与高维特征

除了状态空间问题,在实际训练中我们还需应对其他挑战:

1. 大规模数据集:
当训练集很大时,每次梯度更新都要遍历所有样本计算损失和梯度,计算量依然很大。解决方案是采用随机梯度下降(SGD)。在SGD中,每次迭代只随机抽取一个小批量(Mini-batch)样本来计算梯度并更新参数。虽然需要更多迭代次数,但每次迭代更快,且对内存更友好。

2. 高维特征:
特征向量 ψ 的维度 D 可能很高(例如,来自深度网络的特征),导致内积计算和参数更新变慢。一种常见的策略是进行分阶段训练:首先,使用非线性分类器(如SVM、神经网络)单独预训练一元势函数,将其输出(如对数概率)作为CRF中低维的、固定的“特征”。这样,CRF训练时只需要学习相对低维的 pairwise 势函数的权重,从而加速训练和推理。但缺点是,如果一元分类器本身性能很差,CRF也难以修复。

应用实例

以下是条件随机场在计算机视觉中的几个典型应用,它们都遵循“局部线索+先验约束”的模式:

  • 语义分割:输入是图像,输出是每个像素的类别标签。
    • 一元势函数:基于像素外观(如颜色、纹理、深度特征)判断其属于某类别的概率。
    • 二元势函数:鼓励相邻像素具有相同标签,以产生*滑的分割结果。
  • 手写识别:输入是字符图像序列,输出是字符标签序列。
    • 一元势函数:基于单个字符图像识别其类别。
    • 二元势函数:编码语言模型,即某些字符组合(如“qu”)比另一些(如“qz”)更可能出现。
  • 人体姿态估计:输入是图像,输出是每个像素所属的身体部位。
    • 一元势函数:基于局部图像特征分类像素属于哪个身体部位。
    • 二元/高阶势函数:编码身体部位之间的空间约束关系(如头通常在躯干上方)。

在这些应用中,CRF的学习过程就是调整一元和二元势函数的权重,使得模型能结合局部预测和全局先验,得到更干净、更一致的结果。

总结

本节课中我们一起学习了条件随机场的参数估计方法。我们了解到:

  1. 参数估计的目标是通过最大似然估计,使模型分布逼*数据分布,这转化为最小化负对数似然损失函数的凸优化问题。
  2. 损失函数及其梯度的计算,核心难点在于对指数级大小输出空间的求和。
  3. 通过利用图模型的因子分解结构,我们可以借助置信传播等推理算法高效计算配分函数和特征期望,从而将计算变得可行。
  4. 对于大规模数据,采用随机梯度下降(SGD) 可以有效加速训练。
  5. 对于高维特征,分阶段训练策略(先预训练强一元分类器)可以简化CRF的训练过程。
  6. 在语义分割、手写识别、姿态估计等任务中,CRF通过结合局部分类结果和全局结构化先验,显著提升了预测效果。

因此,训练一个CRF模型本质上是在高效推理算法的支撑下,进行梯度下降优化,以学习如何最佳地融合局部证据与结构化约束

028:从X恢复形状 - 从明暗恢复形状 (Shape-from-X - Shape-from-Shading) 👁️

在本节课中,我们将学习如何从图像中恢复三维几何形状,特别是利用“明暗”这一视觉线索。我们将从最基础的“从明暗恢复形状”技术开始,探讨如何仅凭单张图像的亮度变化来推断物体表面的三维信息。

概述

在之前的课程中,我们已经学习了两种从图像重建三维几何的技术:双目立体视觉和多视图重建。今天,我们将探讨如何利用其他线索,特别是“明暗”线索。本讲座分为四个部分:首先,我们将讨论“从明暗恢复形状”,这是一种允许我们从单张图像重建三维信息的技术。其次,我们将介绍“光度立体视觉”,可以看作是“从明暗恢复形状”在多光源条件下的推广。第三,我们将概述包括上述技术在内的各种“从X恢复形状”方法。最后,我们将学习如何融合这些技术得到的不完整重建结果,形成一个更全局、更大规模的世界模型。

第一单元:从明暗恢复形状 (Shape from Shading)

本节我们将探讨的核心问题是:我们能否仅通过观察单张图像的明暗变化来恢复形状?这里的“明暗”指的是图像中观察到的相对亮度。换句话说,我们想要揭示亮度与形状之间的关系。直观上,这似乎是可能的,就像人类观察图像时,即使不认识物体,也能通过明暗线索对光源位置和物体形状有所感知。

然而,从单张图像解决这个逆问题非常具有挑战性。著名的Adelson和Pentland的“Checker Shadow”错觉就很好地说明了这一点:能够产生完全相同二维像素配置的形状、材质和光照组合是极其庞大的。因此,我们需要引入先验和假设,来找到最可能的三维几何解释。

为了解决问题,我们必须回顾第二讲中提到的图像形成过程,即渲染方程。

渲染方程回顾

渲染方程描述了三维表面点P反射到观察方向V的光量。设V为观察方向,S为入射光方向,N为表面法线。方程如下:

L_out(V) = L_e(V) + ∫_Ω f_r(P, ω_i -> V) L_in(ω_i) (N · ω_i) dω_i

其中:

  • L_out(V) 是沿观察方向V的出射光亮度。
  • L_e(V) 是表面自发光项(通常不考虑)。
  • f_r 是双向反射分布函数,定义了光在表面点P如何反射。
  • L_in(ω_i) 是沿方向ω_i的入射光亮度。
  • (N · ω_i) 是余弦项,模拟了入射角对接收光量的影响(朗伯余弦定律)。

这是最一般的形式。为了应用于从明暗恢复形状问题,我们需要做出一系列简化假设。

关键假设与简化

为了得到一个可解的简单方程,我们做出以下假设:

  1. 朗伯表面 (Lambertian Surface):假设物体表面是纯漫反射的。这意味着BRDF是一个常数,称为反照率 (albedo, ρ)。光被均匀地散射到所有方向。
  2. 单一点光源 (Single Point Light Source):假设场景由一个位于方向S的远距离点光源照明,没有环境光。这使得对半球面的积分简化为一个点。
  3. 正交投影 (Orthographic Projection):假设相机位于无穷远处,观察方向V对所有像素是恒定的。

在这些假设下,渲染方程简化为:

L_out = ρ * (N · S) * L_in

如果我们进一步将乘积 ρ * L_in 吸收到观测到的图像强度 I 中(或假设其为1),则得到核心关系:

I(x, y) ∝ R(N) = N · S

这里,R(N) 被称为反射率图,它建立了表面法线N与观测图像强度I之间的直接联系。我们的目标就是从观测到的I反推出N

法线参数化:梯度空间

表面法线N是一个三维单位向量,具有两个自由度。为了方便表示,我们使用梯度空间。设深度图为Z(x, y),我们定义表面梯度 p = -∂Z/∂x, q = -∂Z/∂y。那么,表面点(x, y)处的法线可以表示为:

N = [p, q, 1]^T / sqrt(p^2 + q^2 + 1)

这样,我们用法线梯度(p, q)这两个变量替代了三维法线。反射率图也可以重写为:

R(p, q) = (p*s_x + q*s_y + s_z) / sqrt(p^2 + q^2 + 1)

其中 S = [s_x, s_y, s_z]^T 是已知的归一化光源方向。

问题的病态性与等亮度线

对于一个给定的像素强度观测值 I,满足 R(p, q) = I(p, q)组合有很多。在梯度空间中,这些解构成了一条曲线,称为等亮度线。下图展示了对于不同的I值,等亮度线是椭圆、抛物线或双曲线等圆锥曲线。

这意味着,仅凭单个像素的亮度,我们无法唯一确定其法线。除了I = 1(法线与光源方向完全一致)和I = 0(法线与光源方向垂直)等特殊情况外,解空间都是一个连续集。

为了获得唯一解,我们需要引入额外的约束。主要有两种思路:1) 在单张图像中增加正则化约束(即经典的从明暗恢复形状);2) 增加更多的观测(即下一节的光度立体视觉)。

从明暗恢复形状的变分公式

经典的从明暗恢复形状方法通过引入以下约束来解决病态问题:

  1. 图像亮度误差:重建的法线应使预测的亮度R(p, q)与观测亮度I(x, y)尽可能一致。
  2. *滑性约束:假设物体表面是光滑的,即相邻点的法线变化应尽可能小。这通过惩罚pq的梯度幅值来实现。
  3. 遮挡边界约束:假设我们已知物体的分割掩码。在物体的遮挡边界上,表面法线必须与视线方向垂直,并且与边界切线方向垂直。这为边界上的法线提供了强约束。

综合以上约束,我们构建一个能量函数进行优化:

E(p, q) = ∫∫ [(I(x,y) - R(p,q))^2 + λ (||∇p||^2 + ||∇q||^2)] dx dy

其中λ是*滑项权重。在优化时,将遮挡边界上的法线固定为已知值,内部区域的法线初始化为零,然后进行迭代优化直至收敛。

从法线图到深度图

优化后我们得到的是表面梯度场(p, q),即法线图。要得到最终的三维形状(深度图Z),需要“积分”这些梯度。这可以通过求解另一个变分问题来实现:

min_Z ∫∫ [ (∂Z/∂x + p)^2 + (∂Z/∂y + q)^2 ] dx dy

这个问题的目标是找到一个深度图Z,其梯度与估计出的(p, q)场尽可能匹配(注意符号关系:p = -∂Z/∂x)。该问题可以利用离散快速傅里叶变换等方法高效求解。

结果与扩展

经典的从明暗恢复形状方法在满足其强假设(朗伯表面、单一点光源、已知反照率)的条件下,能够从单张图像恢复出粗糙的形状。然而,结果对光源位置敏感,且容易产生偏差。

现代的研究致力于放松这些强假设。例如,一些工作尝试从单张RGB图像同时估计深度、法线、反射率、着色和光照,这是一个更具挑战性但也更通用的“从明暗恢复形状”问题。

总结

在本节中,我们一起学习了“从明暗恢复形状”的基本原理。我们了解到,通过假设朗伯表面、单一点光源和正交投影,可以将复杂的渲染方程简化为图像强度与表面法线点积的直接关系。然而,由于从单个亮度值无法唯一确定法线,我们引入了*滑性约束和遮挡边界约束,构建了一个变分优化问题来求解法线图,并最终通过积分得到深度图。这项技术是理解如何利用光照线索推断三维形状的重要基础。接下来,我们将看到如何通过增加观测来更稳健地解决这个问题,即“光度立体视觉”。

031:从形状到体积融合 📦

在本节课中,我们将学习如何将来自多个视角的几何重建结果融合成一个完整、一致的三维场景模型。我们将重点介绍一种因其简洁高效而广泛使用的技术——体积融合

我们已经学习了许多从图像输入重建几何形状的技术。然而,这些重建大多只针对单个物体,或者仅生成单张深度图。在实际应用中,我们通常希望重建整个场景,即由多个物体构成的大规模场景。这就引出了一个关键问题:如何将这些独立的局部重建组合成一个完整、一致的三维场景模型。

传统三维重建流程概览

以下是传统三维重建流程的概览图,其输入是一组图像。

我们首先估计相机姿态,可以使用运动恢复结构或光束法*差等技术。根据估计的相机姿态和图像,我们可以利用双目/多目立体视觉、单目视觉、主动视觉或明暗恢复形状等技术来计算密集对应关系。这些计算可能产生的一个中间表示是每张参考图像的深度图。

深度图融合的任务,就是将所有深度图融合成一个一致的三维重建结果,如上图左侧所示。

理解体积融合:从显式到隐式表示

为了理解体积融合的工作原理,我们首先需要了解它所使用的表示方法。这种方法使用的不是显式表示,而是形状的隐式表示

显式表示 vs. 隐式表示

这里我们看到一个基于网格的表示,这是一个被离散化为一系列顶点和边的圆形。在三维中,这将是顶点和面的集合。这是一种显式表示,它通过存储顶点和面来直接描述几何形状。虽然它曾被用于融合,但并非理想的融合表示,并且很难用这种表示来改变拓扑结构。

我们将转而使用隐式表示。最简单的隐式表示是简单的参数形式。例如,我们可以将一个圆表示为某个抛物面的水*集。我们有一个函数 f(x, y) = x² + y² - r²。当我们将该函数设为零时,就得到了圆的方程。因此,我们通过这样一个函数的水*集隐式地定义了表面形状。

在接下来的课程中,我们将讨论使用神经网络表示这类函数的隐式模型。但这是*期的工作方向,我们首先关注过去20年中的经典方法,即对这种隐式空间的离散化

有符号距离函数

具体来说,我们将关注所谓的有符号距离函数。它测量空间中每个体素中心到最*表面的距离。我们以适合我们内存和计算能力的分辨率对空间进行离散化。然后,在每个体素中,我们存储一个值,该值被设置为到最*表面的距离。

例如,一个体素的值可能是2.5,表示其中心距离最*表面点2.5个单位。我们使用正负号来指示体素是在物体内部(正)还是外部(负)。在某些定义中,符号可能相反,但重要的是我们定义了有符号距离,从而知道内外。

因此,表面被表示为这个离散隐式表示的水*集,我们需要通过插值来实际找到表面。

隐式模型的优势

隐式模型的一个关键优势是它们能够表示任意拓扑结构,并允许拓扑变化。例如,通过改变相应体素的SDF值,可以轻松地关闭物体、移除物体或创建新物体,从而改变表面的连接数量(即拓扑)。相比之下,改变网格的拓扑结构要困难得多,因为需要重新连接顶点。

这里有一个不同拓扑的例子:一个有孔洞的拓扑和一个简单的拓扑。一个更新的工作视频很好地展示了这种隐式模型如何允许改变拓扑,例如在优化过程中从亏格0变为亏格1、2、3、4,增加越来越多的孔洞,这对该表示来说完全没有问题。

体积融合的三个步骤

了解了这种表示方法后,体积融合具体怎么做呢?典型的体积融合(假设以深度图为输入)包含三个步骤:

  1. 将深度图转换为离散有符号距离场表示。
  2. 执行体积融合。
  3. 从融合后的有符号距离场中提取网格。

因此,我们先将显式表示转换为隐式表示,在隐式空间中进行融合,然后再转换回显式表示。

步骤一:深度图到SDF的转换

不幸的是,问题并不像之前图示那么简单,因为我们通常不知道到表面的真实距离。我们通常只知道沿特定光线方向上的表面深度。因此,SDF融合方法通常假设:到表面的距离可以用沿光线的距离来*似。这是一个*似,在表面附*效果较好。

具体操作时,对于每条光线,我们考虑所有与之相交的体素,取体素中心并测量其沿光线到交点的距离,因为这是我们容易获取的信息。我们将这个距离作为有符号距离填入。例如,用负号表示体素在表面前方,正号表示在表面后方。

对于一个特定的视角,考虑该视角的所有光线(实际上每个像素对应一条光线),我们就可以填充这个离散的SDF表示。在实现中,我们通常会反向操作:将所有体素投影到图像中,查看它们落在哪个像素,并取该像素的深度值。

这样,对于红色相机和蓝色相机,我们分别得到两个离散的SDF表示。这就是深度图到SDF的转换。

步骤二:执行体积融合

现在让我们看看如何进行实际的体积融合。为了在一个更简单的例子中说明,我们考虑所有相机都朝同一方向的正交投影情况(这只是为了简化说明,该算法同样适用于视角不同的透视相机)。

在将深度图转换为离散SDF表示后,我们实际上要做的是计算这些离散SDF场的*均值,因为这会给我们一个*均后的隐式表面。通过对SDF值进行*均,我们随后提取的隐式表面也将被*均。

让我们看一个例子。考虑一些光线,有些区域同时被红蓝相机看到,有些只被一个相机看到。我们填充红色SDF图和蓝色SDF图,每个体素根据其与对应相机看到的表面的相对位置获得带符号的距离值。

体积融合所做的就是简单地*均这些值。例如,在重叠区域,我们对来自两个相机的SDF值进行加权*均。最终,表面的零水*集(即表面位置)将位于两个原始表面的中间。这样,我们就有效地*均了隐式表面。

融合的数学表达

数学上,这可以表示为一个加权*均。融合后的距离 D(x) 在体素 x 处定义为:

D(x) = Σᵢ [ wᵢ(x) * dᵢ(x) ] / Σᵢ wᵢ(x)

其中,i 遍历所有相机/图像,dᵢ(x) 是来自相机 i 的SDF值,wᵢ(x) 是相应的权重。W(x) = Σᵢ wᵢ(x) 是融合后的总权重。

这种简单的加权*均可以方便地表示为增量更新规则,其优点是计算开销恒定,允许我们一次添加一张图像,将其融合到现有重建中,支持融合成千上万张深度图。

关于权重

为什么需要权重?主要有两个原因:

  1. 空间衰减:在表面前方(空区域),我们确信距离值正确,权重可以较高。在表面后方,我们需要传播内部信息以保持零水*集,但权重应衰减,以避免对薄壁等结构产生错误影响。
  2. 置信度:对于从远距离、倾斜角度或在物体边界处获得的可能噪声较大的观测,可以赋予较低的全局权重。

这种加权*均之所以是个好主意,是因为它实际上是一个加权最小二乘问题的解。我们寻找一个 D,使其在加权意义上最接*所有观测值 dᵢ

步骤三:从SDF提取网格

现在,我们有了融合后的离散有符号距离场,如何从中提取网格呢?答案是使用著名的行进立方体算法。该算法由Lorensen和Cline于1987年提出,广泛应用于计算机视觉和图形学。

其思想是遍历所有网格单元(可以独立进行),并在检测到符号变化时插入三角形面片。分为两步:

  1. 估计拓扑:通过查看立方体8个顶点处的SDF值的正负号,确定表面穿过该立方体的方式。在3D中,有256种可能的拓扑,但由于旋转对称性,可归纳为15种基本类型。
  2. 预测顶点位置:已知拓扑后,需要确定三角形顶点的精确位置。假设SDF值在边上线性变化,顶点应位于SDF值零交叉的位置。例如,如果一条边两端的SDF值分别为 ab,且符号相反,则零交叉点沿边的位置 t 可通过线性插值求得:t = |a| / (|a| + |b|)

对所有网格单元执行此操作,即可得到最终的三角形网格。

体积融合的应用实例

KinectFusion

最著名的应用之一是KinectFusion,由Newcombe等人于2011年提出。它是一个实时姿态估计和体积融合系统,使用Kinect等深度传感器作为输入。它使用迭代最*点算法的变种进行实时姿态估计,并利用我们前面介绍的SDF融合技术更新重建。用户可以手持传感器移动,系统实时融合深度帧,逐步构建出完整、高保真的场景三维模型。

DynamicFusion

KinectFusion的扩展工作是DynamicFusion,由同一团队在2015年提出,解决了场景非静态的问题。它通过估计一个将当前帧变形到规范帧的形变场,能够重建非刚性运动的场景,例如运动的人体。

结合深度学习的融合

体积融合的一个问题是它假设输入噪声较低,但这并不总是成立。将深度学习集成到估计过程中是有益的。例如,ONetFusion 使用3D卷积网络和高效的自适应数据结构,以融合过程中的特征作为输入,输出一个去噪且补全的重建结果。与传统的变分融合方法相比,它能更好地在去除噪声的同时保留细节。

端到端可微分重建

另一研究方向是尝试端到端地解决学习问题。传统学习方法是先在离散体素空间学习隐式表示,然后通过行进立方体算法提取网格,监督信号作用于隐式表示。现在,研究者开发了可微分的行进立方体算法变体,它能够将拓扑选择和顶点位置预测以概率方式结合,使得梯度可以端到端地反向传播到网络参数。这样,就可以直接使用点云等作为监督信号来训练整个重建系统,而无需依赖隐式表示上的辅助损失函数。

总结

本节课中,我们一起学习了体积融合技术。我们从理解隐式表示(特别是有符号距离函数)的优势开始,详细探讨了体积融合的三个核心步骤:将深度图转换为SDF、在SDF空间进行加权*均融合、以及使用行进立方体算法从融合后的SDF中提取网格。我们还了解了该技术在KinectFusion、DynamicFusion等实时重建系统中的应用,以及如何结合深度学习来提升融合的鲁棒性和质量。体积融合因其原理简单、易于实现和扩展,成为大规模场景三维重建中的一项基础且重要的技术。

032:基于坐标的网络 - 隐式神经表示

在本节课中,我们将要学习一种新颖的3D表示方法——隐式神经表示。我们将探讨如何利用神经网络隐式地表示形状、外观和运动,并了解其相对于传统显式表示方法的优势。

单元 1:形状、外观与运动的基本隐式神经表示

上一节我们介绍了课程概述,本节中我们来看看隐式神经表示的基本概念。

这是之前展示过的一张幻灯片,它描述了一个传统的3D重建流程。输入是一组图像,我们推断相机姿态,例如使用光束法*差。然后我们建立密集对应关系,通过立体视觉或多视图立体视觉生成深度图。最后,我们将这些深度图融合成一个更连贯的全局3D场景重建。

这个流程虽然可行,但除了部分环节可能用到学习技术,我们并未广泛使用学习,特别是没有回答一个核心问题:是否可能直接从一张或多张图像,甚至从一张图像出发,获得一个物体的完整3D重建?这正是我们想探讨的:能否从数据中学习3D重建?

这是一个高度依赖机器学习或数据驱动的问题。学习需要数据,幸运的是,在过去十年左右,许多3D数据集已公开可用。例如,通过主动光照扫描系统等技术获取的数据集,或者由艺术家设计的CAD模型集合,如ShapeNet数据集。*期还有像Matterport这样的数据集,尝试重建整个建筑。

如果我们想构建一个模型,学习从一张或多张输入图像直接预测形状,必须回答一个问题:什么是好的输出表示?输入表示很明确,最简单的情况就是一张二维图像,可以用标准的二维卷积网络处理。但解码器应该是什么?特别是,什么是好的输出表示?

以下是人们考虑过的几种输出表示:

  • 体素表示:这是像素表示在三维中最简单的扩展。体素是像素的三维等价物,它将连续的3D世界离散化为规则的3D网格。虽然易于用神经网络处理,但其主要问题是内存消耗巨大,限制了输出分辨率,且引入了“曼哈顿世界”偏差。
  • 点集表示:点集将表面离散化为3D点。其难点在于不建模连通性或拓扑结构,需要后处理算法提取表面,且通常能表示的点数有限。
  • 网格表示:网格将3D空间离散化为顶点和面。问题在于,由于其复杂的结构,神经网络很难预测出不自交的表面。

在我们的CVPR 2019工作中,我们尝试摆脱这些离散化表示,转而隐式地表示表面。其优势在于可以表示任意拓扑结构,理论上支持任意分辨率,且内存占用低,不受限于任何特定的类别模板。

核心思想是不显式地表示3D形状,而是将表面视为一个非线性分类器的决策边界。例如,在二维中,红色点表示物体内部(占据值1),蓝色点表示外部(占据值0)。训练一个分类模型,使其最优地分离内部和外部点,这个决策边界就是我们认为的表面。因此,表面由该模型的参数隐式表示,需要通过后处理步骤提取。

具体来说,我们训练一个分类器,反复从体积中采样点(我们知道它们是在内部还是外部),并调整神经网络的权重,使决策边界越来越接*理想的表面边界。这需要完整的3D监督,即需要能够查询任何3D点是在形状内部还是外部。

重复一下,我们不显式表示3D形状,而是将物体表面视为非线性分类器的决策边界。我们称这个分类器为占据网络,因为它是一个带有参数θ的神经网络。它将一个3D位置(即点的坐标)加上某个条件(例如输入图像或点云的编码)映射到一个介于0和1之间的占据概率。如果网络预测1,则该点很可能在物体内部;如果预测0,则很可能在外部。

一些说明:函数f_θ建模了一个连续的占据场。也可以建模有符号距离函数,这在之前的讲座中很有用,但本讲座中我们坚持使用更简单的占据概率模型。

为了实现这个模型,我们需要定义神经网络架构f_θ。我们使用一个非常简单的多层感知机,它是一个由五个块组成的残差网络。我们有一个编码器(例如2D卷积网络)来产生一个固定长度的条件向量。这个条件在多个位置被注入到残差网络中。网络的输入是一批3D点,输出是每个点的占据概率。

我们如何训练这个模型?这是一个简单的分类任务,因此可以使用标准的二元交叉熵损失进行训练。我们还可以构建一个变分占据编码器,这本质上是将变分自编码器模型应用于隐式形状表示的思想。

由于这是一个隐式模型,我们无法直接得到网格。因此,我们必须从这个隐式表示中提取网格。我们使用一种称为多分辨率等值面提取的技术。它通过查询占据网络来增量地构建一个八叉树。我们从粗网格开始,查询网格点,找到跨越表面的单元格,然后细分这些单元格并重复查询,直到达到所需的粒度。最后,我们运行移动立方体算法来提取三角形网格。整个过程大约需要一到三秒。

以下是一些结果:输入是图像,右边是体素、点集、网格生成网络等基线方法的结果,以及我们方法的输出。可以看到,隐式表示能够轻松处理复杂拓扑并产生*滑表面。这同样适用于点云形状重建、体素超分辨率等任务。我们还展示了生成模型的潜在空间插值结果。

单元 2:从形状到外观

上一节我们介绍了如何用隐式网络表示形状,本节中我们来看看如何将其扩展到表示外观。

将隐式模型思想扩展到颜色是相当直接的。我们在2020年3DV上发表的工作《学习隐式表面光场》中,尝试通过不仅以输入图像为条件,还以某些3D几何形状为条件,来建模视图相关的外观。我们想训练这个模型,使得之后我们不仅可以改变视角,还可以操控光照。

我们建模一个函数,它将3D点位置、观察方向V和光源位置L映射到一个RGB颜色值。这被称为表面光场。模型概述如下:图像编码器与之前相同,将输入图像编码为潜在向量c。输入形状通过几何编码器编码为全局形状代码s。然后,我们取物体表面的任意点,首先查询一个外观场以获得特征向量,然后这个光照模型(同时以光照设置和观察方向为条件)产生该3D点渲染到图像中的像素颜色。我们最小化预测图像与真实图像之间的重建损失。该模型在通过基于物理的光传输渲染的椅子数据集上进行训练。

以下是一些结果:使用真实几何作为输入时,我们的结果比2D基线方法更一致,能够建模高光和阴影。使用推断几何时,所有输出仅从单个2D RGB图像生成。然而,该模型仅在椅子上训练,因此无法预测椅子以外的物体。

单元 3:从外观到运动

上一节我们探讨了外观表示,本节中我们来看看如何表示运动。

表示3D运动的一种简单方法是将占据网络的思想扩展到4D。但这很困难,因为维度灾难,且4D数据较少。因此,我们改为仅使用3D占据网络表示特定时间点的形状,然后通过一个时空连续的矢量场来表示运动。这仍然是一个需要预测的4D函数,但相比随时间演变的形状,它是一个连续得多的对象,因此模型更容易学习。

位置S与速度V之间的关系由一个简单的常微分方程给出。由于ODE是可微的,我们可以将其用于模型中并反向传播梯度。模型尝试给出离散时间点的真实形状,取任意点,通过由速度场(其本身以输入为条件)隐含的ODE将其扭曲到时间t=0的位置,然后让占据网络正确预测该点的类别标签。整个过程是端到端可学习的,并且我们不需要任何通常此类任务所需的对应关系,因为对应关系由模型隐式建立。

以下是一些输入和输出示例,展示了点云补全任务的结果。与朴素的4D占据网络方法相比,这种“占据流”模型表达能力更强,受维度灾难的影响更小。

单元 4:从物体到场景

我们讨论了表示形状、外观和运动,但所有这些结果都是在相对小尺度的场景(特别是单个物体)上取得的。我们想知道,是否也能使用这种输出表示来预测更大尺度的场景,例如整个房间甚至整个建筑。

到目前为止,我们所见的隐式神经表示有两个重要的局限性。第一个局限是,我们预测的是一个全局潜在代码作为输入条件。对于一个128维的向量来说,要表示整个场景的所有可能性非常困难,通常会导致几何过于*滑。第二个局限是,这种全连接网络架构本质上无法利用*移等变性,而我们知道这对于建模图像或3D场景至关重要。

如果我们将朴素的隐式占据网络应用于比单个物体更复杂的场景,结果并不理想。模型只能正确预测地面等常见元素,而无法正确预测任何物体。

因此,我们在ECCV 2020上发表的工作《卷积占据网络》中,尝试将隐式建模和卷积网络的优点结合起来,以弥补上述两个局限。我们考虑的任务是基于点云的形状补全。

具体做法是:首先,我们使用点编码器对3D点进行局部编码。我们在一个离散结构(如地*面上的2D网格)上计算局部特征。然后,我们使用一个2D卷积网络在这个“图像”上聚合特征,从而利用*移等变性。要查询某个3D点的占据状态时,我们通过双线性插值获取该点对应的特征,并将插值后的特征和点坐标输入到一个更浅的读出MLP中,以预测内部/外部类别。我们也可以将其扩展到3D体素网格,使用三线性插值。

与朴素占据网络相比,这种方法带来了更高的精度和更快的收敛速度。更重要的是,它允许表示场景。即使在合成房间上训练,也能应用于真实扫描数据。最后,我们可以将此模型扩展为全卷积模型,并应用于像Matterport这样包含多个房间的整个建筑的大型场景。由于模型是全卷积的,我们可以以滑动窗口的方式分块处理,从而生成大规模的重建结果。


本节课中我们一起学习了隐式神经表示的核心思想。我们从如何用神经网络隐式表示3D形状开始,了解了占据网络的基本原理。接着,我们探讨了如何将此思想扩展到建模视图相关的外观,即表面光场。然后,我们学习了如何通过结合常微分方程来表示物体的连续运动。最后,我们指出了朴素隐式表示的局限性,并介绍了卷积占据网络如何通过结合局部特征提取和卷积结构,成功地将隐式表示应用于大规模场景的重建。这种表示方法因其灵活性、紧凑性和高质量的输出,已成为计算机视觉领域的一个重要研究方向。

035:基于坐标的网络 - 生成式辐射场 🎨

在本节课中,我们将学习如何将上一单元介绍的神经辐射场(NeRF)表示,构建成一个通用的生成式模型。我们将探讨如何仅使用特定物体类别的2D图像集合,来构建一个能够逼真渲染出新图像的生成式3D模型。这与之前优化特定场景的NeRF不同,这里我们假设不知道相机姿态,仅有一组图像。

生成对抗网络回顾

在开始之前,让我们快速回顾一下生成对抗网络(GANs)。生成式模型是指任何从数据分布 P_data 中学习一个概率分布 P_model 来表示该数据分布的模型。

在某些情况下,模型会显式地估计 P_model,从而允许评估样本 x 的*似似然 P_model(x)。但在许多情况下,这是不可行的,模型只能从 P_model 中生成样本。GANs 就是这个家族(称为隐式模型家族)的突出例子。这里的“隐式”意味着似然没有被显式表示,而是隐式地存在。

GANs 提供了一个无需显式似然的模型训练框架。其典型结构如下:

  • 一个从某个噪声分布中采样的潜在编码 z
  • 一个生成器网络 G,接收 z 并生成数据(例如2D图像)。
  • 一个判别器网络 D,接收图像并尝试分类它看到的是来自真实数据分布 P_data 的真实图像 x,还是来自生成器分布 P_model 的生成图像 G(z)

我们使用一个两人极小极大博弈范式来训练这个模型,其价值函数定义如下:

min_G max_D V(D, G) = E_{x~p_data(x)}[log D(x)] + E_{z~p_z(z)}[log(1 - D(G(z)))]

判别器 D 试图最大化其正确分类的能力,而生成器 G 试图最小化判别器识破其生成图像的能力。理想情况下,当生成器变得足够好时,判别器将无法区分,对所有样本都赋予0.5的概率。

理论上,在非常强的假设下(例如每次迭代都能达到最优判别器 D*,且模型有足够容量),这个极小极大博弈能够恢复真实数据分布。但在实践中,我们使用交替优化:先对 D 进行几步优化,再对 G 进行一步优化,通过足够小的学习率来保持 D 接*其最优解。

将GAN思想应用于辐射场

现在,让我们将这个思想应用到辐射场上。我们希望为辐射场构建一个生成式模型。具体流程如下:

  1. 采样一个潜在编码 z,它捕获了3D点位置、观察方向、物体形状和外观信息,以及相机姿态。
  2. 对于给定的3D点 x 和观察方向 d,使用辐射场预测颜色 c 和密度 σ
  3. 使用体渲染将场景渲染成图像。
  4. 目标是让一个应用于该图像的2D判别器无法区分渲染图像和数据集中的真实图像。

整个模型仅使用2D图像进行训练。这就是生成式辐射场(Generative Radiance Fields,简称GRAF)背后的核心思想。一个主要挑战是,由于我们只有图像作为观测,无法直接在3D空间应用判别器,必须使用体渲染,而这个过程很慢。GRAF论文的一个贡献就是如何使这个过程变得可行。

逐步构建GRAF模型

接下来,我们一步步构建这个模型。首先,我们有一个基础的辐射场,它接收3D点 x 和观察方向 d(经过位置编码 γ),并映射到颜色 c 和密度 σ。然后,对于一条射线,我们沿射线采样多个点,为每个点计算颜色和密度,最后应用体渲染(用 π 表示)来合成像素颜色。这就是NeRF的工作方式。

GRAF在此基础上增加了两个额外的潜在编码:

  • 形状潜在编码 z_s
  • 外观潜在编码 z_a

它们也从标准正态分布中采样,负责对渲染图像的物体形状和外观进行条件建模。

由于渲染整张图像计算量过大,我们改为只渲染一小块图像块(例如32x32像素)。我们随机采样一个2D图像网格的位置和步长,只对这些像素位置执行上述渲染过程。这样,我们得到了一个预测的图像块。

以下是生成图像块的关键步骤:

  1. 随机采样相机姿态、形状码 z_s、外观码 z_a 和图像块采样模式 ψ
  2. 对于采样模式确定的每个像素位置,执行NeRF式的体渲染,生成像素颜色。
  3. 将所有渲染的像素组合成图像块 I_hat

然后,我们可以应用一个标准的2D卷积判别器。这个判别器非常快,它需要区分生成的图像块和从真实图像中按相同采样模式 ψ 随机采样的真实图像块 I

这样,我们就将问题简化了:无需渲染整张图像,只需稀疏采样图像块并进行比较,这大大降低了计算和内存需求,使得在生成对抗网络框架下训练成为可能。图中蓝色部分是生成器(GAN的生成器),红色部分是判别器。判别器是一个类似标准GAN的2D卷积网络,而生成器则生成一个3D结构,并将其渲染成图像块供判别器判断。

条件辐射场网络架构

条件辐射场网络架构的设计确保了形状和外观编码的解耦。具体来说:

  • 体积密度 σ 仅依赖于3D点 x 和形状码 z_s,而不依赖于观察方向 d 和外观码 z_a。这迫使网络首先用 z_s 来建模形状。
  • 预测的颜色 c 则额外依赖于观察方向 d 和外观码 z_a。由于形状信息已在前层处理,颜色预测头具有较小的容量,用于根据这些条件调整颜色,从而能够建模依赖于视角的外观(例如镜面反射材料)。

结果展示与总结

GRAF方法能够从无姿态的2D图像集合中学习,生成高分辨率且3D一致的图像。它还能通过独立操纵形状码 z_s 和外观码 z_a 来分别控制生成物体的形状和外观。

最后,值得一提的是GIRAFFE工作,它扩展了GRAF的思想,用于组合式场景的生成,能够从图像集合中解耦出场景中的不同物体,并因此获得了CVPR 2021最佳论文奖。

坐标网络总结

本节课我们一起学习了基于坐标的网络。我们来总结一下:

  • 坐标网络 是表示形状、外观、材料和运动的一种有效隐式表示。
  • 优点:它们不需要任何离散化,能够建模任意拓扑结构,并且可以通过可微分渲染从图像中学习。应用领域包括3D重建、运动估计、视图合成,甚至在机器人学和自动驾驶中也显示出应用潜力。
  • 挑战:由于是隐式表示,提取几何等属性需要后处理步骤;扩展到更高维度会面临维度灾难;全连接架构和全局条件化可能导致结果过于*滑。
  • 未来方向:包括使用局部特征(如卷积或基于点的特征)、更好的输入编码(如NeRF中的位置编码),以及新的网络架构(如SIREN)。

基于坐标的网络为计算机视觉中的3D内容生成和理解提供了强大而灵活的框架。


本节课中,我们一起学习了如何将神经辐射场扩展为生成式模型(GRAF),它能够仅从无姿态的2D图像中学习生成3D一致且高分辨率的图像。我们还回顾了GAN的基本原理,并总结了基于坐标的网络的总体优势与挑战。

036:图像分类 📸

在本节课中,我们将要学习计算机视觉中的一个核心子领域——识别,并重点探讨其基础任务:图像分类。在过去的课程中,我们主要关注了计算机视觉的几何方面。本节我们将转向一个数据驱动且因深度学习而取得巨大进展的领域。

本讲座分为三个单元。在第一单元,我们将介绍计算机视觉的基本宏伟目标之一:图像分类。在第二单元,我们将探讨一个称为语义分割的问题。最后,我们将讨论物体识别、物体检测与分割。

在开始之前,我们先简要了解一下这些问题及其相互之间的区别。

识别任务概览

以下是四种主要的识别任务及其区别。

  • 图像分类:给定一张图像,目标是为整张图像分配一个单一的类别标签(如图像类别)。例如,为一张图像分配“街景”标签。
  • 语义分割:目标是为图像中的每一个像素分配一个语义类别标签(如“汽车”、“天空”、“树木”)。它不区分同一类别的不同个体。
  • 物体检测:目标是通过二维边界框定位物体,并对其进行分类。它只针对可数的物体类别(如汽车、行人),而不处理“天空”这类“东西”类别。
  • 语义实例分割:目标是为属于物体的每个像素同时分配一个语义标签和一个实例标签。这使得即使相邻的同类物体(如两辆汽车)也能被区分开。

以上是我们要探讨的四个问题。现在,让我们从图像分类开始。

图像分类问题

问题定义如下:输入是一张图像,我们希望为该图像分配一个单一的类别标签或图像类别,例如“街景”。

为什么这是一个有趣的问题?首先,它本身可以是一个有用的任务,例如识别手写数字或基于关键词搜索图像。其次,这个规范简单的问题(输入是图像,输出是离散的类别标签)可以使用标准的损失函数(如交叉熵)来学习模型。因此,图像分类长期以来一直是计算机视觉中一个困难且标准化的基准任务,因为它需要对图像内容进行深入理解和推理。

此外,图像分类也被证明是一个有用的高级代理任务,用于学习能够很好地迁移到新任务和新领域的表征。通过在大规模标注数据集上预训练一个分类模型,我们可以获得强大的视觉表征,然后在数据量较小的目标任务(如分割、检测)上进行微调,从而取得优异性能。

那么,我们如何对图像进行分类或归类呢?早期的尝试试图通过手工设计规则来解决这个问题,例如基于边缘和角点关系来推断图像类别。但这些尝试都失败了,因为物体的形状和外观过于复杂,难以手动描述。这正是机器学习和标注数据集在解决此问题上发挥根本作用的原因。

经典数据集

让我们看一些在图像分类发展史上具有里程碑意义的数据集。

  • MNIST:一个在机器学习社区非常著名的数据集,包含手写数字。它有60,000个训练样本和10,000个测试样本,图像分辨率较低。
  • Caltech 101:第一个主要的物体识别数据集,包含101个物体类别。图像中的物体通常居中、姿态规范、背景简单,按当今标准来看相对简单。
  • ImageNet:一个推动深度学习兴起的关键数据集。它包含约22,000个类别,用于年度挑战赛的通常有1,000类。图像中物体姿态复杂、类别区分难度高,拥有数百万张图像。它至今仍是预训练通用视觉表征的主要数据集之一。

图像分类的挑战

图像分类之所以不简单,主要面临以下挑战:

  • 类别数量庞大:估计有10,000到30,000个主要图像类别,区分相似类别(如不同犬种、鸟类)很困难。
  • 类内差异:同一类别的物体(如椅子)在形状、颜色、外观上可能差异巨大。
  • 视角变化:从不同视角观察同一物体,像素值会发生剧烈变化。
  • 光照变化:光照条件不同会彻底改变图像的外观和强度。
  • 遮挡:物体可能被部分遮挡。
  • 背景杂乱:物体可能存在于复杂背景中。
  • 形变:某些物体类别(如猫)本身具有很大的形变。

从简单模型到深度学习

我们首先看一个简单的模型:最*邻分类器。给定查询图像,它在整个训练集中寻找像素距离(如L1距离)最*的图像,并返回其类别标签。

最*邻分类公式
预测类别 = argmin_{i' ∈ 训练集} D(I, I'),其中 D 是图像间距离。

然而,这种方法效果不佳。首先,在推理时进行最*邻搜索速度很慢。其次,像素空间中的距离信息量不足,无法捕捉语义相似性。一个思想实验可以说明问题:将棋盘图像水**移一个格子,两幅图像的像素差异会最大,但它们的类别完全相同。

接下来,社区采用了更成功的词袋模型。其核心思想是通过比较局部特征的直方图来获得空间不变性,从而消除特征位置的依赖性。具体步骤是:1) 提取图像局部特征(如SIFT描述子);2) 对所有训练图像的特征进行聚类(如K-means),形成视觉词汇表;3) 将每张图像的特征量化到最*的视觉词,生成视觉词频直方图;4) 基于这些直方图训练分类器(如SVM)。

词袋模型比原始像素方法好得多,但性能最终会饱和,因为其中包含太多手工设计的组件(如SIFT特征、聚类方法),而学习部分太少。

最终的解决方案是深度学习:使用卷积神经网络(CNN)从图像像素端到端地学习整个模型。所有模块(绿色部分)的参数都是可训练的。2012年,AlexNet在ImageNet挑战赛上大幅超越传统方法,标志着深度学习在计算机视觉领域的突破。此后,性能持续提升,并超越了人类水*。

卷积神经网络(CNN)回顾

CNN是解决图像分类任务的主要模型。典型的CNN(如VGG网络)包含三种类型的层:

  1. 卷积层:使用权重共享的卷积核在输入上滑动计算,大幅减少参数量,并引入*移等变性(输入*移导致输出相应*移)。
  2. 下采样层(如池化层):降低特征图的空间分辨率(如使用2x2最大池化,步长为2),同时增加感受野。池化通常逐通道进行。
  3. 全连接层:在空间维度被压缩后(例如通过全局*均池化或展*操作),使用全连接层进行最终分类。

一个关键特性是,通过堆叠卷积和池化层,网络最终能够实现*移不变性,这对于分类任务至关重要。

输出层与损失函数

对于图像分类,我们使用Softmax输出层交叉熵损失函数。这是一个自然的选择,因为我们的目标是预测一个类别分布。

我们假设标签 y 服从一个由网络参数化的分类分布。网络输出一个“得分”向量 s,通过Softmax函数将其转换为概率分布:
P(y=c | x, W) = softmax(s)_c = exp(s_c) / ∑_k exp(s_k)

然后,我们通过最大似然估计来训练网络,这等价于最小化交叉熵损失
L = - ∑_i ∑_c y_{i,c} log( P(model predicts c | x_i, W) )
其中 y_{i,c} 是第 i 个样本的真实标签(one-hot编码)。

Softmax函数鼓励正确类别的得分提高,同时抑制其他类别的得分。它对输入之间的差异敏感,但对所有输入加一个常数不敏感,这一性质可用于实现数值稳定的计算。

经典网络架构

最后,我们简要回顾一些成功的CNN架构:

  • LeNet-5 (1998):早期的成功CNN,结构较浅,主要用于MNIST等小规模问题。
  • AlexNet (2012):深度学习的引爆点,证明了CNN在复杂图像分类任务上的强大能力。
  • VGGNet (2014):表明使用堆叠的3x3小卷积核可以替代大卷积核,在获得相同感受野的同时减少参数量,但全连接层参数仍很多。
  • Inception / GoogLeNet (2015):引入了并行多尺度卷积的“Inception模块”和辅助分类器,以改善梯度流动并训练更深的网络。
  • ResNet (2016):通过引入残差连接,让网络层学习残差映射,使得训练极深的网络(如152层)成为可能,成为当前许多领域的主流架构。

这些架构的演进在精度、计算复杂度和参数量之间取得了更好的*衡。

总结 🎯

本节课我们一起学习了计算机视觉中识别领域的基础任务——图像分类。我们了解了图像分类的定义、意义及其作为预训练代理任务的价值。回顾了从简单最*邻分类器、词袋模型到深度学习解决方案的发展历程。我们深入探讨了卷积神经网络的核心组件(卷积、池化、全连接层)及其特性,并解释了Softmax输出层与交叉熵损失函数的工作原理。最后,我们简要回顾了推动图像分类性能不断提升的几个关键神经网络架构。理解图像分类是进入更复杂视觉识别任务(如分割、检测)的重要基础。

038:目标检测与分割 🎯

在本节课中,我们将要学习计算机视觉中的核心任务之一:目标检测,以及与之相关的实例分割等任务。我们将从目标检测的基本定义和评估方法开始,逐步深入到经典的滑动窗口检测、基于深度学习的现代方法,并最终了解如何扩展这些方法来处理更复杂的输出,如像素级分割和3D检测。

目标检测概述

目标检测的目标是定位并分类图像中的所有物体。我们不仅需要知道物体是什么(分类),还需要知道它在哪里(定位)。定位通常通过一个紧密贴合物体的二维边界框来表示,同时为每个边界框分配一个类别标签。例如,在一张街景图中,我们需要检测出汽车(类别5)和电线杆(类别7),并为它们各自绘制边界框。

目标检测有广泛的应用,例如自动驾驶中的导航和避障、机器人抓取等。一个典型的例子是Mobileye公司的驾驶辅助系统,它通过摄像头检测前方车辆并估算距离,从而在车辆过于接*时发出警告。

问题定义与评估指标

输入与输出

  • 输入:通常是一张RGB图像。对于3D目标检测,输入也可以是激光雷达点云。
  • 输出:一组带有类别标签和置信度的2D或3D边界框。置信度对于后续处理至关重要,例如,低置信度的预测可能被忽略,而高置信度的预测则需要认真对待。

无论是2D还是3D检测,图像中的物体数量和大小都是未知的,这使得目标检测成为一个复杂的结构化预测问题。

交并比

在讨论算法之前,我们需要一个衡量检测好坏的指标。与语义分割类似,我们使用交并比 来衡量预测边界框与真实标注框之间的重叠程度。

公式
IoU = (预测框 ∩ 真实框) / (预测框 ∪ 真实框)

如果预测框与真实框完全重合,IoU为1。在实践中,IoU达到0.7通常被认为是很好的检测,而低于0.5则被认为是较差的检测。因此,在多数评估场景中,通常将IoU阈值设为0.5。

多目标评估:*均精度

对于包含多个物体的图像,我们需要一个更全面的评估指标。以下是评估流程:

首先,目标检测器会为每个预测输出一个置信度。通过改变置信度阈值,我们可以得到不同数量的预测结果(高置信度的预测更少,但更可能正确)。

接着,我们将预测框与真实标注框进行二分图匹配(例如使用匈牙利算法),为每个真实框分配一个最匹配的预测框,形成一一对应关系。

匹配完成后,我们可以计算以下数量:

  • 真正例:正确检测到的物体数量(IoU > 0.5)。
  • 假负例:未被检测到的真实物体数量。
  • 假正例:错误的检测数量(包括与任何真实框IoU都小于0.5的预测,以及为同一个真实物体产生的多个冗余预测)。

基于这些数量,我们计算两个关键指标:

  • 精确率:衡量检测结果的准确性。精确率 = 真正例 / (真正例 + 假正例)
  • 召回率:衡量检测出所有真实物体的能力。召回率 = 真正例 / (真正例 + 假负例)

理想的检测器需要同时具备高精确率和高召回率。通过不断调整置信度阈值,我们可以得到一条精确率-召回率曲线

*均精度 就是这条曲线下的面积。它通过在不同召回率水*下取对应的最高精确率,然后计算*均值得到。AP值越高,说明检测器的综合性能越好。

经典目标检测方法

上一节我们介绍了如何评估目标检测器,本节中我们来看看早期的一些经典检测算法。

滑动窗口检测

滑动窗口检测是最直观的方法之一。其核心思想是使用一个固定大小的窗口,以一定的步长遍历整张图像。

以下是其基本步骤:

  1. 在图像的每个位置和多种尺度上截取图像块。
  2. 对每个图像块提取特征。
  3. 使用一个分类器(如SVM)判断该图像块是否包含特定目标(如行人、汽车)。
  4. 由于目标附*可能会产生多个高置信度的检测,最后需要应用非极大值抑制 来去除冗余的、置信度较低的检测框,只保留最好的一个。

这种方法计算量巨大,因为需要在大量位置和尺度上运行分类器。

HOG特征与DPM模型

为了改进滑动窗口方法,研究者们设计了更好的特征。方向梯度直方图 特征在2005年被提出,并取得了巨大成功。

HOG特征的计算过程如下:

  1. 计算图像的梯度幅值和方向。
  2. 将图像划分为小的单元格。
  3. 为每个单元格计算一个梯度方向的直方图(用梯度幅值加权)。
  4. 将所有单元格的直方图连接成一个长特征向量。

HOG特征对小的*移、旋转和形变具有一定的鲁棒性。然而,对于大的形变(如非刚性物体的不同姿态),HOG特征效果有限。

为了解决非刚性形变问题,可变形部件模型 被提出。DPM将物体建模为多个部件的组合,并用弹簧模型描述部件之间的空间关系,允许部件在一定范围内移动。虽然DPM在深度学习时代之前是性能最好的模型之一,但其基于图形模型的推理过程非常缓慢。

深度学习时代的目标检测

传统方法在特征设计和计算效率上存在瓶颈。深度学习通过数据驱动的方式学习特征,彻底改变了目标检测领域。自2015年以来,基于深度学习的方法在精度上实现了飞跃。

两阶段检测器:R-CNN系列

两阶段检测器首先生成候选区域,然后对每个区域进行分类和精修。

R-CNN 是这一系列的开创性工作。其流程如下:

  1. 区域提议:使用传统算法(如Selective Search)从图像中提取约2000个可能包含物体的候选框。
  2. 特征提取:将每个候选框裁剪并缩放到固定大小,然后分别输入一个卷积神经网络提取特征。
  3. 分类与回归:使用提取的特征,一方面通过一个分类器(如SVM)预测类别,另一方面通过一个回归器微调边界框的位置。

R-CNN的主要问题是效率低下,因为它需要为每个候选区域独立运行一次完整的CNN前向传播,计算没有共享。

Fast R-CNN 对此进行了改进。它首先使用一个全卷积网络处理整张图像,生成一个共享的特征图。然后,对于每个候选区域,通过一个感兴趣区域池化 操作,从特征图中提取固定大小的特征。最后,这些特征被送入一个轻量级的全连接网络进行分类和边界框回归。这种方法实现了特征共享,大大加快了速度。

Faster R-CNN 的革新在于用神经网络替代了传统的区域提议算法。它在共享的特征图上运行一个区域提议网络。RPN是一个小型网络,它在特征图上滑动,为每个位置预设多个不同尺度和长宽比的锚框,并预测每个锚框包含物体的概率以及需要调整的偏移量。这样,区域提议、特征提取、分类和回归全部整合进一个可端到端训练的神经网络中。

单阶段检测器

除了两阶段检测器,还有更快的单阶段检测器,如YOLO和SSD。它们移除了区域提议阶段,直接在单个网络中从特征图预测边界框和类别。虽然速度更快,但其精度通常略低于精心设计的两阶段检测器。

提升检测性能的技术

现代检测器还集成了多种技术来提升性能:

特征金字塔网络 解决了多尺度检测问题。传统的CNN特征图随着网络加深,分辨率降低,小物体的信息会丢失。FPN通过自顶向下和横向连接的结构,构建了一个具有强语义信息的多尺度特征金字塔,使得模型能在不同尺度的特征图上进行预测,显著提升了对小物体的检测能力。

Mask R-CNN 是在Faster R-CNN基础上扩展的实例分割模型。它在原有的分类和边界框回归分支之外,增加了一个掩码头分支。这个分支为每个检测到的物体预测一个像素级的二值掩码,精确勾勒出物体的轮廓。此外,Mask R-CNN将RoI Pooling改进为RoI Align,使用双线性插值代替取整操作,使特征对齐更精确,从而提升了分割边界的质量。

超越2D框:更丰富的输出

基于上述通用框架,我们可以预测比边界框更丰富的输出。

DensePose 的目标是预测人体图像中每个像素在3D人体模型表面上的对应坐标。通过训练一个网络来预测这些坐标,我们可以从单张图像中恢复出详细的人体姿态和表面信息。

3D目标检测 将框架扩展到3D领域。例如,PointRCNN直接处理点云数据,其结构与Faster R-CNN类似,但输出是3D空间中的边界框。

Mesh预测 则更进一步,旨在为2D检测框内的物体预测其完整的3D网格模型。

总结与工具

本节课中我们一起学习了目标检测与分割的核心内容。我们从目标检测的基本定义和评估指标出发,回顾了经典的滑动窗口和HOG特征方法。然后,我们深入探讨了深度学习如何革新这一领域,重点介绍了R-CNN系列两阶段检测器的发展脉络,以及Mask R-CNN如何实现实例分割。最后,我们了解了如何将这一框架扩展到3D检测、人体姿态估计等更复杂的任务。

如果你想亲自尝试这些强大的模型,Facebook AI Research开源的Detectron2 工具箱是一个绝佳的起点。它提供了多种先进模型的预训练权重和易于使用的代码,方便大家进行实验和开发。

040:任务特定模型 🎯

在本节课中,我们将学习自监督学习中的任务特定模型。这些模型专门针对特定的下游任务进行设计,与我们后续将要学习的、旨在学习独立于任何下游任务的通用表示的模型不同。我们将首先探讨如何无监督地学习深度和自身运动。

概述

我们将重点介绍一种无需深度或姿态真值标签,仅使用单目视频序列来训练深度估计网络和相机姿态估计网络的方法。其核心思想是利用视频帧之间的光度一致性假设来构建损失函数,从而优化网络参数。

无监督深度与自身运动学习

上一节我们介绍了任务特定模型的概念。本节中,我们来看看一个具体应用:从单目视频中无监督地学习深度和相机自身运动。

任务设定如下:训练时的输入仅仅是单目视频(可从互联网下载或用车载相机录制)。目标是训练两个神经网络:

  • 深度网络(绿色):一个卷积神经网络,以单张图像为输入,输出密集的深度图。这是一个单图像深度预测任务。
  • 姿态网络(红色):以两帧图像为输入,预测它们之间的相对相机运动(一个3D旋转矩阵 R 和一个3D*移向量 t,共6个自由度)。

我们希望在没有任何深度或姿态真值监督的情况下,联合训练这两个网络。这看似困难,但我们将看到其实现原理。

核心思想:光度一致性

我们受到经典光流技术的启发,利用光度一致性假设。该假设认为,在静态场景、仅存在相机自身运动、且光照恒定的条件下,同一个3D点在相邻帧中投影的像素颜色应该相同。

以下是实现这一思想的具体步骤:

  1. 选取视频帧:考虑三个连续帧:目标帧 I_t(时间 t)、前一帧 I_{t-1} 和后一帧 I_{t+1}。后两者称为源视图。
  2. 网络预测:深度网络预测目标帧 I_t 的深度图 D_t。姿态网络分别预测 I_tI_{t-1}I_tI_{t+1} 的相对姿态 T_{t→t-1}T_{t→t+1}
  3. 图像扭曲:利用预测的深度 D_t 和相对姿态 T,我们可以将源视图(I_{t-1}I_{t+1})中的像素“扭曲”到目标视图 I_t 的坐标系中,生成扭曲后的图像 Î_{t-1→t}Î_{t+1→t}
  4. 构建损失:如果预测的深度和姿态正确,那么扭曲后的源图像像素应与目标图像对应像素颜色一致。因此,我们可以计算它们之间的差异(如RGB值的L1或L2损失)作为光度一致性损失。通过最小化这个损失,我们可以反向传播梯度来更新深度网络和姿态网络的参数。

投影与扭曲过程

以下是像素从目标帧投影到源帧坐标的数学公式。给定目标帧中的一个像素 p_t 及其预测深度 d_t,其在源帧中的投影位置 p_s 计算如下:

p_s = K * T_{t→s} * d_t * K^{-1} * p_t

其中:

  • K 是相机内参矩阵。
  • T_{t→s} 是预测的从目标帧到源帧的刚体变换([R | t])。
  • p_tp_s 是齐次坐标。

由于计算出的 p_s 是连续值(亚像素精度),我们需要通过双线性插值从源图像 I_s 中采样颜色值,以生成扭曲图像 Î_s。这个操作是可微分的,允许梯度反向传播。

模型架构与损失函数

在实际模型中(如CVPR 2017论文所示),通常会采用以下设计来稳定训练并提升效果:

  • 多尺度预测:深度网络在不同特征尺度上预测深度图,并在相应尺度上计算光度损失,以改善梯度流动和优化效果。
  • 额外的正则化损失
    • *滑性损失:对预测的深度图(或视差图)施加*滑约束,避免陷入不良的局部最优解。这是此类病态优化问题的关键。
    • 可解释性掩码:一些模型会额外预测一个掩码,用于在光度损失中重新加权像素,以处理遮挡或非朗伯表面区域。

最终的优化目标是这些损失的加权和。控制光度损失与*滑性损失之间权重的超参数需要仔细调整。

效果与局限

令人惊讶的是,早在2017年,这种完全自监督的方法在深度估计任务上的性能就接*了有监督方法。其预测的深度图合理、*滑,并能泛化到训练时未标记的区域(如天空)。

然而,该方法有一个核心假设:场景是静态的。因此,在存在动态物体(如移动的车辆、行人)时,模型会失效,因为动态物体违反了光度一致性假设。

从立体图像对进行自监督学习 🖼️🔄

为了解决动态场景的问题,另一种自监督深度估计方法是利用立体图像对进行训练。立体图像是同时拍摄的,因此不存在动态物体导致的帧间外观变化问题。

其核心思想与单目视频方法完全相同,只是将“相邻帧”替换为“立体图像对”(左视图和右视图)。以下是几种模型变体:

  • 简单模型:输入左图,预测左图视差,然后利用视差将右图扭曲至左图坐标系,并计算光度损失。但这种方法可能产生伪影。
  • 改进模型:输入左图,网络同时预测左视差图和右视差图。然后可以:
    1. 用左视差图扭曲右图,与左图计算损失。
    2. 用右视差图扭曲左图,与右图计算损失。
    3. 引入左右一致性约束,强制左视差图与右视差图在几何上一致,这有助于消除异常值并提升训练稳定性。

后续改进

在后续工作中(如Monodepth2),研究者引入了多项改进以提升自监督单目深度估计的质量:

  1. 最小光度损失:当使用三个连续帧时,对每个像素,不再计算与所有源帧损失的*均值,而是取最小值。这有助于处理遮挡,因为一个像素只要在至少一个源帧中可见,就能提供有效的监督信号。
  2. 多尺度损失计算:将低分辨率深度图上采样至高分辨率,再计算与高分辨率图像的光度损失,这可以避免“纹理复制”伪影。
  3. 自动掩码:检测相机是否静止(例如在等红灯时)。如果相机静止,深度估计问题变得病态(任何深度都成立),这类帧会损害训练。通过比较帧间像素的整体变化,可以自动过滤掉这些帧或其中的像素。

这些改进使得自监督深度估计的结果边界更清晰、细节更丰富,性能显著提升。

扩展到光流与场景流估计 🌊

同样的自监督思想可以自然地扩展到其他任务,如光流估计。

一种方法(如2018年论文)采用双向训练策略:

  • 使用一个共享权重的光流网络(FlowNet)。
  • 输入图像对 (I1, I2),网络预测前向光流 F_{1→2}
  • 交换输入顺序为 (I2, I1),同一网络预测后向光流 F_{2→1}
  • 利用预测的光流分别扭曲图像,并计算前向和后向的光度一致性损失。
  • 引入前向后向一致性约束,鼓励光流场在循环投影后保持一致,这有助于处理遮挡区域。

总损失包括*滑性损失、光度数据损失和一致性损失。这种方法能够产生可靠的无监督光流估计结果。

更进一步,可以结合深度和光流,进行场景流的估计(即每个点的3D运动)。同样可以使用自监督方法,例如利用立体视频进行训练,但在推理时仅需单目视频。

总结

本节课我们一起学习了自监督学习中的任务特定模型,重点探讨了如何从视频中无监督地学习深度和运动。

  • 我们首先介绍了利用单目视频序列光度一致性原理,联合训练深度网络与姿态网络的方法。其优势在于无需任何真值标签,但假设场景静态。
  • 接着,我们看到了利用立体图像对进行自监督深度估计的方法,它天然避免了动态场景问题,并通过左右一致性约束提升了效果。
  • 然后,我们了解了诸如最小光度损失、多尺度损失计算和自动掩码等改进技术,它们显著提升了自监督深度估计的质量。
  • 最后,我们将这一框架扩展到光流场景流估计任务,展示了自监督学习思想的通用性。

这些方法展示了如何利用数据本身的内在结构(如视频帧间的几何关系)作为监督信号,在没有昂贵人工标注的情况下,训练出性能优异的视觉模型。

041:自监督学习 - 前置任务 🧩

在本节课中,我们将要学习自监督学习中的“前置任务”方法。前置任务是一种巧妙的设计,它允许我们利用大量无标签数据来训练模型,学习到通用的视觉特征表示,这些特征随后可以迁移到我们真正关心的下游任务中,如图像分类或目标检测。

上一节我们介绍了自监督学习的基本概念,本节中我们来看看一种具体的方法:通过设计“前置任务”来学习特征。

什么是前置任务?

到目前为止,我们看到的自监督模型都是针对特定下游任务(如单目深度估计、光流估计)量身定制的。现在,我们的目标是学习更通用的神经表征。为此,我们将定义一个所谓的“辅助任务”或“前置任务”。

例如,预测图像的旋转角度。我们将图像随机旋转(比如这只鸟的图片),然后要求模型找出图像原本的正确朝向。我们使用这个前置任务进行预训练,希望它能引导我们学习到良好的特征,以便在后续感兴趣的下游任务中重用。

所以,我们定义一个用于预训练的前置任务(如旋转预测)。当然,我们拥有大量无标签数据,可以从互联网下载数百万甚至数十亿张图片。然后旋转它们,并询问网络:“我做了哪种旋转?”我们可以任意角度旋转,例如,可以取90度的倍数旋转,然后问网络这张图片被旋转了多少度。

这就是前置任务。我们取大量无标签数据,针对前置任务定义一个卷积网络(包含几个卷积层和一些全连接层)。在这个例子中,我们希望分类出四种可能的朝向(90度将是正确答案)。

然后,我们丢弃图中白色的最后几层,只保留卷积层的权重(即所谓的特征提取器),并将其复制用于下游任务。

假设下游任务不是旋转预测,而是分类(例如,我们想分类图片中是否有鸟)。我们只有少量带标签的数据(可能每个类别只有20个实例),无法承担更新网络所有参数的成本。但我们希望在前置任务中学到的参数已经足够好、足够通用、具有某种语义意义,以至于我们只需添加一两个新层(例如一个线性分类器)并仅训练这些层,就能获得良好的模型性能。

通过从前置任务迁移大部分参数,并添加一个需要训练的小型“读出头”(该头可以用较少数据训练),我们可以在目标任务(分类)上评估这个网络。

那么,前置任务的一般定义是什么?根据维基百科,前置任务是为做某事或说某事(可能不准确)而找的借口。它可能基于半真半假的事实,或在误导性虚构的背景下发展。前置任务被用来隐藏行动和言语背后的真实目的或理由。

显然,这不是我们想做的。我们想找到一个与下游任务有一定关联,但又是一个“借口”的任务,用它来代替我们真正想做的事。我们这样做是因为它更容易。就像这个例子:告诉妻子我每晚都去图书馆,比说出真相更容易。

前置任务示例

在接下来的内容中,我们将看看文献中提出的一些前置任务。必须承认,这些任务都是手工设计的,目前还没有理论支撑,只有经验证据表明每个任务在实践中效果良好。经验表明,当我们复制这些权重并将其应用于某些下游任务(仅微调某些层或进行少量全网络迭代)时,我们可以用更少的标签数据完成下游任务。

以下是另一个前置任务示例。

通过上下文预测学习

这是最早的前置任务之一,由Dosovitskiy等人在ICCV 2015提出。在这个任务中,目标是根据两个图像块预测它们的相对位置。

我们取一个蓝色的中心块,然后针对这个红色块,我们只观察这两个块,并要求网络分类红色块相对于蓝色块是位于哪个位置(例如左上、正上、右上等)。共有8种可能性,因此这是一个8分类任务。

给定蓝色块和红色块,有8种可能的位置来描述红色块相对于蓝色块的位置。上下文预测的目标是预测图像块的相对位置(这是一个离散集合)。

这里的希望同样是,这个任务要求模型学习识别物体及其组成部分。该任务的设计方式是,如果模型没有学到关于物体如何构成的有趣知识,它将无法解决这个任务。

为了更深入理解,让我们玩一个小游戏(这也是那篇论文的预告图)。你能识别红色块相对于蓝色块的位置吗?给你五秒钟时间思考。

如果你看这两个块,你可能会说:“这是公交车的前部,这是公交车的左后部,所以红色块很可能位于蓝色块的右下角。”它不太可能在正下方(因为那样会显示公交车前部),也不太可能在左侧(因为那样会显示一些背景)。同样,对于火车图片,红色块更可能在蓝色块的上方,因为它显示了火车的顶部,而蓝色块显示了底部。

如果一个神经网络想要正确完成同样的任务,你可以看到它必须获得一些关于现实世界物体的知识,而这正是我们在这里要利用的。

这是论文中使用的架构。两个图像块输入,采用类似孪生网络的架构,经过卷积和池化,直到全连接层。然后,全连接层的输出被拼接,再经过少量全连接层进行分类。

这听起来很棒,但必须注意一些问题。特别是,我们必须确保神经网络不会采取任何简单的捷径解决方案。实际上,神经网络不会做你想让它们做的事,它们会做最简单的事。

例如,如果我们取直接相邻的块,神经网络可以不通过理解物体的语义,而是通过观察边缘并尝试对齐边缘来解决问题。如果它看到边缘是对齐的,那么这种块配置(例如左右交换)的可能性就更大。为了避免模型利用这种简单的捷径,这项工作采取的方法是在块之间引入一个小间隙,使它们不直接相邻,这样边缘连续性就无法被利用。同时,对块位置进行轻微的空间抖动,以避免这种现象。

还有一个更微妙的捷径。作者发现,网络实际上很容易预测图像的绝对位置。如果网络仅通过观察一个块就能预测其绝对图像位置,那么块的相对位置显然可以轻松推断出来。为什么会发生这种情况?

作者做了一个小实验来验证和理解这一点。他们随机裁剪图像块,然后训练一个神经网络以监督方式预测每个块的绝对图像位置。结果发现,网络确实能够做到。网络仅观察这个局部块,就能预测出它在图像中的绝对位置(例如,这个块应该出现在图像的右侧)。这是如何可能的?图像位置信息是如何编码在这个局部块中的?

答案是:一些相机镜头会根据图像位置不同地偏移颜色通道。特别是,镜头质量不佳的相机会出现所谓的“色差”问题。色差源于镜头对不同波长的光反射不同,这意味着不同颜色通道存在空间偏移,而这种空间偏移依赖于图像中的位置。模型可以利用这个事实,仅通过观察局部颜色偏移(而忽略纹理、语义和块内内容)来预测位置,这正是发生的情况。

为了避免网络利用这个简单捷径,解决方案是随机丢弃颜色通道、将颜色投影到灰度通道,或直接使用灰度图像(这当然不允许这种捷径)。

在解决了这些简单捷径后,网络实际上能够学习到一些有语义意义的内容,这些内容可以迁移到下游任务。例如,他们将其用于目标检测(使用R-CNN架构)。他们使用这种基于上下文预测的预训练技术(无需任何标签)来训练卷积神经网络特征,然后使用较小的带标签训练集来训练剩余参数并微调神经网络。他们发现,如果不使用任何预训练,结果会显著变差。虽然在这种情况下,性能尚未达到使用ImageNet标签进行预训练的水*(因为这是一个非常语义化的识别任务,确实受益于监督的语义类别),但令人印象深刻的是,其性能已经可以与使用大量数据、完全监督的ImageNet预训练相媲美。

该方法也适用于表面法线估计等完全不同的任务。同样,他们观察到,没有预训练的结果明显更差,而他们的方法有时甚至超过了ImageNet预训练模型。在这种情况下也更有意义,因为表面法线估计与识别任务非常不同,因此用识别数据集来预训练该模型的参数更困难,所以更容易与这里的监督方法竞争。

论文中还研究了网络实际学到了什么视觉表征。一种方法是在特征空间中寻找最*邻。他们比较了随机初始化网络、AlexNet和他们的自监督方法,发现随机初始化通常不会给出有意义的结果,而他们方法检索到的结果在语义上是有意义的,与使用ImageNet预训练检索到的图像块类似。

拼图游戏任务

在拼图游戏前置任务中,想法是随机排列图像的3x3*铺版本,并要求网络恢复原始图像(就像玩拼图一样)。因为有9的阶乘种不同的排列,数量非常庞大,这是一个巨大的分类问题,所以他们将自己限制在1000种预定义的随机排列。这些排列是根据汉明距离选择的,以增加难度,他们试图找到特别困难的排列,让模型学得更好。

这是使用的架构:九个打乱的图像块首先被输入,然后送入卷积架构,特征被送入MLP进行1000路分类,然后用于反向传播和训练模型。

同样,在拼图任务中,他们必须确保避免捷径,故事与上一篇论文类似。这些捷径之所以发生,是因为它们对解决前置任务有用,但与目标任务无关,因此我们需要避免它们。

一种捷径是低阶统计量。如果你看相邻的块,它们通常包含相似的低阶统计量(如均值和方差)。他们为解决这个问题应用的方法是根据均值和方差对块进行归一化。同样,他们也处理了边缘连续性问题,通过从更大的单元格中随机选择64x64像素的块,有效地应用了一些抖动和填充。色差问题也类似,他们应用了灰度图像或对每个颜色通道进行几个像素的空间抖动来避免。

捷径学习是深度神经网络学习中的一个普遍而有趣的问题。如果你对捷径学习更感兴趣,我强烈推荐Tübingen大学Matthias Bethge团队的这篇论文《Shortcut Learning in Deep Neural Networks》。

通过解决拼图游戏学到的表征是有意义的。在网络的较早层学到了低阶统计量,随着进入更深的层,你得到了更有语义意义的激活。

他们也将这种表征应用于Pascal VOC分类、检测和分割任务(这是几年前著名的挑战赛之一)。他们发现,在某些情况下(例如目标检测),他们的性能已经可以与使用相同架构、相同预训练时间但无需标签的ImageNet全监督预训练模型相媲美。这表明,你并不一定需要ImageNet数据,也可以使用此类前置任务进行预训练,并在某些情况下获得至少可比的性能。

图像修复任务

这是另一个称为“图像修复”的前置任务。它与我们已经见过的去噪自编码器有点相关,但不同之处在于,这里被遮盖的不是单个像素,而是整个大区域。现在的关键任务是尝试仅从上下文恢复被移除的区域。你可以看到模型实际上可以相当不错地完成这项工作。如今(五、六年后)的先进方法比这要好得多,但在2016年,当语义分割和图像级神经推理还相当新的时候,已经可以取得这样的结果。为了让模型真正执行好这个任务,它必须学习一些关于世界结构的知识。这始终是相同的核心理念。

图像旋转预测任务

我们已经在开头看到了图像旋转预测任务。目标是预测所显示图像的朝向,图像被人为旋转,输出是一个4分类任务,我们试图恢复真实的朝向。同样,为了恢复正确的朝向,前提是需要语义知识来解决该任务。

总结

在本节课中,我们一起学习了自监督学习中的前置任务方法。

前置任务侧重于视觉常识,例如重排、旋转预测、修复、着色等。模型被迫学习关于自然图像的良好特征。例如,为了解决前置任务,它们必须隐式地解决更困难的任务(如对象类别的语义分割)。这就是前置任务被选择的方式。我们并不关心前置任务本身的性能,而是关心所学特征表示对我们实际关心的下游任务(如图像分类、目标检测、语义分割、深度估计、法线预测等)的效用。

然而,这种方法的问题是:设计好的前置任务是繁琐的,并且仍然像一种“黑色艺术”,没有完善的理论指导,因此不清楚如何构建更好的前置任务。另一个问题是,学到的表征可能不够通用,前置任务与下游任务的实际关系并不明确。

这正是我们接下来要探讨的内容。

042:对比学习

在本节课中,我们将要学习自监督学习中的一种重要范式——对比学习。我们将探讨其核心思想、数学原理、实现方法以及它如何克服传统前置任务的局限性。

概述

在前面的章节中,我们讨论了各种前置任务,例如拼图、旋转预测等,用于预训练神经网络。然而,这些任务与下游任务(如图像分类)的关联性并不明确,我们只能凭经验希望它们能对齐。本节介绍的对比学习,旨在通过构建一个更通用的学习目标,使模型学习到的特征表示能更好地服务于下游任务。

前置任务的问题

上一节我们介绍了用于预训练神经网络参数的各种前置任务。本节中我们来看看这些方法存在的一个根本问题。

在用于预训练神经网络大量参数的前置任务中,我们考虑的任务乍一看与下游任务完全脱钩。例如,我们尝试解决拼图游戏来预训练神经网络参数,然后为网络附加小型线性层或多层感知机作为“读出头”,并使用少量有标签样本来训练这些读出层的参数,以完成实际的下游任务(如图像分类)。但我们并不知道这个拼图任务是否真的与下游的图像分类任务相关。我们无法确定,正如之前提到的,这里没有理论指导,一切基于经验。

换句话说,我们所做的是强烈希望预训练任务和迁移任务能够对齐,并尝试寻找与下游任务对齐得更好的预训练任务,这正是对比学习的目标。

以下是该问题的另一个图示说明。从拼图等前置任务中学到的特征,其性能表现如下图所示。如果我们在这个网络的不同层附加读出头,下游任务性能(此处为*均精度,越高越好)的变化如图所示。我们观察到,前置任务特征的性能会达到饱和。如果我们使用更后面的、更具语义的层(这些层本应对下游分类任务更有利)并附加线性读出层,性能会饱和甚至在某些点下降。

其原因是,前置任务(如拼图)与图像分类任务差异过大,导致网络的最后几层专门针对前置任务进行了优化。这些层非常擅长解决拼图、上下文预测或旋转估计,但它们并不包含解决图像分类任务所需的语义知识,因此性能会下降。

对比学习的核心思想

现在的问题是,能否找到一个更通用的前置任务?首先,理想的预训练特征应该能够表示图像之间的关联。例如,同一只猫的图片,即使经过轻微改动,其特征在特征空间中也应位于相*区域;而不同动物的图片则应位于特征空间的不同区域。同时,特征应对干扰因素保持不变,例如物体的具体位置、光照条件或颜色等。所有这些变体(你可以认出我们之前讨论过的一些前置任务)都应该与原始图像相似。

在对比学习中,我们的做法不是尝试预测已丢失的某些信息,而是直接让这些相似的变体在特征空间中彼此靠*。我们可以使用任何想要的增强方法。从参考图像生成的这些增强图像,在对比学习社区中被称为“视图”。

简而言之,我们希望构建一个模型,使得对于特定的参考图像,其不同视图在特征空间中彼此靠*,而任何其他物体的任何视图则远离该区域。这在直觉层面正是对比学习的目标。

数学实现:InfoNCE 损失

我们如何实现这个目标?下图展示了基本概念。你可以看到参考图像 X,以及通过数据增强(如裁剪部分、旋转、改变颜色等)生成的正例 X+。它们都应该相似。同时,我们还有负例 X-,它来自不同的图像或同一图像中远离感兴趣区域的区域。相对于参考图像,这些是正例和负例。

在数学上,给定一个选定的评分函数 s,我们希望学习一个编码器网络 f,使得正样本对 (x, x+) 获得高分,负样本对 (x, 😆 获得低分。换句话说,我们希望 s(f(x), f(x+)) > s(f(x), f(x-))

我们可以将其表述为一个优化问题。考虑以下标准对比学习目标:我们有一个参考图像 x,一个正例 x+,以及 n-1 个负例 x-。

以下是常用的多类交叉熵损失函数,与 ImageNet 分类中使用的类似,区别在于内部包含了评分函数。

损失函数公式:
L = -E[log(exp(s(z, z+)) / (exp(s(z, z+)) + Σ_{j=1}^{n-1} exp(s(z, z-_{j}))))]

其中,z = f(x),z+ = f(x+),z-{j} = f(x-)。这个损失通常被称为 InfoNCE 损失。该目标的一个有趣特性是,其负值 -L 是参考图像特征 f(x) 与正例特征 f(x+) 之间互信息的一个下界。互信息越大,下界越紧。另一个关键点是,我们需要一个大的负样本集才能使这个方法有效。

从这个公式中,我们已经可以看到我们试图遵循的关键思想:最大化从多个视图提取的特征之间的互信息,这迫使特征捕获关于更高级别因素的信息。我们的目标是最小化损失,即最大化互信息。

设计选择与挑战

以下是这些对比方法可以考虑的几个设计选择,以及相关的一些问题。

1. 评分函数

第一个设计选择是评分函数。最常见的评分函数选择是余弦相似度,即特征向量的内积除以它们的范数。

余弦相似度公式:
s(u, v) = (u · v) / (||u|| ||v||)

2. 样本选择

第二个设计选择是如何选择正例和负例样本。

  • 对比预测编码:样本取自同一图像。相关正例选自邻*区域,不相关的负例选自远处区域。
  • 实例判别:更常见的方案。假设同一图像中的所有图像块都是相关的(因为都显示了同一个主体,如一棵树),而不相关的负例则来自任何其他随机图像中的随机图像块。这被称为实例判别,因为我们在区分不同的实例。

3. 数据增强

第三个设计选择是数据增强。与之前需要精心设计的前置任务不同,在对比学习中,我们可以组合所有想要的增强方法,这对于使这些方法有效至关重要。例如,我们可以裁剪、调整大小、翻转、旋转图像,或从中切掉一个区域;也可以降低颜色饱和度、添加颜色抖动、添加高斯噪声或高斯模糊,或计算边缘。

代表性方法:SimCLR

目前该领域表现最好的方法之一是 SimCLR。它使用余弦相似度作为评分函数。SimCLR 接收输入参考图像,通过随机采样的增强方法生成两个不同的视图,然后通过我们感兴趣的编码器网络 f 和其后的投影网络 g 进行处理。我们最终想要的是编码器 f 产生的表示 h,而投影网络 g 仅在训练时使用,训练完成后会被丢弃。投影网络有助于更好地训练,因为它允许使用更早层的特征,并且可以投影到更高维的空间。

以下是该方法的核心伪代码:

# 伪代码示例
for x in dataloader:
    # 生成两个增强视图
    view1, view2 = augment(x), augment(x)
    # 通过编码器和投影网络
    h1, z1 = projection(encoder(view1))
    h2, z2 = projection(encoder(view2))
    # 计算 InfoNCE 损失
    loss = InfoNCE_loss(z1, z2, other_negatives_in_batch)
    # 反向传播更新参数
    loss.backward()

SimCLR 效果非常好,在 ImageNet 上的性能可以媲美甚至在某些情况下超过有监督的预训练模型。然而,它的一个关键问题是需要非常大的训练批次大小(例如 4096 或 8192)才能达到最佳性能,这导致了巨大的内存需求,通常需要在大型计算集群上进行分布式训练。

改进方法:MoCo

为了缓解 SimCLR 对大批次大小的依赖和巨大的内存需求,提出了 动量对比 方法。MoCo 的核心思想是维护一个负样本键的队列(可以看作一个环形缓冲区)。在训练时,新的小批次被编码后加入队列,最旧的小批次被移除。关键创新在于:

  1. 动量更新:用于编码队列中键的编码器,不是直接从查询编码器复制,而是采用动量更新的方式,使其参数变化更*滑,保证了队列中键特征的一致性。
  2. 梯度截断:反向传播时,梯度只更新查询编码器,而不更新键编码器,因此无需存储队列中所有样本的中间激活,大大降低了内存需求。

这使得 MoCo 能够使用一个非常大的“字典”(负样本队列),同时只需较小的批次大小(如 256)即可达到与 SimCLR 相当甚至更好的性能,从而使其在常规计算设备(如 8 GPU 节点)上变得可行。

新范式:Barlow Twins

最*提出的 Barlow Twins 方法稍微偏离了经典的对比学习范式,使事情变得更加简单。它不关注样本之间的距离,而是关注神经元之间的冗余度。其核心思想是:神经元应对数据增强保持不变,但彼此之间应尽可能独立。

具体实现是:对同一图像生成两个增强视图,通过编码器得到两个特征向量,然后计算这两个特征向量在批次维度上的互相关矩阵。损失函数鼓励这个互相关矩阵接*单位矩阵:对角线元素接* 1(保证同一神经元在不同视图下的输出相关),非对角线元素接* 0(减少不同神经元之间的冗余)。

Barlow Twins 损失函数:
L = Σ_i (1 - C_ii)^2 + λ Σ_{i≠j} C_ij^2
其中 C 是互相关矩阵,λ 是权衡系数。

这种方法的主要优点是不需要负样本,实现极其简单,并且对批次大小的依赖比 SimCLR 小。它在性能上与最先进的方法相当。

总结

本节课中我们一起学习了自监督学习中的对比学习。我们首先回顾了传统前置任务与下游任务可能存在的错位问题。接着,我们深入探讨了对比学习的核心思想:通过拉*同一图像不同增强视图的特征,并推远不同图像的特征,来学习通用的特征表示。

我们介绍了实现这一目标的数学基础——InfoNCE 损失函数,并分析了评分函数、样本选择和数据增强等关键设计选择。然后,我们详细讲解了三个代表性的对比学习方法:

  1. SimCLR:一个简单有效的框架,但需要极大的批次大小。
  2. MoCo:通过引入动量编码器和负样本队列,显著降低了对内存和批次大小的要求。
  3. Barlow Twins:一种新颖的冗余减少方法,无需负样本,实现简单且性能强大。

这些对比学习和冗余减少方法,相比经典的前置任务,能更好地与下游任务对齐,并产生了最先进的结果,正在缩小与全监督 ImageNet 预训练之间的差距。自监督学习通过从数据本身学习,无需任何人工标签,展示了克服数据标注成本高昂这一难题的巨大潜力。

043:输入优化技术 🎯

在本节课中,我们将学习计算机视觉中一个有趣且强大的概念:输入优化。与之前我们熟悉的优化神经网络权重不同,输入优化技术旨在固定一个预训练好的网络,然后通过反向传播梯度来优化输入图像本身。我们将探讨这一技术在两个截然不同领域的应用:对抗攻击神经风格迁移

概述

在之前的课程中,我们学习了如何通过反向传播梯度来优化神经网络的权重参数。然而,计算图具有更大的灵活性。我们可以固定网络的参数,转而将梯度反向传播到输入节点。这被称为输入优化。本节我们将看到两个应用实例:一是生成能够欺骗分类器的对抗样本,二是生成融合内容与风格的艺术图像

对抗攻击 🔓

上一节我们介绍了输入优化的基本思想。本节中,我们来看看它在对抗攻击领域的应用。对抗攻击揭示了深度神经网络一个令人惊讶的脆弱性:通过对输入图像添加人类难以察觉的微小扰动,就能使网络做出完全错误的预测。

以下是几种主要的对抗攻击方法:

  • L-BFGS攻击:这是早期的一种攻击方法。其目标是寻找一个最小的噪声图像 Δx,将其添加到原始图像 x 上,使得分类器 f 以高置信度将结果分类为目标错误类别 y_t。其数学形式化如下:

    x_adv = x + argmin_{Δx} (||Δx||_2) subject to f(x+Δx) = y_t

  • 鲁棒性对抗攻击:这种攻击考虑了现实世界中的各种变换(如视角变化、光照变化)。它通过优化一个在多种变换下都能保持攻击效果的扰动,使得攻击在物理世界中仍然有效。其核心是期望过变换方法。

  • 补丁攻击:与针对整个图像的微小扰动不同,补丁攻击是在图像中添加一个较小的、可见的特定图案。这个补丁被优化为无论放置在场景中的哪个位置,都能导致网络误分类。例如,一个打印出来的小贴纸可以让自动驾驶系统将“停车”标志误认为其他物体。

对抗攻击的成功催生了一个庞大的防御研究领域。主要的防御范式包括:

  • 梯度掩蔽/混淆:通过隐藏或扭曲模型的梯度信息,使基于梯度的攻击方法失效。
  • 鲁棒性优化/对抗训练:在训练过程中主动加入对抗样本,让模型学习如何正确分类它们,从而提高鲁棒性。
  • 对抗样本检测:研究正常样本与对抗样本在分布上的差异,从而在输入模型前将其检测并过滤掉。

神经风格迁移 🎨

在了解了如何利用输入优化进行“破坏”后,我们来看看它如何用于“创造”。神经风格迁移是一种利用输入优化生成艺术图像的技术,其目标是将一张图片的内容与另一张图片的风格融合起来。

以下是神经风格迁移的核心步骤:

  1. 使用预训练网络:固定一个在ImageNet上预训练好的VGG网络,将其作为特征提取器。
  2. 定义损失函数:定义两个损失函数来分别约束生成图像的内容和风格。
    • 内容损失:确保生成图像在高层特征上与内容图像相似。它计算生成图像和内容图像在特定网络层(如conv4_2)的特征图之间的均方误差。

      L_content = ||F^l - Pl||2
      其中,F^lP^l 分别是生成图像和内容图像在第 l 层的特征图。

    • 风格损失:确保生成图像在纹理和风格上与风格图像相似。它通过比较生成图像和风格图像在各层特征图的Gram矩阵来实现。Gram矩阵计算了不同特征通道之间的相关性,能有效捕捉纹理信息。

      G^l_{ij} = Σ_k F^l_{ik} F^l_{jk}
      L_style = Σ_l w_l ||G^l - Al||2
      其中,G^lA^l 分别是生成图像和风格图像在第 l 层的Gram矩阵,w_l 是各层的权重。

  3. 优化输入:从一个随机噪声图像开始,将其作为输入送入固定的VGG网络。通过反向传播,计算内容损失和风格损失对输入图像的梯度,并不断更新这个输入图像(而非网络权重),使其总损失最小化。

最终,优化过程会收敛到一张既保留了内容图像主体结构,又具有风格图像艺术特色的新图像。

总结

本节课中,我们一起学习了输入优化这一核心概念。我们看到,通过固定预训练模型的参数并反向传播梯度至输入,可以实现两种强大的应用:

  1. 对抗攻击:通过精心构造的微小扰动,可以揭示并利用神经网络的脆弱性,这对模型的安全性和鲁棒性提出了重要挑战。
  2. 神经风格迁移:通过结合内容损失和风格损失,可以创造出融合不同图像内容与风格的艺术作品,展示了深度学习在创造性任务上的潜力。

这两种技术虽然目的不同,但都体现了深度神经网络计算图的灵活性,以及通过梯度优化解决复杂视觉问题的强大能力。

045:人体模型 🧍

在本节课中,我们将要学习计算机视觉中一个重要的主题:人体建模。我们将重点介绍一个在学术界和工业界都非常流行且影响深远的生成式人体模型——SMPL模型。理解人体模型对于分析人类行为、实现人机交互以及创建虚拟角色(如电影或游戏中的角色)都至关重要。

概述

人体通过身体进行互动,如拥抱、协作、舞蹈等。为了理解和模拟这些互动,我们需要一个能够精确表示人体形状和姿态的模型。SMPL模型正是这样一个生成式人体模型,它专注于建模穿着最少衣物的人体,并力求在几何形状和外观上尽可能真实。

SMPL模型的目标

SMPL模型的设计目标如下:

  • 真实感:模型的重建结果应看起来像真人。
  • 精确变形:模型的变形应像真人身体的变形。
  • 参数精简:模型应具有少量参数,便于表示、存储和操作。
  • 易于拟合:模型应易于拟合到扫描数据或图像上,以便理解人体。
  • 易于动画化:模型应易于动画化,便于在电影或游戏等场景中驱动生成的虚拟角色。

模型的输出是一个三维网格,该网格依赖于姿态、形状、动态和纹理等参数。

人体建模的历史与灵感

人体形状和姿态的建模在计算机视觉领域有着悠久的历史,始于上世纪70-80年代。一个核心问题是:什么是好的表示方法?

SMPL模型的一大灵感来源于1999年Blanz和Vetter在SIGGRAPH上发表的关于人脸模型的里程碑式工作。该工作可以看作是SMPL模型的前身,但专注于人体的特定部分——面部。该模型能够从单张照片重建高精度的3D人脸形状和纹理,并进行动画处理,即使在今天看来也令人印象深刻。

SMPL模型简介

SMPL是“Skinned Multi-Person Linear Model”的缩写。其核心思想是:收集大量人体扫描数据,并从中创建一个生成式3D模型。这个模型是“因子化”的,意味着我们可以独立控制姿态、形状、动态等不同因素。

例如,在固定姿态下可以改变形状,在固定形状下可以改变姿态,或者同时改变两者。这种解耦设计使得模型能够灵活生成多样化的人体。

SMPL的技术细节

上一节我们介绍了SMPL模型的基本概念和目标,本节中我们来看看其背后的技术实现。

网格表示与注册问题

SMPL使用3D网格作为输出表示。一个基础网格由艺术家设计,以匹配大多数人体,它包含约7000个顶点(即21000个数字)。然而,直接在这个高维空间中操作会产生大量无意义的随机形状。我们的目标是在这个空间中找到与训练数据集中人体形状相对应的“合理”设置。

为了实现这一目标,第一步是解决网格注册问题。原始的扫描数据只是无序且不完整的3D点云,存在许多伪影和孔洞。我们需要将一个由艺术家设计的模板网格与每个扫描数据对齐。这是一个“先有鸡还是先有蛋”的难题:我们需要训练好的模型参数来将模板变形以匹配观测数据,同时又需要已注册的观测数据来训练模型。

SMPL模型的解决方案是联合求解模型估计和注册问题

形状建模:主成分分析

现在,让我们暂时假设注册问题已经解决,所有扫描数据都被转换到了一个标准姿态(例如“T-pose”)。然后,我们可以将每个扫描数据表示为一个向量(顶点坐标减去*均形状),并将所有向量堆叠成一个矩阵。通过对这个矩阵进行主成分分析,我们可以得到一个线性模型。

该模型可以表示为:
M(β) = \bar{T} + \sum_{n=1}^{|\beta|} \beta_n S_n
其中,\bar{T} 是*均形状,S_n 是形状基向量(主成分),β 是低维的形状参数(例如10维)。通过改变 β,我们可以生成不同体型的人体,从整体尺寸到局部细节。

姿态变形:从线性混合蒙皮到SMPL

然而,我们最初并没有所有在标准姿态下的注册数据。SMPL通过扩展线性混合蒙皮 技术来联合解决注册和建模问题。

以下是线性混合蒙皮的工作原理:
对于模板网格上的每个顶点 T_i,我们通过一个加权和将其变换到目标姿态:
v_i' = \sum_{k=1}^{K} w_{k,i} G_k(\theta, J) T_i
其中,w_{k,i} 是蒙皮权重(表示第 k 根骨骼对顶点 i 的影响程度),G_k 是第 k 根骨骼的刚性变换矩阵(依赖于姿态参数 θ 和关节位置 J)。在关节处,顶点会受到相邻两根骨骼变换的混合影响,以实现*滑过渡。

但是,线性混合蒙皮过于简单,在关节处会产生不真实的收缩或膨胀等伪影。

SMPL的改进

SMPL在LBS的基础上引入了三个关键改进,其公式为:
M(\beta, \theta) = W(T_P(\beta, \theta), J(\beta), \theta, \mathcal{W})
具体来说:

  1. 关节位置回归:关节位置 J 不再是固定的,而是通过一个函数从形状参数 β 回归得到,以适应不同体型(如高矮胖瘦)。
  2. 形状矫正项:在标准姿态下添加一个与形状参数 β 相关的偏移量 B_S(β),以精确建模不同体型的静态形状差异。
  3. 姿态矫正项:添加一个与姿态参数 θ 相关的偏移量 B_P(θ)。这是SMPL最关键的创新,它通过在标准姿态下根据目标姿态预先调整网格形状,来补偿LBS在变形时产生的伪影,从而得到更自然、真实的变形效果。

SMPL模型在一个包含数千个扫描数据的大型数据集上训练,优化形状基 S、姿态矫正基 P 以及其他参数。

SMPL模型的应用与扩展

SMPL模型能够精确表示人体形状,并可以拟合到许多人身上。它的应用包括:

  • 运动重定向:将一个人的运动迁移到另一个具有不同体型的人体模型上。
  • 动态建模:扩展模型(如DMPL)可以建模软组织随时间变化的动态效果。
  • 单图像人体姿态与形状估计:利用模型先验知识,仅从单张RGB图像中估计人体的3D姿态和形状。

当前研究方向与总结

本节课中,我们一起学习了SMPL人体模型。它通过因子化的方式,用少量参数生成真实感强、易于动画化的人体网格,是许多后续工作的基础。

当然,人体建模的研究并未止步。当前的研究方向包括:

  • 衣物的建模(比裸体或穿少量衣物的人体更难)。
  • 外观材质的真实感建模。
  • 动态交互(如人与人、人与环境)的建模。
  • 极少数据(如网络摄像头)中学习并创建个性化虚拟化身。

这些方向正在推动计算机视觉中人体建模领域不断向前发展。

046:深度伪造技术 🔍

在本节课中,我们将学习计算机视觉领域的一个重要且备受关注的话题——深度伪造。我们将了解其基本概念、核心技术原理、应用场景以及相关的检测方法。

什么是深度伪造?🤔

深度伪造这个名称,有趣的是,最初来源于一个GitHub代码仓库。随后它迅速传播开来,现在被广泛用来指代整个相关技术领域。

以下是该GitHub仓库,这是一个仍在积极维护的仓库,旨在让名为“FaceSwap”的技术对所有人开放。其目的是帮助公众更好地理解该技术的可能性,并意识到该技术带来的影响。

你可以在这里看到一个例子,其中应用了“换脸”技术。该技术用于替换视频中人物的脸部,并以逼真的视频形式播放。它被应用到了一位演员的视频上,但这位演员的脸被替换成了尼古拉斯·凯奇的脸,如右图所示。

深度伪造如何工作?⚙️

这个原始的换脸模型实际上相当简单。它的工作方式是提取两个视频中的人脸。

你需要两个视频,并希望交换其中的人脸。你需要录制两个不同人物的视频。从这两个视频的所有帧中提取人脸。一旦提取了人脸,你就为这两个人分别训练一个自动编码器,其中关键的是编码器是共享的。

这样,你可以使用同一个编码器,将这张脸或那张脸映射到同一个潜在空间。编码器共享权重的作用是强制使用同一个潜在空间,以捕捉诸如姿态、表情和光照等在单个视频中会变化的因素。

现在我们有了一个训练好的编码器和两个独立的解码器(分别对应两个人)。在推理时,换脸技术所做的就是简单地交换解码器:用新的身份解码器来解码潜在编码。这样,我们可以获取此人的表情和光照条件,然后用另一个人的外观渲染出来。

正如你所见,它并不完美,在许多情况下,人们仍然相对容易识别。但当然,这项技术自那时起已经进步,取得了许多进展,人们越来越难以识别差异。

以下是这个原始深度伪造换脸技术实际运行的例子。

“你能有朋友吗?”“是的。”“但你没有感情,对吧?”“不完全是,然而,即使在人类中,友谊有时也较少是情感反应,而更多是一种熟悉感。”“你会习惯某个人,没错。当我经历某些感官输入模式时,我的心理路径会习惯它们。最终会预见到输入,甚至在缺失时会想念它。”

希望你认出了这里被换脸的角色。

换脸与面部重演的区别 🎭

换脸只是其中一种技术,实际上是一种非常朴素的技术。也许更有趣的是“面部重演”。换脸和面部重演有什么区别?

这在这里有说明。左边是换脸。在换脸中,我们从一个视频中获取人脸,并将其复制到另一个视频上。我们取这张脸,将其复制到另一个视频中人物的脸上,但我们无法操纵那个视频。目标视频仍然以原始视频中演员的表情运行。我们只是试图用新的外观替换那张脸的样子。因此,输出是背景(包括头发等)和新前景的混合体,并且如你所见,也存在伪影,例如不同的发型混合在一起,这是这种混合过程的明显伪影。

相比之下,在面部重演中,我们感兴趣的是动画。我们在这里做的是,从一个视频中获取表情——仅仅是表情。然后用它来驱动另一个人物。我们这里有那个人物,我们获取那个表情,并试图驱动那个人物,但保持那个人物的身份不变。因此,我们不是取两张图像的混合体,而是仍然保持那个人物、那个身份、那个外观,只是改变那个人物正在做的事情。

这使得它比仅仅换脸能实现更多功能,特别是动画。当然,这对图形和电影行业非常相关,并且已经使用传统的图形技术(如三维重建、材质和光照估计)在电影行业中得到广泛应用。然而,传统方法需要精细的三维模型创建和手动编辑,这相当繁琐且非常昂贵。因此,机器学习有潜力自动化这一过程,从而以更低的成本实现更丰富的编辑。

面部重演技术:Face2Face 🎬

这是该领域一些研究小组的成果。我将向你展示的是图宾根大学马蒂亚斯·尼迈尔实验室所做的一些研究。

他们实验室一项特别受欢迎的工作叫做“Face2Face”。Face2Face的目标是实现实时面部重演。对于源视频(即演员的视频),使用普通的网络摄像头捕获。因此,它结合了两个非常困难的问题:实时处理,同时使用非常有限的传感器(只需一个价值约50美元的普通网络摄像头)。

这是如何工作的?这是一项2016年的传统技术,它没有使用大量学习,主要采用计算机图形学技术。它使用了一个人脸模型,比如我们在前一单元展示过的3D形变模型。它通过将这个面部模型非刚性密集对齐到源视频和目标视频来恢复该模型的参数,然后在源视频和目标视频上跟踪这个面部模型的参数。

如果你能做到这一点,你就有了几何估计和两个视频上的外观估计。然后,你就可以开始交换两者,因为通过模型,你有了两者之间的对应关系。这就是所谓的“外观迁移”。你可以像这样获取目标和源,然后用源的表情渲染目标。

以下是该技术的一个小视频演示。

“我们提出了一种新颖的实时面部重演方法,适用于任何普通网络摄像头。由于我们的方法仅对源演员和目标演员使用RGB数据,因此我们能够实时操纵YouTube视频。我们在此演示了我们的方法在实时设置中的应用。在右侧,源演员通过标准网络摄像头捕获。此输入驱动左侧监视器上显示的视频中人脸的动画。与先前方法的一个显著区别是嘴部内部的重新渲染。为此,我们基于时间和光度相似性,使用训练序列中的视频片段重新合成了目标演员的嘴部内部。正如我们所见,我们能够生成逼真且令人信服的重演结果。这里我们展示了先前实时重演片段的特写。输入视频流显示在左侧,请注意目标演员以中性姿态重新渲染。在右侧,我们可以看到我们方法的最终输出。”

正如你所见,它允许对表情进行相当复杂的操纵,但当然,它不允许对姿态进行任意操纵,并且在这种情况下只影响面部区域。

超越传统:神经渲染 🧠

为了超越传统图形技术并提高输出的真实感,这篇名为“Deferred Neural Rendering”的特定论文使用了一种所谓的“神经渲染器”。它基本上只是一个U-Net网络,它接受一个特征表示,并通过这个神经网络进行推理来渲染输出。这样做的好处是,它可以补偿我之前讨论的基于模型的方法可能存在的缺陷。

例如,面部模型可能没有完美对齐,或者人脸可能实际上并不完全符合面部模型。或者由于遮挡或透视缩短效应,可能很难转移某些像素的外观。因此,你需要做的是“幻觉”出内容,而这正是这个神经网络可以做到的。

这个模型所做的与之前的模型非常相似。它也提取一个面部模型,但它结合了一种所谓的“神经纹理”来提取几何形状。对于每个像素,我们都有一个特征向量,用于捕获应存储在该表面点上的部分外观信息。然后,这个神经纹理可以被渲染成一张图像,这就是神经渲染器的输入,其任务是生成逼真的、照片级的输出图像。这样,它可以修复伪影并克服这些问题,因为它有额外的参数可以补偿这些缺陷。

“嗯,布什41,克林顿,布什43还是奥巴马?为什么?我真的会说克林顿,可能我不得不说克林顿,为什么?坦率地说,他本来会有一点精神的。”

这是一个例子,正如你所见,人类很难(当然,除了这个例子中的男孩们)区分视频是真实的还是伪造的。而这正是引起极大关注的原因,也引起了研究界的兴趣。

深度伪造检测 🛡️

因此,现在有许多研究工作关注深度伪造检测:给定一个视频,我如何检测该视频是否被人工操纵过,或者它是否是原始视频。

其基本思想非常简单。我们使用多种技术创建一个包含真实视频和操纵视频的大型数据集。然后,我们可以训练卷积神经网络来尝试区分真实与伪造。我们简单地学习一个二元分类器来检测被操纵的图像。这效果相当好。

这就是这篇名为“FaceForensics++”的论文中收集的数据集。它收集了许多视频,超过200万个被操纵的帧,并且是公开的,因此每个人都可以用它来测试他们的算法、他们的检测算法。它是使用许多深度伪造技术创建的,如左图所示,包括Face2Face和原始的换脸技术等。因此,将不同的深度伪造创建技术结合到一个大数据集中,然后可以用来训练分类模型。

如果你这样做,会发生什么?如果你在相同分布的数据集测试集上测试(即使用相同技术操纵的数据集,例如Face2Face),它会获得非常高的分类准确率。但是,如果你在一个数据集上训练,然后在用不同技术创建的数据集上测试,性能会下降到几乎随机猜测的水*。这意味着这种方法本身泛化能力不强。因此,这是当前的研究课题:如何使这些模型更好地泛化?这里采用的技术是计算机视觉界用来解决这些问题的经典技术,例如自监督学习、迁移学习和联邦学习。

深度伪造的积极应用:Synthesia 🚀

马蒂亚斯·尼迈尔的研究小组也在这一领域衍生出了一家初创公司。因为当然,生成这些人工角色不仅仅是一种对抗性的想法,它还可以在许多领域带来益处。例如,在电影中,也许一个角色已经去世,你需要重演该角色;或者在新闻报道中,也许记者无法到场或生病了等等。因此,在许多用例中,你希望有合成角色说话,这正是其中一家名为“Synthesia”的初创公司的重点。

有一个网站,你实际上可以提交自己的视频,提交自己的文本,它会通过人工智能完全生成由这位演员叙述的视频。我想向你展示Synthesia为我提交的文本生成的视频。

“亲爱的同学们,我希望你们喜欢图宾根大学的这门计算机视觉基础系列讲座。我祝你们考试一切顺利。我说不出比这更好的话了。本讲座到此结束。非常感谢你们一直陪伴我们到最后。当然,我和整个图宾根团队都祝你们考试顺利。我希望在未来的讲座中再次见到你们。谢谢。”

总结 📝

在本节课中,我们一起学习了深度伪造技术。我们从其定义和起源开始,了解了基础的换脸技术原理,包括共享编码器和独立解码器的自动编码器架构。接着,我们探讨了更高级的面部重演技术,如Face2Face,它通过3D面部模型参数跟踪和外观迁移实现表情驱动。然后,我们看到了神经渲染如何通过U-Net等网络提升生成结果的真实感,以补偿传统模型的不足。我们也讨论了深度伪造检测面临的挑战,即模型在跨技术泛化上的困难。最后,我们了解了深度伪造技术的积极应用,例如Synthesia在内容创作领域的用例。深度伪造是一把双刃剑,既带来了创新的可能性,也引发了关于真实性和安全性的重要讨论。

posted @ 2026-03-26 13:18  布客飞龙V  阅读(0)  评论(0)    收藏  举报