【论文简读】DIV-Loss

很久没有跟踪无监督MVS的工作了,今天快速过一篇ECCV2024 Oral的文章,作者都来自UCSB。这也是我第一次知道这个学校也有组在做MVS。

项目地址:Github

文章目录

  • [1 Introduction](#1 Introduction)
  • [2 Related Work](#2 Related Work)
  • [3 Methods](#3 Methods)
    • [3.1 Preliminaries](#3.1 Preliminaries)
    • [3.2 Depth-Smoothness Loss](#3.2 Depth-Smoothness Loss)
    • [3.3 Image-Synthesis Loss](#3.3 Image-Synthesis Loss)
    • [3.4 Supervision View Sampling](#3.4 Supervision View Sampling)
  • [4 Experiments](#4 Experiments)
  • [5 核心代码](#5 核心代码)

1 Introduction

论文的主要创新点集中在改进无监督 MVS 的核心损失函数,提出了 DIV Loss,包括以下三个关键部分:

  • 提出了一个新的深度平滑loss,使用Clamped 2nd-Order Depth Smoothness
  • 提出了一个learning-based监督,通过合成图像来做,提升与视角相关的效果
  • 除了使用本来的source views之外,还使用更多的view来做监督,以增强网络预测未见视角的能力

介绍了有监督和无监督的MVS,并且多介绍了深度平滑的一些工作,为后面展开说自己的方法做铺垫。

3 Methods

3.1 Preliminaries

pipeline如下图所示:

3.2 Depth-Smoothness Loss

如图2所示,传统无监督MVS的平滑损失使用一阶梯度,这样的损失鼓励locally-constant depth,容易导致楼梯效应(stair-stepping),在物体边界就深度非常不准,造成artifacts。于是,部分工作使用二阶梯度,来鼓励locally-smooth depth,这样虽然能缓解楼梯效应,但这样会错误地跨物体边界平滑,导致深度边界模糊,如图4所示。

作者发现,二阶梯度光滑性是有用的,但不应在边界区域过度 penalize。因此,他们提出梯度截断(Clamping),即在计算损失时将二阶梯度的绝对值限制在一个上限。这样的话,在平滑区域,损失与传统二阶平滑一致,就能保持平滑表面;在物体边界,二阶梯度通常很大,但被 clamp 限制,就不会被过度penalize了,并且,允许出现清晰的深度不连续性,可以消除深度渗透问题。

本文创新点:提出 "二阶梯度+梯度截断"。

  • 对二阶梯度进行截断(clamp),允许在物体边界处出现锐利的深度不连续。
  • 在平滑区域仍能保持光滑性,显著减少边界artifacts。
  • 效果:显著改善物体边界的深度预测质量。

3.3 Image-Synthesis Loss

传统无监督MVS使用基于warp的photometric loss,并用min-K策略过滤遮挡与高误差像素。

本文创新点:引入一个小 CNN 网络。

  • 将 warp 后的多视角图像作为输入,预测每个像素的权重。
  • 将加权融合后的结果作为"合成参考图像"进行 photometric supervision。
  • 同时结合显式的遮挡 mask(shadow mapping)。
  • 优点:更好地处理视角相关效应(如高光、反射);避免手工设计启发式规则。

3.4 Supervision View Sampling

以往方法使用的监督视图与MVS输入视图完全一致。

本文创新点:DIV Loss 额外采样一些非输入视图作为监督信号。

  • 挑战网络去预测能在未见视角下仍一致的深度。
  • 提高模型泛化能力与对缺失信息的鲁棒性。
  • 几乎无额外计算成本。

4 Experiments

目前来说纯无监督MVS这个是SOTA,从实验表格上看这个截断loss和策略上的trick在其他MVS pipeline也可以用上。

5 核心代码

核心创新点,也就是loss中深度平滑正则项,对二阶梯度的截断,实现很简单。

python 复制代码
def depth_smoothness_2nd_order(depth, img, lambda_wt=1.0, clip=2.0):
    """Computes image-aware depth smoothness loss using relaxed 2nd-order formulation."""
    # 对深度图计算一阶梯度,append_zeros=True表示在图像边界补零,避免尺寸不一致
    depth_dx, depth_dy = gradient(depth, append_zeros=True)
    # 对一阶梯度再求梯度,得到二阶梯度
    depth_dxdx, depth_dxdy = gradient(depth_dx, append_zeros=True)
    depth_dydx, depth_dydy = gradient(depth_dy, append_zeros=True)

    # enormous 2nd order gradients correspond to depth discontinuities
    # 将所有二阶梯度截断到[-clip, clip],避免边界处的大梯度被过度penalize,从而允许物体边界出现锐利的深度不连续
    depth_dxdx = torch.clip(depth_dxdx, -clip, clip)
    depth_dxdy = torch.clip(depth_dxdy, -clip, clip)
    depth_dydx = torch.clip(depth_dydx, -clip, clip)
    depth_dydy = torch.clip(depth_dydy, -clip, clip)

    # 对图像计算一阶梯度
    image_dx, image_dy = gradient(img, append_zeros=True)

    # get weight for gradient penalty
    # 在图像的边缘处,梯度大,权重变小,相当于放宽深度平滑约束(允许深度跳变)
    # 在图像平坦区域,梯度小,权重接近1,相当于强化平滑约束
    weights_x = torch.exp(-(lambda_wt * torch.sum(torch.abs(image_dx), 3, keepdim=True)))
    weights_y = torch.exp(-(lambda_wt * torch.sum(torch.abs(image_dy), 3, keepdim=True)))

    # 对 x、y 方向分别计算平滑损失,每个方向同时考虑同方向和交叉方向的二阶导数(平均后求和),最终返回两个方向的加权平均
    smoothness_x = weights_x * (torch.abs(depth_dxdx) + torch.abs(depth_dydx)) / 2.
    smoothness_y = weights_y * (torch.abs(depth_dydy) + torch.abs(depth_dxdy)) / 2.
    return torch.mean(smoothness_x) + torch.mean(smoothness_y)

这个正则是一种无监督的几何先验,解决了"深度要合理"的问题,允许物体边界处的锐利跳变。

相关推荐
星夜Zn42 分钟前
生成式人工智能展望报告-欧盟-04-社会影响与挑战
论文阅读·人工智能·大语言模型·发展报告·ai社会影响
余俊晖1 小时前
图像、视频、音频多模态大模型中长上下文token压缩方法综述
人工智能·音视频
LetsonH1 小时前
⭐CVPR2025 FreeUV:无真值 3D 人脸纹理重建框架
人工智能·python·深度学习·计算机视觉·3d
蹦蹦跳跳真可爱5891 小时前
Python----大模型(大模型微调--BitFit、Prompt Tuning、P-tuning、Prefix-tuning、LORA)
人工智能·python·深度学习·自然语言处理·transformer
小杨勇敢飞1 小时前
大语言模型的解码策略:贪婪解码与波束搜索
人工智能·语言模型·自然语言处理
喵王叭1 小时前
【大模型核心技术】Agent 理论与实战
人工智能·langchain
golitter.1 小时前
pytorch的 Size[3] 和 Size[3,1] 区别
人工智能·pytorch·python
乙真仙人2 小时前
数据,正在成为AI大模型最后的护城河
大数据·人工智能·数字化
eric-sjq2 小时前
基于深度学习的图像到文本序列转换技术
人工智能·深度学习
源图客2 小时前
Ubuntu22.4部署大模型前置安装
人工智能·深度学习