PHENet:雾天遥感为什么需要高度先验

Date 2026-05-10 · Category tech · Status finished · Confidence likely
论文解读, 遥感视觉, 目标检测

论文信息

PHENet:雾天遥感为什么需要高度先验 阅读导航图

论文题目:PHENet: Toward Robust Fog-Resilient Change Detection in Remote Sensing Imagery With a Physics-Guided Height-Enhanced Network

论文任务是雾天遥感变化检测。输入两期遥感图像,输出哪些区域发生变化。作者关注的不是普通晴天场景,而是更困难的雾、霾等大气退化条件。

代码地址:https://github.com/sssy3/PHENet


核心动机:雾会制造伪变化

遥感变化检测最常见的输入是两张不同时刻的 RGB 图像。模型通过比较两期图像的颜色、纹理、边缘和语义特征,判断建筑新增、拆除或地表变化。

但在雾天,这个前提会变得不稳定。雾会造成:

  • 对比度下降;
  • 颜色偏移;
  • 边缘模糊;
  • 小目标被遮挡;
  • 两期图像雾浓度不同,从而产生伪变化。

所谓伪变化,就是地物本身没有变,但图像外观看起来变了。普通变化检测模型如果只依赖 RGB 差异,就容易把天气造成的差异误判为真实变化。

论文的关键观察是:雾会改变 RGB 外观,但不会真正改变地物高度结构。

雾天图像与估计高度图

上图第一行是雾天图像,第二行是估计高度图。高度图中越亮表示高度越高,通常对应建筑、屋顶等结构。即使雾让 RGB 图像变灰、变模糊,高度图仍然保留了相对稳定的结构轮廓。

因此,PHENet 的基本思想是:

不要只看 RGB 外观变化,而要引入高度结构信息和大气散射物理约束,帮助模型区分真实变化与雾造成的伪变化。


整体框架

PHENet 整体框架

PHENet 的输入包括四个部分:

T1 image   第一时相 RGB 图像
T2 image   第二时相 RGB 图像
T1 height  第一时相高度图
T2 height  第二时相高度图

模型由两条编码路径开始:

  • RGB 图像进入 image encoder;
  • 高度图进入 height encoder。

之后通过三个关键模块处理:

  • HAMF:Height-Aware Mixture Fusion,高度感知混合融合;
  • HED:HED-Augmented Difference Fusion,高度增强差异融合;
  • PGARM:Physics-Guided Adversarial Refinement Module,物理引导对抗细化。

其中 HAMF 负责让每一期 RGB 特征更抗雾,HED 负责比较两期 RGB 差异和高度差异,PGARM 在训练阶段引入大气散射约束。


HAMF:用高度引导频域特征增强

HAMF 模块

HAMF 解决的问题是:在比较 T1 和 T2 之前,先让每一期图像的 RGB 特征更可靠。

作者认为雾对频率成分的影响不同:

  • 低频部分容易包含大范围雾霾、亮度偏移、对比度下降;
  • 高频部分包含边缘、纹理、建筑轮廓等结构细节。

因此 HAMF 先对 RGB 特征和高度特征做 DCT 频域分解,再分别处理高频和低频,最后用高度特征做 cross-attention 引导 RGB 特征。

代码中对应的模块是 FrequencyDecompositionCrossFrequencyAttentionHAMF

class FrequencyDecomposition(nn.Module):
    def forward(self, x):
        coeff = dct_2d(x)
        bands = []
        for i in range(self.bands):
            expanded_filter = self.filters[i].repeat(C, 1, 1, 1)
            band = F.conv2d(coeff, expanded_filter, padding=3, groups=C)
            bands.append(idct_2d(band))
        return bands

这里先通过 dct_2d 把特征转到频域,然后用可学习的 depthwise filter 得到多个频带,最后通过 idct_2d 回到空间域。论文中称为高频和低频,不过代码里这两个频带是可学习得到的,不是手工固定滤波器。

高度引导注意力的实现如下:

