预备知识

最近在学习 CV 相关的双目相机立体匹配 Stereo Matching,本文是关于 GwcNet 的一些学习和思考。开始之前,先需要理解几个概念:RGB 像素、特征向量、张量、视差、立体匹配、三维重建、代价体、视差求解的范式、卷积正则化。

RGB 像素

图像由像素组成,一张 1920x1080 分辨率的屏幕就代表有 1920x1080 个像素。RGB 代表光的三原色。R = Red,G = Green,B = Blue。这三种颜色通过不同的亮度组合可以形成各种颜色。计算机给每种颜色的亮度划分了 0 ~ 255 共 256 个等级。

可以计算出,三种原色,256 种亮度,可以组合出 $256^3≈1677万$ 中颜色。

每一个彩色图像的像素点都由红、绿、蓝三个发光的子像素(Sub-pixels,可以理解为三个微型 LED 灯)紧挨着组成的,可以看成:(R, G, B),比如 (255, 0, 0) 代表纯红。这是 原始像素


特征向量

像素的高维向量。一个图像有 1024 个像素,理论上特征向量也有 1024 个,一一对应,相当于给每一个像素发一张“高维身份证”。但在工程上,使用 CNN 提取高维特征向量十分消耗显存,如果像素和特征向量 1:1 很容易爆显存。

所以要 降采样 : 使用“步长卷积(Stride Convolution)”或“池化(Pooling)”将图像 缩小(降采样)。比如在比如 GwcNet 中,特征图的宽和高都被缩小到了原来的 $1/4$。

假设原本像素为 $32×32$,降采样 1/4 后得到 $8*8=64$ 个特征向量。此时这 64 个特征向量里的每一个,代表的不再是单个像素,而是一小块区域(感受野)的特征汇总。


张量

向量-Vector,张量-tensor。数学上,向量就是一阶张量。但是,在物理几何体系和计算机工程(深度学习)体系下,它们代表了两种完全不同的“世界观”。

深度学习视角

在这个世界里(也就是 PyTorch / TensorFlow 的世界),张量纯粹就是一个 装载数字的收纳盒(多维数组)。可以把张量理解为高维数组。

  • 核心概念: 张量是 数据结构,用来高效存取成千上万个数字。
  • 什么是“维度”: 指的是 嵌套的层级(轴的数量 / Rank)
    • 1 维张量 (1D Tensor):一排格子(只有行)。比如 [3, 4],或者你的 320 维特征 [0.5, 0.1, ..., 0.9]
    • 2 维张量 (2D Tensor):一个表格(有行、有列)。比如一张灰度图片。
      [[1,2,3], [4,5,6], [7,8,9]] 是一个形状(Shape)为 (3, 3) 的二维张量。
    • 3 维张量 (3D Tensor):一个魔方(有行、列、深度)。比如彩色图片,或者你刚学的代价体。
  • 什么是“长度/大小”: 某个轴上有多少个格子(元素个数)。
  • 关注点: 程序员和 CV 研究员关心的是,我的显存能不能装下这个多维数组?它的 Shape(形状)能不能和下一个网络层对齐(Broadcasting)?
视角 这个东西是什么? “维度 (Dimension)” 的含义 “长度 (Length/Size)” 的含义
几何/数学 这是一个存在于极高维抽象空间中的 320 维几何向量 它需要 320 个坐标轴来定位空间位置。 根据多维勾股定理算出来的极其抽象的空间模长(距离)。
深度学习/代码 这是一个存放了 320 个特征属性的 1 维张量 (1D Tensor) 它的套娃层级只有 1 层(它只有一条轴 / 一个方向)。 这个数组里装了 320 个具体的数字元素。

特征向量

为什么在深度学习里我们还要管它叫“特征向量”?

既然它是张量,为什么论文(包括这篇 GwcNet)里还是满篇都在写“Feature Vector(特征向量)”呢?

因为当我们对这个 1D 张量进行计算时,我们借用了数学世界的工具。 比如在 GwcNet 中,我们把左图的 8 个数字和右图的 8 个数字拿来做 内积(Dot Product),借此来衡量这两个特征在抽象空间里的“夹角”(相似度)。


视差

定义

有一个理想的双目相机系统,两个相机的成像平面是共面和行对齐的,左图中某个点,与对应右图中的匹配点在同一个水平线上。

如果空间中有一个三维点 $P$,它在左图的像素坐标是 $(u_L, v)$,在右图的对应坐标是 $(u_R, v)$ (注意纵坐标 $v$ 是一样的),那么这个点的视差 $d$ 就是它们在水平方向上的坐标差:

