卫星影像覆盖范围广、获取成本低,是构建数字孪生城市和大规模地形三维重建的重要数据来源。但直接把经典的神经辐射场(Neural Radiance Fields)方法套用到卫星图像上,重建质量往往不理想。Sat-NeRF正是针对卫星成像特点改造NeRF的一类方法,它把太阳方位角、高度角等物理量引入辐射场建模,让网络能适应跨时相、跨光照条件下的影像差异,从而恢复出更可靠的三维几何结构。本文将从问题背景、核心原理、实现思路和实际应用几个层面展开介绍。

为什么经典NeRF在卫星影像上表现不佳
经典NeRF假设输入图像来自同一场景的近距离密集拍摄,相机视角环绕目标物体或区域,视角之间基线较小且光照条件基本一致。而卫星影像的成像条件截然不同:不同时相拍摄的光照方向差异极大,太阳高度角可能从早上的30度变化到正午的70度,导致同一地物在不同影像中的颜色和阴影完全不同。
这种光照不一致会直接破坏NeRF训练所依赖的光度一致性假设。网络在学习过程中无法判断像素颜色差异究竟来自视角变化还是光照变化,最终收敛到错误的几何解,重建结果出现漂浮物、扭曲的建筑物轮廓或者大面积模糊。此外,卫星图像视角稀疏且近似平行投影,可用的视差信息有限,进一步加剧了几何估计的病态性。
另一个不可忽视的问题是大气影响。成像路径长,大气散射和薄云会导致不同影像之间存在整体色调偏移,这种全局辐射差异如果不在模型中显式处理,会淹没掉真正有用的几何线索。Sat-NeRF系列方法正是围绕这些问题逐一给出解决方案。
Sat-NeRF的核心原理与模型设计
Sat-NeRF的关键改进是把太阳几何信息作为条件输入到神经辐射场中。具体来说,网络除了接收采样点的空间坐标和观察方向外,还接收当前影像对应的太阳方位角和高度角。这样网络可以显式地学习场景在不同光照条件下的外观变化,例如建筑物在早晨和正午呈现的不同阴影形态。
在几何表达上,由于卫星成像接近正射投影,Sat-NeRF通常采用射线方向上固定的方向向量替代传统NeRF中依赖相机位置的观察方向计算方式。场景坐标系直接建立在地心坐标系或局部切平面坐标系上,方便把多张卫星影像的射线统一到同一空间中进行积分渲染。
损失函数设计上,Sat-NeRF除了标准的光度损失外,通常还会加入跨视角的几何一致性约束,例如利用不同视角对同一表面点的可见性关系构造阴影一致性损失。简单来说,如果一个三维点在某张影像中被其他建筑遮挡处于阴影中,那么在其他影像中它的受光状态也应该符合对应的几何关系。这种物理约束显著提升了重建的鲁棒性。
辐射补偿与色彩校准
针对大气和传感器差异带来的全局色调偏移,实践中常用的做法是为每张影像学习一组仿射色彩变换参数,即一个缩放系数和一个偏移量。渲染出的颜色先经过这组参数校准再与真实像素比较,可以有效吸收掉跨影像的辐射差异,让网络把注意力集中在几何学习上。类似的思路在S-NeRF等工作中被证明非常有效。
基于PyTorch的简化实现思路
下面给出一个简化版的Sat-NeRF网络结构示意,重点展示如何把太阳角度信息融合进NeRF的输入。实际工程中还需要配合体渲染流程、分层采样以及多影像光线批处理。
import torch
import torch.nn as nn
class SatNeRF(nn.Module):
def __init__(self, pos_dim=60, dir_dim=24, sun_dim=24, hidden=256):
super().__init__()
# 位置编码后的坐标维度 + 太阳角度编码维度
self.input_dim = pos_dim + sun_dim
self.pos_mlp = nn.Sequential(
nn.Linear(self.input_dim, hidden), nn.ReLU(),
nn.Linear(hidden, hidden), nn.ReLU(),
nn.Linear(hidden, hidden), nn.ReLU(),
nn.Linear(hidden, hidden), nn.ReLU(),
)
# 输出体密度,仅依赖几何与太阳几何
self.density_head = nn.Linear(hidden, 1)
# 外观分支额外接收观察方向和影像嵌入
self.color_mlp = nn.Sequential(
nn.Linear(hidden + dir_dim + 16, hidden // 2), nn.ReLU(),
nn.Linear(hidden // 2, 3), nn.Sigmoid()
)
self.feature_head = nn.Linear(hidden, hidden)
self.embedding = nn.Embedding(64, 16) # 每张影像一个外观嵌入
def forward(self, pos_emb, dir_emb, sun_emb, img_id):
h = self.pos_mlp(torch.cat([pos_emb, sun_emb], dim=-1))
density = torch.relu(self.density_head(h))
feat = self.feature_head(h)
img_emb = self.embedding(img_id)
color = self.color_mlp(
torch.cat([feat, dir_emb, img_emb], dim=-1))
return density, color上述代码中,太阳角度编码与空间坐标编码一起输入主干网络,共同决定体密度,这体现了阴影与几何耦合的物理直觉:阴影区域吸收率不同,本质上与太阳方向相关。外观分支中的影像嵌入则起到了前文提到的辐射补偿作用,每张影像学习独立的隐式色彩偏移。
训练数据的准备需要注意几点。首先是精确的有理多项式系数(RPC)模型,用于把像素坐标反投影为地面射线;其次是每张影像的太阳方位角和高度角,可以从拍摄时间与卫星轨道参数计算得到;最后建议对影像做辐射定标,把DN值转换为表观反射率,减少原始数据中的辐射噪声。数据集划分时保留一两张影像作为测试视角,用PSNR和SSIM评估新视角合成质量,同时用重建网格与LiDAR参考数据的Chamfer距离评估几何精度。
应用场景与工程实践建议
Sat-NeRF在大范围城市三维建模中有明显优势。传统的摄影测量方法如SfM加MVS虽然成熟,但对弱纹理区域和光照差异敏感,而Sat-NeRF通过神经网络的先验学习能力能补全这些薄弱区域。在建筑物密集的城市中心区,Sat-NeRF重建的立面几何通常比纯MVS方法更完整,屋顶和阴影区域的细节也更丰富。
工程落地时有几点经验值得参考。第一,训练分辨率要控制,全分辨率卫星影像直接训练代价极高,通常先在降采样影像上预训练,再逐步提升分辨率微调。第二,注意显存管理,多影像批次采样时把光线按影像分组,配合梯度累积可以显著降低峰值显存。第三,重建结果导出时建议采用密度阈值加 marching cubes 提取网格,再结合多视角深度图融合做后处理平滑。
当然,Sat-NeRF也并非没有局限。训练耗时长、对RPC精度要求高、动态场景(移动车辆、植被季节变化)会造成鬼影。后续研究出现了结合平面扫描先验、引入单体化建筑物参数化先验等改进方向,进一步提升了几何质量。对于想要上手的开发者,可以先在公开数据集上复现,例如涵盖多个城市的多时相卫星影像基准,再迁移到自己的数据上,逐步调整太阳编码维度和损失权重,通常就能获得比较稳定的结果。