class CrossFrequencyAttention(nn.Module):
    def forward(self, feat, height_feat):
        Q = self.query(feat).view(B, -1, H * W).permute(0, 2, 1)
        K = self.key(height_feat).view(B, -1, H * W)
        V = self.value(height_feat).view(B, -1, H * W)
        attention = F.softmax(torch.bmm(Q, K), dim=-1)
        out = torch.bmm(V, attention.permute(0, 2, 1)).view(B, C, H, W)
        return self.gamma * out + feat

这里的含义是:

Query 来自 RGB 特征
Key/Value 来自高度特征

也就是说,RGB 特征在学习“应该参考高度图中的哪些结构信息”。gamma 初始化为 0,表示训练刚开始时模块几乎不改变原特征,之后逐步学习高度引导。

HAMF 的整体代码逻辑是:

def forward(self, feats, ndsm):
    outputs = []
    for feat, block in zip(feats, self.blocks):
        h_enc = block['height_encoder'](ndsm)
        feat_low, feat_high = block['freq_decomp'](feat)
        h_low, h_high = block['freq_decomp'](h_enc)
        attn_low = block['low_attn'](feat_low, h_low)
        attn_high = block['high_attn'](feat_high, h_high)
        fused = block['fusion'](torch.cat([attn_low, attn_high], dim=1))
        outputs.append(feat + fused)
    return outputs[0], outputs[1], outputs[2]

总结一下,HAMF 的作用是:

用高度图提供稳定结构参考,在频域上抑制雾相关干扰,同时保留建筑边界和纹理信息。


HED:用高度差异辅助判断真实变化

HED 模块

HED 是这篇论文里最直接服务变化检测的模块。

它同时比较两类差异:

RGB 差异:   ΔF_t = |F_t1 - F_t2|
高度差异:  ΔF_h = |F_h1 - F_h2|

RGB 差异可能来自真实变化,也可能来自雾、光照和颜色偏移。高度差异则更偏向结构变化,因此可以作为辅助判断。

代码中 HED 对应 DifferenceFeatureExtractor

def forward(self, img1, img2, height_diff):
    img_diff = torch.abs(img1 - img2)
    img_avg = self.img_avgpool(img_diff)
    img_max = self.img_maxpool(img_diff)
    img_cat = torch.cat([img_diff, img_avg, img_max], dim=1)

    height_avg = self.height_avgpool(height_diff)
    height_max = self.height_maxpool(height_diff)
    height_cat = torch.cat([height_diff, height_avg, height_max], dim=1)

    img_feat = self.img_mlp(img_cat)
    height_feat = self.height_mlp(height_cat)
    w = height_feat + img_feat

    feat1 = img1 * (1 + w)
    feat2 = img2 * (1 + w)
    return self.fusion_conv(torch.cat([feat1, feat2, feat1 - feat2], dim=1))

这段代码对应论文中的注意力融合:

w_rgb 来自 RGB 差异
w_h   来自高度差异
w     = w_rgb + w_h

随后用 w 同时增强 T1 和 T2 特征,再拼接两期特征及其差异进行融合。

直观理解是:

RGB 变化明显,但高度没变:可能是雾造成的伪变化
RGB 和高度都变化:更可能是真实结构变化

PGARM:训练时加入大气散射物理约束

PGARM 模块

PGARM 的目标不是在推理时额外去雾,而是在训练阶段让模型学习符合雾成像规律的特征。

论文使用经典大气散射模型:

I = J · t + A · (1 - t)

其中:

  • I 是观测到的雾图;
  • J 是潜在清晰图;
  • t 是透射率;
  • A 是大气光。

代码中对应的是 SRBranch

class SRBranch(nn.Module):
    def forward(self, shallow_feat, deep_feat):
        deep_up = self.deep_up(deep_feat)
        fused = self.fusion(torch.cat([shallow_feat, deep_up], dim=1))
        fused = self.up(fused)
        t = self.t_pred(fused)
        A = self.A_pred(fused).squeeze(-1).squeeze(-1)
        A = A[:, :3]
        I_HR_hazy = self.to_rgb(fused) * t + A.view(-1, 3, 1, 1) * (1 - t)
        return I_HR_hazy, t, A