这就是视差。它是一个 标量,单位是 像素(Pixel)

应用

视差可以用来求一个像素点的深度(Depth),就是像素点对应的物体实际离相机的距离。具体公式为:

Z 为深度,f 为相机焦距,B 为基线(左右两个相机光心之间的物理距离),d 为视差

image-20260323222726980

学术

当前有一些立体匹配网络,基于代价体构建的 GwcNet、IGEV,基于循环迭代的 RAFT-Stereo。这些网络本质都是求视差 d,即为左图的一个像素点,在右图如何寻找最准确的对应点求出视差 $d$。

简而言之,视差是连接 2D 图像特征和 3D 几何物理世界的桥梁。


立体匹配 和 三维重建

双目相机匹配

核心任务是:在左右两张图像中,把显示中同一个物理点的像素点找出来。(寻找同名点

这里举一个实例

使用双目相机拍摄一个苹果。苹果的果梗在左相机 $(u_L,v)$,在右相机的 $(u_R,v)$。使用人眼很容易根据经验找出两幅图像的相同像素点。但是计算机需要一种算法,当它拿到左图果梗的像素时,能去右图里 精确地“匹配”到 对应的那个像素。

事先要对相机做 极线校正,使双目向机成像水平,这样找一点在另一图像中像素点,只需要沿着水平方向滑动搜索。

立体匹配

Stereo Matching

核心任务是:寻找同名点,即像素的同一个物理点,根据视差计算深度。

三维重建

3D Reconstruction

核心任务是:在计算机世界复刻现实物体或场景的3D几何结构和外观。立体匹配是三维重建的前置重要任务。


代价体 Cost Volume

介绍

一种为了求解视差定值的数据结构,他是三维张量。

在刚才的苹果匹配例子中,实际采用的是 穷举法打分:对于左图的一个像素点,在右图中把所有可能的视差偏移量(比如 0~192 像素)穷举一遍,每次都计算出左右两个 像素块 的相似度或者差异度(代价)。当这个代价最小,即两个像素块差异最小时,可以认为找到了匹配像素点。

构建代价体的传统方法:

  • 传统方法:计算两个像素快的 绝对误差和 SAD
  • 深度学习:提取左右图的高维特征矩阵,计算内积,相似度越高越好

把左图所有的像素 $(H \times W)$,针对所有可能的视差搜索范围 $(D)$,全部算出一个匹配得分后,把这些得分堆叠在一起,就形成了一个三维的张量(Tensor)—— 这就是代价体(Cost Volume)。

它的维度通常是:最大视差数 $(D) \times$ 图像高度 $(H) \times$ 图像宽度 $(W)$

image-20260323215538996

  • 关于这个坐标 D ($D$ / Disparity),被称为通道维度或深度维度,它代表了所有的 候选视差值

  • 关于坐标 $(x, y, d)$ 的含义,每一个坐标存放一个数值(打分),这个数值代表了:左图的坐标 $(x, y)$ 这个像素,如果去和右图的坐标 $(x-d, y)$ 这个像素匹配,它们的“差异度(Cost)”或“相似度(Correlation)”有多大。

作用

有了这个存满打分值的三维张量,即可以求视差。

如果这个数值 $f(x_0, y_0, d_0)$ 是相似度,那么这个数值的最大值 $f_m(x_0, y_0, d_0)$,对应的 $(x_0, y_0, d_0)$ 点,这个 $d_0$ 即为像素 $(x_0, y_0)$ 实际视差。

为什么要把它做成一个完整的三维张量? 如果只看单个像素,很容易受噪声干扰(比如一块纯白色的墙,右图哪个位置看起来都很像)。把所有像素的匹配得分整合到一个宏大的 3D 张量中后,现代深度学习模型(比如 3D CNN 或 3D 堆叠沙漏网络)就可以在这个大张量里进行 空间维度的平滑和上下文信息聚合。它可以参考周围像素的信息,把原本不明显的极值变得更加突出和准确。


3D 卷积正则化

Gwc 这篇论文代表的是 3D 匹配的卷积正则化的范式。在立体匹配和三维重建的语境下,正则化=代价聚合=空间平滑。严格意义上,代价聚合是目的,卷积正则化是手段。

概述

在立体匹配的语境下,卷积正则化本质是为了 去噪上下文投票。当我们构建好代价体后,他是一个堆评分

Gwc 这篇论文使用 3D 堆叠沙漏网络 作为 3D 卷积正则化的工具。


求视差的基本流程

一共分为五步,输入像素、提取特征向量、构建代价体、卷积正则化、视差回归。

关于这个流程

这个流程本质上是计算机在做信号搜索与解码。

Step1 RGB像素输入

系统接收到左右图,为许多 RGB 像素点。但不能直接使用 RGB 原始像素去匹配,因为左右图相同颜色的点可能不止一对,引发歧义。

Step2 特征提取

为解决歧义,使用 2D CNN 卷积神经网络,将原本单薄的 RGB 像素被编码成了一个高维的 特征向量(比如 64 维度),, 然后 Pooling 进行降采样,这个特征向量包含了一个像素点高级征信息(如是否处于边缘、材质),是他的“指纹”。

Step3 构建代价体

根据特征向量,在右图的同一行寻找左图像素的对应点,假设最大视差范围是 192 个像素。系统会把左图的特征,与右图平移 0 到 192 个位置的特征分别进行比对(GwcNet 采用了 分组相关,按特征子空间分别计算相似度)。

计算完毕构成了巨大的张亮 — 代价体。

像素提取特征向量,经历了降采样的步骤,这时特征向量数量小于 RGB 像素数量,这时是怎么根据特征向量来构建代价体的?能够根据它直接对比吗?

  1. 代价体是由“降采样”后的少量特征向量构成的

  2. 数学上比较高维向量的手段非常优雅

    在 CV 领域,比较两个高维特征向量(比如左右图都是 320 维的向量)相似度,向量内积。如果两个向量相似度高,方向指向相似,那么内积值会很大。如果积出来是复数或者是 0,那么关系很微弱。

Step4 代价聚合

刚建好的代价体是非常嘈杂的,使用 3D 卷积神经网络 CNN 把代价体进行精炼,使其变成干净的概率分布体。

Step5 视差回归

针对左图的某一个像素,我们沿着代价体的视差维度看过去,会得到一条平滑的概率曲线。理论上直接找最高点,即视差。但实际上要构建视差图:不直接取最高点(Argmax),而是使用 Soft-argmin 操作。它会对这条概率曲线进行加权求和(算期望值)。这样不仅能输出连续的、平滑的视差图,还能让整个网络保持“可微”状态,从而支持端到端的反向传播训练。

GwcNet

这篇论文的核心贡献在 Step3,提取出图像特征后构建代价体。


GwcNet

Group-wise Correlation Stereo Network (GwcNet)

这篇论文属于双目立体匹配领域 Stereo Matching,是 2019CVPR 的会议论文。它提出了一种构建 代价体 的高效方法(GwcNet),方便求解视差。

背景 - 构建代价体的两难

极端一:全相关

极端二:直接拼接

折中解法:分组相关

核心贡献

混合代价体(Combined Volume)的互补设计

该方法将左右图提取的两组特征向量,沿着维度通道 channel dimension 划分成多个组。然后每一组的对应特征之间独立计算相关性。

c723c552-9b39-4627-88f8-957f917c3667

该图左侧(蓝色部分)是特征提取部分,使用 CNN 提取 类似 ResNet 分别对左图 ($I_L$) 和右图 ($I_R$) 提取特征。

该图中间(橘色部分)为核心,分两路构建两个代价体,最后再合并 Combined Volume 。上面的分支 Concat Volume 把提取的特征压缩后,直接进行拼接;下路 Group-Corr Volume分组相关代价体,下面这一路专门用来提供高精度的匹配相似度特征。

需要注意的是并非左图只用 直接拼接 , 右图只用 分组相关 ,而是把左图和右图的代价体分成两半,一半用直接拼接,一半用分组相关,分别构建两个代价体,再合并起来,这在论文中被称为 Combined Volume(混合代价体)

这样做可以实现优势互补:

  • 分支 A(直接拼接代价体):左右图各自压缩后直接拼接,他保留了绝对完整的上下文语义信息。能为后续的 3D 网络提供丰富的全局感知。
  • 分支 B(分组相关代价体):左右图特征进行分组内积,计算精准的相似度得分,减轻 3D 网络推断相似度的负担。

该图右侧,合并出混合代价体(粉色部分),最后通过 Soft-argmin 输出黑白的视差图。

分组相关 Group Wise Correlation

那么分组相关的具体细节是怎么实现的呢?这个主要在论文 3.2 节 (Group-wise correlation volume) 中,有严格的数学定义。

可以用张量流转的思路理解:

改进的 3D 堆叠沙漏聚合网络

c583c125-535a-420d-8dfd-5cb20ca70c5c

这是将上一图中 粉色方块(3D aggregation network) 的内部结构。主要作痛是代价聚合、空间正则化。