让相机自己决定拍哪儿!——NeRF 三维重建的主动探索之路

我在 NeRF 中折腾自动探索式三维重建的心得

写在前面:
最近我在研究三维重建方向,深切感受到 NeRF (Neural Radiance Fields) 在学术界和工业界都备受瞩目。以往三维重建通常要依赖繁琐的多视图几何管线(比如特征匹配、深度估计、网格融合等),或者需要依靠激光雷达 / RGB-D 传感器才能得到可观的三维数据。

但 NeRF 出现后,给三维重建带来了革命性的思路:它直接用一个多层感知机(MLP)来隐式建模场景位置和方向与颜色、密度的映射关系,再配合可微分的体渲染公式,就能端到端地重建出精准且逼真的场景。

然而,NeRF 往往默认已经有一批“采集好”的图像,训练时并不考虑如何采集这些图像。一旦缺乏足够且有效的多视图信息,NeRF 也很难重建出理想效果。

所以在本文里,我想分享的核心想法是:如果我们能主动控制相机的运动轨迹,怎样才能高效、全面地探索场景,从而让 NeRF 重建的质量更优?


用 NeRF 做三维重建时,如何自动选择拍摄视角?——我的探索尝试

为什么要关心相机视角?
大家可能都知道,NeRF(Neural Radiance Fields) 这种用神经网络来做三维重建的方法很火,它能在一批图像的驱动下,隐式地学习场景的几何和外观,然后渲染出各种新视角图像。但问题是,如果拍摄视角不够好,或者数据采集做得比较随意,就算再强大的 NeRF 也很难得到完整、清晰的重建。

所以我就想:既然相机可以移动,那能不能自动规划相机的运动,让它去“看”最需要看的地方?这样既能节省拍摄成本,也能让 NeRF 获得更准确的三维模型。于是,就折腾出了下面这套“自动探索式”三维重建方法的思路。


一、总体想法

1. 大方向

  1. 一开始,用少量随机拍摄到的图像先训练出一个初步的 NeRF;
  2. 然后让相机(例如无人机或者机器人上的摄像头)自动探索
    • 根据当前 NeRF 的“模型不确定性”评估哪些位置、哪个角度拍摄更有价值;
    • 规划相机的运动路径,让它飞过去拍摄;
    • 将新获得的图像再增量更新到 NeRF 中;
  3. 如此循环,直到我们的 NeRF 足够“自信”,或者时间 / 资源耗尽。

2. 为啥要不确定性?

NeRF 其实暗含了一个体密度(也可以理解为“有没有东西”)的分布,某些区域如果模型还没看清,就会有比较大的“熵”(表明不确定度高)。如果在这些区域多来几张照片,模型就能对它更确定,进而让重建更加精准和全面。


二、用“熵”来衡量哪些视角值得拍

1. 信息增益的概念

我们可以把相机的某个视角记为 V V V,然后把这个视角可以“看到”的所有光线统称为 R ( V ) R(V) R(V)。如果 NeRF 在这些光线上不太确定,那就说明这个视角能带来“新知识”。用函数 H H H 描述不确定度的话,信息增益可以用下面这个公式来表示:

Gain ( V ∣ F ) = ∑ r ∈ R ( V ) ∫ n e a r f a r H ( σ F ( r ( t ) ) ) d t \text{Gain}(V \mid F) = \sum_{r \in R(V)} \int_{near}^{far} H\bigl(\sigma_F(r(t))\bigr)\, dt Gain(VF)=rR(V)nearfarH(σF(r(t)))dt