这段代码直接实现了大气散射形式。to_rgb(fused) 可以理解为预测出的清晰图相关分量,然后与透射率 t 和大气光 A 组合,得到重建雾图 I_HR_hazy

PHENet.forward() 中,PGARM 只在训练阶段运行:

if self.training:
    I_HR_hazy1, t1, A1 = self.sr_branch(FL_1, FH_1)
    I_HR_hazy2, t2, A2 = self.sr_branch(FL_2, FH_2)
    J1 = (I_HR_hazy1 - A1.view(-1, 3, 1, 1) * (1 - t1)) / (t1 + 1e-6)
    J2 = (I_HR_hazy2 - A2.view(-1, 3, 1, 1) * (1 - t2)) / (t2 + 1e-6)
else:
    I_HR_hazy1 = I_HR_hazy2 = J1 = J2 = t1 = t2 = A1 = A2 = None

这说明 PGARM 不增加推理阶段的额外负担。训练时它提供物理损失约束,推理时只保留主干变化检测路径。


主网络前向流程

把所有模块串起来,PHENet.forward() 的主要逻辑是:

FL_1, FM_1, FH_1 = self.backbone(x1)
FL_2, FM_2, FH_2 = self.backbone(x2)

FL_1, FM_1, FH_1 = self.hamf([FL_1, FM_1, FH_1], h1)
FL_2, FM_2, FH_2 = self.hamf([FL_2, FM_2, FH_2], h2)

HL_1, HM_1, HH_1 = self.h_feat([FL_1, FM_1, FH_1], h1)
HL_2, HM_2, HH_2 = self.h_feat([FL_2, FM_2, FH_2], h2)

L_Hdiff = torch.abs(HL_1 - HL_2)
M_Hdiff = torch.abs(HM_1 - HM_2)
H_Hdiff = torch.abs(HH_1 - HH_2)

attcf2 = self.conv1(self.stage2(FL_1, FL_2, L_Hdiff))
attcf3 = self.conv2(self.stage3(FM_1, FM_2, M_Hdiff))
attcf4 = self.conv3(self.stage4(FH_1, FH_2, H_Hdiff))

可以看到高度信息被用了两次:

第一次:在 HAMF 中增强每一期 RGB 特征
第二次:在 HED 中提供两期高度差异

最后模型把三尺度变化特征融合,再上采样输出变化图。

attcf34 = self.fuse4(attcf4, attcf3)
attcf234 = self.fuse3(attcf34, attcf2)

up1 = self.up1(attcf234)
block1 = self.block1(up1)
up2 = self.up2(block1)
block2 = self.block2(up2)

return self.conv(block2), ...

实验如何验证

作者在 WHU-CD 和 LEVIR-CD 上合成三种雾强度:

light-foggy
medium-foggy
heavy-foggy

评价指标包括 Precision、Recall、F1 和 IoU。

主实验结果

在 WHU-CD 上,PHENet 的 IoU 分别是:

light-foggy   88.36
medium-foggy  87.92
heavy-foggy   87.58

从轻雾到重雾只下降 0.78,说明模型对雾强度变化比较稳定。

在 LEVIR-CD 上,PHENet 的 IoU 分别是:

light-foggy   83.25
medium-foggy  83.03
heavy-foggy   82.13

这个结果说明 PHENet 不只是某个单一场景有效,而是在不同数据集和不同雾强度下都能保持较强稳定性。


可视化结果

可视化对比结果

可视化图中,重点看红色和绿色区域:

红色:误检,模型说变了但其实没变
绿色:漏检,真实变了但模型没检测出来

随着雾变重,很多方法会出现边界破碎、漏检小建筑、误把雾造成的模糊当成变化等问题。PHENet 的预测区域相对更完整,边界也更干净。

这部分验证的是:PHENet 的提升不只是表格数字更高,预测图本身也更接近真实标注。


消融实验

模块消融实验

Table V 验证了三个模块的贡献:

  • 加入 HAMF 后性能提升,说明高度引导频域增强有效;
  • 加入 HED 后继续提升,说明高度差异能帮助区分真实变化;
  • PGARM 单独使用不一定稳定,和对抗训练结合后效果更明显。