这里, σ F ( r ( t ) \sigma_F(r(t) σF(r(t) 是 NeRF 对光线上某点密度的估计; H ( p ) = − p log ⁡ p − ( 1 − p ) log ⁡ ( 1 − p ) H(p) = -p \log p - (1-p)\log(1-p) H(p)=plogp(1p)log(1p) 是二值分布的熵。当 p ≈ 0.5 p \approx 0.5 p0.5 时熵最大,也就代表不确定性最高。

2. 时间衰减

在实际探索中,我们希望在早期阶段多挖掘信息,因此让早期视角的增益更“值钱”,可以给它加一个时间衰减系数 1 / i 1/i 1/i

Gain ( V i ∣ F ) = 1 i ∑ r ∈ R ( V i ) ∫ n e a r f a r H ( σ F ( r ( t ) ) ) d t \text{Gain}(V_i \mid F) = \frac{1}{i} \sum_{r \in R(V_i)} \int_{near}^{far} H\bigl(\sigma_F(r(t))\bigr)\, dt Gain(ViF)=i1rR(Vi)nearfarH(σF(r(t)))dt

这样,在最初几次探索时,相机会更加积极地寻找那些不确定性高的区域进行拍摄;后面如果想要精修细节,也可以再继续拍,但贡献权重逐渐变低。


三、让相机别乱走——用“表面趋势场”来规划运动

1. 为什么要表面趋势?

如果一个场景的某些位置变化剧烈(比如物体的边缘或拐角处),就需要多看看;如果一片平坦空旷,可以“快步路过”。为此,我们构造了一个“表面趋势场” g ⃗ ( x ) \vec{g}(x) g (x) ,让它告诉相机:哪些地方表面变化快,值得多花点时间拍。

2. 趋势场怎么定义?

我们想要某个函数 Φ ( x ) \Phi(x) Φ(x) 来表示“距离表面有多远”。在传统 3D 里,这类似“有符号距离场 (SDF)”。NeRF 里可以用“体密度”在光线终止处做一个期望估计,得到一个近似的距离分布:

Φ ( x ) ≈ ∫ n e a r f a r d ⋅ σ F ( r ( d ) ) d d \Phi(x) \approx \int_{near}^{far} d \,\cdot\, \sigma_F(r(d)) \, dd Φ(x)nearfardσF(r(d))dd

然后对 Φ \Phi Φ 做梯度,就能获得

g ⃗ ( x ) = ∇ Φ ( x ) = ( ∂ Φ ∂ x , ∂ Φ ∂ y , ∂ Φ ∂ z ) . \vec{g}(x) = \nabla \Phi(x) =\left( \frac{\partial\Phi}{\partial x}, \frac{\partial\Phi}{\partial y}, \frac{\partial\Phi}{\partial z} \right). g (x)=∇Φ(x)=(xΦ,yΦ,zΦ).

如果 ∥ g ⃗ ( x ) ∥ \|\vec{g}(x)\| g (x) 很大,就意味着这里的表面变化剧烈,需要重点关注。

如何理解这条公式

Φ ( x ) ≈ ∫ n e a r f a r d ⋅ σ F ( r ( d ) ) d d \Phi(x) \approx \int_{near}^{far} d \,\cdot\, \sigma_F\bigl(r(d)\bigr)\,\mathrm{d}d Φ(x)nearfardσF(r(d))dd

  1. 这里的 d d d 表示沿光线从近端 n e a r near near 到远端 f a r far far深度 (或者距离)。
  2. σ F ( r ( d ) ) \sigma_F\bigl(r(d)\bigr) σF(r(d)) 可以理解为 NeRF 模型对光线 r r r 在深度 d d d 处的“体密度”或“占据概率”预测。

如果我们把 σ F \sigma_F σF 看作对“物体在深度 d d d 附近出现的可能性”进行加权的函数,那么:

  • σ F ( r ( d ) ) \sigma_F\bigl(r(d)\bigr) σF(r(d)) 较大时,就意味着在深度 d d d 左右有更高概率遇到场景表面;
  • 将深度 d d d 与该处的密度相乘,并在整个可见深度范围内积分,相当于在所有深度上做一个加权平均,得到“光线可能终止(与表面交汇)的期望深度”。

因此, Φ ( x ) \Phi(x) Φ(x) 可以近似表示“场景表面在哪儿”。在此基础上,还可以对其做梯度计算,用来估计表面的趋势或几何结构,并将这些信息应用于相机路径的规划和优化。

3. 在时间上也要优化

现在我们不只选“空间上的拍摄点”,还想决定多久拍一次运动速度如何。于是把相机轨迹离散成一系列 t j , v j t_j, v_j tj,vj 控制点,目标是让相机尽量垂直于表面趋势运动,同时时间分配要平滑。可以写成一个优化问题:

{ t j , v j } 1 : m = arg ⁡ min ⁡ { t j , v j } ∑ j = 1 m − 1 ∫ t j t j + 1 ∥ v j ⋅ g ⃗ ( p ( t ) ) ∥ 2 d t + λ ∑ j = 1 m ( Δ t j ) 2 \{t_j, v_j\}_{1:m} = \arg\min_{\{t_j, v_j\}} \sum_{j=1}^{m-1} \int_{t_j}^{t_{j+1}} \bigl\| v_j \cdot \vec{g}(p(t)) \bigr\|_2 \, dt \;+\; \lambda \sum_{j=1}^{m} (\Delta t_j)^2 {tj,vj}1:m=arg{tj,vj}minj=1m1tjtj+1 vjg (p(t)) 2dt+λj=1m(Δtj)2

并满足

∑ j = 1 m Δ t j = T , p ( t j ) = v j . \sum_{j=1}^m \Delta t_j = T, \quad p(t_j) = v_j. j=1mΔtj=T,p(tj)=vj.

这里, Δ t j = t j + 1 − t j \Delta t_j = t_{j+1} - t_j Δtj=tj+1tj表示第 (j) 段运动时间, l a m b d a \\lambda lambda 是平滑系数。如果轨迹跟表面走得“太平行”,就会被惩罚;而太频繁地加减速,也会被惩罚。


四、在线更新 NeRF,别让模型忘掉以前的地方

1. 滑动窗口思路

每次拍到新图像,我们都把它放进一个缓存 ( B ) 中。如果缓存超了,就丢掉最老的数据(或者做优先级筛选)。然后每来一张图,就利用它做一点梯度更新:

Θ n + 1 = Θ n − η ∇ Θ L ( I n , V n ; Θ n ) , \Theta_{n+1} =\Theta_n - \eta \nabla_\Theta \mathcal{L}\bigl(I_n, V_n; \Theta_n\bigr), Θn+1=ΘnηΘL(In,Vn;Θn),

这里 Θ \Theta Θ 是 NeRF 参数, η \eta η 是学习率。

2. 避免遗忘

如果相机一直在某个局部区域晃悠,缓存里就全是这个局部的图像。久而久之,模型可能把其他区域的记忆“遗忘”了。
为此,我们引入一个重建置信度 C Ω ( x ) = exp ⁡ ( − H ( σ F ( x ) ) ) C_\Omega(x) = \exp(-H(\sigma_F(x))) CΩ(x)=exp(H(σF(x)))。如果熵大,置信度就低,表示当前点的重建不够好。相反,熵小就代表模型在那儿挺确定了。
那对每张图像,衡量一下它覆盖了多少“低置信度”区域,把这个结果当做采样权重

w ( I i ) = 1 ∣ R ( V i ) ∣ ∑ r ∈ R ( V i ) ∫ n e a r f a r [ 1 − C Ω ( r ( t ) ) ] d t . w(I_i) =\frac{1}{|R(V_i)|} \sum_{r \in R(V_i)} \int_{near}^{far} \bigl[\,1 - C_\Omega(r(t))\bigr] \, dt. w(Ii)=R(Vi)1rR(Vi)nearfar[1CΩ(r(t))]dt.

数值大的图,说明它拍到了更多不确定区域,也就更值得在训练中多出现。这样可以平衡:已经很熟悉的地方,别再重复占用太多训练迭代;而欠探索区域的图像要多参与训练。
另外,还可以周期性地复位缓存,回到历史所有数据,让模型整体都再刷一遍,防止完全遗忘老地方。


五、实验情况与一些发现

  1. 合成场景:在模拟环境里,我们控制无人机在一个大盒子里乱飞,比较不同策略:

    • 随机飞;
    • 固定速度向前飞;
    • 贪心只看单步“下一视角增益”;
    • 以及我们的“综合时空优化”策略;
      结果显示,我们的方法在渲染质量和覆盖率上都显著更高。在相同的拍摄步数下,能覆盖更多有效区域,也重建得更精细。
  2. 真实场景:在一些公开的三维重建数据集(如 Tanks & Temples, ScanNet)上,也把已有图像视为“可能拍摄到的潜在位置”,再模拟我们的探索算法。我们的自动探索在大规模、复杂环境中更能显出优势,尤其是室内场景遮挡多,需要更聪明地选择角度。另外,我们的增量式训练在资源占用上还算可控,没有比传统离线训练方式高太多。

  3. 采样分布可视化:如果画一张俯视图,会看到随机或者固定路线的拍摄,分布要么太散,要么只在少数地方。而我们的策略在前期先快速扫一遍全局,然后在几何细节多的地方慢下来细拍。最终形成一条既兼顾覆盖,又兼顾细节的曲线。


六、还有哪些不足?

  • 暂时只考虑静态场景:如果场景里有动态人物、非刚体形变等,就需要更复杂的动态 NeRF,定义不确定性也会更棘手;
  • 没和语义任务结合:现在只考虑了几何信息增益,如果还想做目标检测 / 语义分割,就要把语义不确定性也加进来;
  • 相机内参等因素:我们主要在优化“相机位姿”,没考虑镜头焦距、曝光等更多可调参数;
  • 需要进一步的持续学习方法:虽然用了缓存和加权采样,但在超长时间的探索中,如何让模型一直保持对过去的记忆,还是一个难题。

七、总结

整体而言,让相机主动探索,在 NeRF 等隐式表示下做三维重建,能显著提升建模的速度和精度。这背后其实是一个很有潜力的研究方向:把主动视觉神经场景表示结合起来,不再被动地“等数据”,而是“主动去找数据”。
如果未来和机器人、无人机技术紧密结合,那么在陌生环境中,机器人就能自己知道去哪儿拍、怎么拍,快速学到一份高保真的 3D 场景模型。对自动驾驶、VR/AR、环境监测等领域都大有帮助。

参考一些前沿成果:

  • Mildenhall et al. “NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis”
  • Barron et al. “Mip-NeRF”
  • Müller et al. “Instant Neural Graphics Primitives”

非常期待这个方向能吸引更多研究和应用,也欢迎大家讨论和分享自己的想法!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/14732.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5 计算机网络

5 计算机网络 5.1 OSI/RM七层模型 5.2 TCP/IP协议簇 5.2.1:常见协议基础 一、 TCP是可靠的,效率低的; 1.HTTP协议端口默认80,HTTPSSL之后成为HTTPS协议默认端口443。 2.对于0~1023一般是默认的公共端口不需要注册,1024以后的则需…

unity碰撞的监测和监听

1.创建一个地面 2.去资源商店下载一个火焰素材 3.把procedural fire导入到自己的项目包管理器中 4.给magic fire 0 挂在碰撞组件Rigidbody , Sphere Collider 5.创建脚本test 并挂在magic fire 0 脚本代码 using System.Collections; using System.Collections.Generic; usi…

使用云效解决docker官方镜像拉取不到的问题

目录 前言原文地址测试jenkins构建结果:后续使用说明 前言 最近经常出现docker镜像进行拉取不了,流水线挂掉的问题,看到一个解决方案: 《借助阿里个人版镜像仓库云效实现全免费同步docker官方镜像到国内》 原文地址 https://developer.aliyun.com/artic…

element-plus+vue3前端如何根据name进行搜索查到符合条件的数据

界面如图&#xff0c;下面的区域是接口给的所有的&#xff0c;希望前端根据输入的内容自己去匹配。 我是使用的element-plusvue3ts的写法。 <el-input v-model"filters.region" placeholder"输入区域搜索" keyup"filterRegion(filters.region)&q…

电路研究9.3——合宙Air780EP中的AT开发指南(含TCP 示例)

根据合宙的AT研发推荐&#xff0c; AT指令基本上也简单看完了&#xff0c;这里开始转到AT的开发了。 AT 命令采用标准串口进行数据收发&#xff0c;将以前复杂的设备通讯方式转换成简单的串口编程&#xff0c; 大大简化了产品的硬件设计和软件开发成本&#xff0c;这使得几乎所…

cursor指令工具

Cursor 工具使用指南与实例 工具概览 Cursor 提供了一系列强大的工具来帮助开发者提高工作效率。本指南将通过具体实例来展示这些工具的使用方法。 1. 目录文件操作 1.1 查看目录内容 (list_dir) 使用 list_dir 命令可以查看指定目录下的文件结构: 示例: list_dir log…

AI安全最佳实践:AI应用开发安全评估矩阵(上)

生成式AI开发安全范围矩阵简介 生成式AI目前可以说是当下最热门的技术&#xff0c;吸引各大全球企业的关注&#xff0c;并在全球各行各业中带来浪潮般的编个。随时AI能力的飞跃&#xff0c;大语言模型LLM参数达到千亿级别&#xff0c;它和Transformer神经网络共同驱动了我们工…

Java继承简介

继承的本质&#xff1a;是代码的复用&#xff0c;重复使用已经定义好的方法和域&#xff08;即全局变量&#xff09; 要掌握继承首先要了解Java方法的重载和重写 方法的重载和重写 方法的重载 当前方法名相同&#xff0c;但是参数类型不同&#xff0c;发生重载 类比数学函…

【redis】缓存设计规范

本文是 Redis 键值设计的 14 个核心规范与最佳实践&#xff0c;按重要程度分层说明&#xff1a; 一、通用数据类型选择 这里我们先给出常规的选择路径图。 以下是对每个步骤的分析&#xff1a; 是否需要排序&#xff1f;&#xff1a; zset&#xff08;有序集合&#xff09;用…

Unity抖音云启动测试:如何用cmd命令行启动exe

相关资料&#xff1a;弹幕云启动&#xff08;原“玩法云启动能力”&#xff09;_直播小玩法_抖音开放平台 1&#xff0c;操作方法 在做云启动的时候&#xff0c;接完发现需要命令行模拟云环境测试启动&#xff0c;所以研究了下。 首先进入cmd命令&#xff0c;CD进入对应包的文件…

Android studio怎么创建assets目录

在Android Studio中创建assets文件夹是一个简单的步骤&#xff0c;通常用于存储不需要编译的资源文件&#xff0c;如文本文件、图片、音频等 main文件夹&#xff0c;邮件new->folder-assets folder

第26场蓝桥入门赛

5.扑克较量【算法赛】 - 蓝桥云课 C&#xff1a; #include <iostream> #include <algorithm> using namespace std;int a[100005];int main() {int n,k;cin>>n>>k;for (int i1; i<n; i)cin>>a[i], a[i] % k;sort(a1, a1n);int mx a[1]k-a…

公司配置内网穿透方法笔记

一、目的 公司内部有局域网&#xff0c;局域网上有ftp服务器&#xff0c;有windows桌面服务器&#xff1b; 在内网环境下&#xff0c;是可以访问ftp服务器以及用远程桌面登录windows桌面服务器的&#xff1b; 现在想居家办公时&#xff0c;也能访问到公司内网的ftp服务器和win…

c++:list

1.list的使用 1.1构造 1.2迭代器遍历 &#xff08;1&#xff09;迭代器是算法和容器链接起来的桥梁 容器就是链表&#xff0c;顺序表等数据结构&#xff0c;他们有各自的特点&#xff0c;所以底层结构是不同的。在不用迭代器的前提下&#xff0c;如果我们的算法要作用在容器上…

《Wiki.js知识库部署实践 + CNB Git数据同步方案解析》

一、wiki.js 知识库简介 基本概述 定义 &#xff1a;Wiki.js 是一个开源、现代、轻量且功能强大的 Wiki 应用程序&#xff0c;基于 Node.js 构建&#xff0c;旨在帮助个人和团队轻松创建、管理和共享知识。开源性质 &#xff1a;它遵循 AGPLv3 许可证&#xff0c;任何人都可以…

ip地址是手机号地址还是手机地址

在数字化生活的浪潮中&#xff0c;IP地址、手机号和手机地址这三个概念如影随形&#xff0c;它们各自承载着网络世界的独特功能&#xff0c;却又因名称和功能的相似性而时常被混淆。尤其是“IP地址”这一术语&#xff0c;经常被错误地与手机号地址或手机地址划上等号。本文旨在…

微服务 day01 注册与发现 Nacos OpenFeign

目录 1.认识微服务&#xff1a; 单体架构&#xff1a; 微服务架构&#xff1a; 2.服务注册和发现 1.注册中心&#xff1a; 2.服务注册&#xff1a; 3.服务发现&#xff1a; 发现并调用服务&#xff1a; 方法1&#xff1a; 方法2&#xff1a; 方法3:OpenFeign OpenFeig…

网络安全:挑战、技术与未来发展

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 在数字化时代&#xff0c;网络安全已成为全球关注的焦点。随着互联网的普及和信息技术的高速发展&#xff0c;网络攻击的…

PostgreSql-COALESCE函数、NULLIF函数、NVL函数使用

COALESCE函数 COALESCE函数是返回参数中的第一个非null的值&#xff0c;它要求参数中至少有一个是非null的; select coalesce(1,null,2),coalesce(null,2,1),coalesce(null,null,null); NULLIF(ex1,ex2)函数 如果ex1与ex2相等则返回Null&#xff0c;不相等返回第一个表达式的值…

neo4j-解决导入数据后出现:Database ‘xxxx‘ is unavailable. Run :sysinfo for more info.

目录 问题描述 解决方法 重新导入 问题描述 最近在linux上部署了neo4j&#xff0c;参照之前写的博客:neo4j-数据的导出和导入_neo4j数据导入导出-CSDN博客 进行了数据导出、导入操作。但是在进行导入后&#xff0c;重新登录网页版neo4j&#xff0c;发现对应的数据库状态变…