Table VI 验证物理损失权重。最终较优设置是:

λ1 = 0.2
λ2 = 0.5
λ3 = 0.5

这说明物理约束不能简单越强越好。比如透射率平滑约束过强,可能会抹掉建筑边界。


高度信息的作用与局限

高度消融与局限分析

Table VII 对比了完整 PHENet 和去掉高度图的版本。WHU-CD 上,去掉高度图后重雾 IoU 从 87.58 降到 85.31。雾越重,RGB 越不可靠,高度信息的价值越明显。

但高度信息也带来一个风险:如果高度估计错了,模型会被误导。

Fig. 9 展示了几类失败情况:

  • 建筑高度没有估出来,导致漏检;
  • 平地被误估成有高度,导致误检;
  • 相邻建筑间隙没有体现在高度图中,导致边界错误。

所以 PHENet 的优势和风险都来自高度先验:

高度准 → 抗雾能力增强
高度错 → 可能误导变化检测

这篇论文的核心思路

PHENet 最值得借鉴的不是某个单独模块,而是整体设计范式:

不要只依赖图像外观;
引入更稳定的结构先验;
再用成像物理模型约束训练;
让模型区分真实目标变化和退化造成的伪信号。

具体到这篇论文:

RGB 图像:提供颜色、纹理、语义信息
高度图:提供相对稳定的结构信息
大气散射模型:提供雾成像物理约束

三个模块分别对应三个问题:

HAMF:雾污染 RGB 特征怎么办?
HED:RGB 差异可能是假变化怎么办?
PGARM:如何让训练过程符合雾成像规律?

能否推广到医学图像或其他领域

我认为可以推广,但不能照搬高度图。真正可迁移的是这套思想:

用任务相关的物理或结构先验,约束模型不要只依赖外观纹理。

在医学图像分割中,可以建立如下类比:

遥感 RGB 图像        → CT / MRI / 超声 / 内镜图像
高度图               → 解剖结构先验 / 形状先验 / 距离图 / 多模态图像
雾退化               → 噪声 / 伪影 / 低剂量退化 / 运动模糊 / 偏置场
大气散射模型         → 医学成像物理模型
变化检测             → 分割 / 病灶检测 / 纵向变化分析

比如低剂量 CT 分割中,可以引入噪声模型或 CT 投影物理约束;MRI 分割中可以考虑 bias field、k-space 采样或多模态结构先验;超声分割中可以引入散斑噪声、阴影和声学传播相关先验。

HED 的思想尤其适合医学纵向分析,例如:

  • 治疗前后肿瘤变化检测;
  • 术前术后结构变化分析;
  • 随访 CT/MRI 中病灶进展检测;
  • 器官体积和边界变化评估。

在其他领域也有类似空间:

  • 自动驾驶:图像 + 深度 / LiDAR / 雷达,处理雨雾夜间;
  • 工业缺陷检测:图像 + 几何或材料反射先验,处理反光和纹理噪声;
  • 水下视觉:图像 + 水下成像模型,处理散射和颜色衰减;
  • 农业遥感:图像 + 地形高度 + 物候先验,处理云雾和季节变化。

推广时最关键的是三点:

  1. 辅助先验必须比原图外观更稳定;
  2. 物理模型必须真实解释图像退化或成像过程;
  3. 辅助先验质量要可靠,否则会像错误高度图一样误导模型。

总结

PHENet 这篇论文的贡献可以概括为:

在雾天遥感变化检测中,引入高度先验和大气散射物理约束,
让模型从“看起来变了”转向判断“结构上是否真的变了”。

它不是简单的图像去雾方法,也不是单纯堆叠一个额外输入模态。它把高度信息分别放进特征增强和差异判断两个阶段,又在训练中加入物理约束,形成了一个比较完整的抗雾变化检测框架。

对后续研究来说,PHENet 更有启发性的地方在于:当图像外观不可靠时,应该主动寻找更稳定的结构信号和物理规律,而不是只让网络从 RGB 纹理中硬学。


See also