DehazeNet全局去雾算法:给照片戴上“智能去雾眼镜”

想象一下:你戴上一副智能去雾眼镜,透过浓雾看风景。这副眼镜能自动分析整张照片的雾浓度,然后全局统一调整,让整张照片都变得清晰。这就是DehazeNet的思想!


一、核心问题:雾是什么?

雾的物理模型(大气散射模型)

科学家发现,雾天照片可以用一个简单公式表示:

观察到的图像 I(x) = J(x) × t(x) + A × (1 - t(x))

拆解理解:

I(x):我们拍到的雾蒙蒙照片(已知)
J(x):清晰的原始场景(我们想求的)
t(x):透射率(0~1,雾越浓越接近0)
A:大气光(通常是雾的亮度)

简单说:雾照片 = 清晰照片 × 透射率 + 雾的颜色 × (1-透射率)

生活比喻:

  • 像透过脏玻璃看风景

  • 玻璃越脏(透射率越低),看到的越模糊

  • DehazeNet就是智能清洁工,帮你擦干净玻璃


二、DehazeNet的核心思想

传统方法 vs DehazeNet

DehazeNet的聪明做法:

不依赖人工规则,让神经网络自己学习:
输入雾图 → 神经网络 → 输出透射率图 → 恢复清晰图

关键是:DehazeNet学的是“全局透射率”,
不是每个像素单独处理,而是看整体雾的分布规律。

三、DehazeNet网络结构:三层理解法

第一层:特征提取层(侦察兵)

# 类似侦察兵收集情报
输入:雾图(RGB三通道)
输出:多尺度特征(看到不同粗细的雾)

实现:多个并行的卷积层,用不同大小的卷积核
- 小卷积核(3×3):看细雾、薄雾
- 中卷积核(5×5):看中等雾
- 大卷积核(7×7):看厚雾、全局雾分布

第二层:特征融合层(情报分析中心)

# 把不同侦察兵的情报汇总分析
输入:多尺度特征
过程:把所有特征拼接起来,分析相互关系
输出:融合后的雾浓度特征图

关键:使用1×1卷积进行通道融合
就像指挥官把各部队报告汇总,找出规律

第三层:非线性回归层(决策指挥官)

# 做出最终判断:每个位置的透射率是多少
输入:融合后的特征
过程:多层全连接网络,全局考虑
输出:透射率图(0~1之间的值)

特点:这里用了一个特殊的激活函数BReLU
BReLU = 把输出限制在0~1之间(因为透射率只能是这个范围)

网络结构简化图:


四、DehazeNet的三大创新点

创新1:端到端学习

传统:手工设计规则 → 估计透射率 → 恢复图像
      (容易出错)    (分两步,误差累积)

DehazeNet:雾图 → 神经网络 → 透射率 → 清晰图
           (自动学习)      (一步到位,全局优化)

创新2:多尺度特征提取

就像医生诊断:
- 用放大镜看局部(小卷积核)
- 用肉眼整体看(中卷积核)
- 站远看全局(大卷积核)

结合起来,才能准确判断雾的分布

创新3:BReLU激活函数

# 传统ReLU:输出可以是0到无穷大
# 但透射率只能是0~1!

# BReLU(双边限制线性单元):
def BReLU(x):
    # 下限限制:不能小于0
    x = max(0, x)
    # 上限限制:不能大于1
    x = min(1, x)
    return x

# 物理意义:保证透射率符合现实

五、工作流程详解

完整去雾流程:

关键步骤:估计大气光A

大气光A通常是图像中最亮的像素值
(因为雾本身是白色的,会提高亮度)

DehazeNet的做法:
1. 取透射率最小的前0.1%像素
2. 在这些像素对应的原图位置中
3. 找亮度最大的值作为A

恢复清晰图像公式:

def recover_clear_image(I, t, A):
    """
    I: 雾图 (0~255)
    t: 透射率图 (0~1)
    A: 大气光值 (标量,如240)
    
    公式:J = (I - A) / t + A
    但为了防止除以0和溢出,实际:
    """
    # 限制t的最小值(如0.1),避免除以0
    t = np.maximum(t, 0.1)
    
    # 恢复清晰图像
    J = (I - A) / t[:, :, np.newaxis] + A
    
    # 限制到0~255范围
    J = np.clip(J, 0, 255)
    
    return J.astype(np.uint8)

六、DehazeNet的优势

与传统方法对比:

对比维度 传统方法(如暗通道) DehazeNet
原理 基于物理假设(暗通道先验) 数据驱动,自动学习
适应性 对天空等亮区域失效 能处理各种场景
颜色保真 容易颜色失真 颜色更自然
计算复杂度 中等 一次前向传播,速度快
需要调参 需要手动调多个参数 训练好后无需调参

实际效果示例:

场景1:城市雾景
传统方法:天空区域出现色斑
DehazeNet:天空过渡自然,建筑细节清晰

场景2:森林晨雾
传统方法:树叶边缘有光环效应
DehazeNet:细节保留完整,色彩真实

场景3:浓雾人像
传统方法:人脸颜色发青
DehazeNet:肤色恢复自然

七、DehazeNet的局限性

仍然存在的挑战:

  1. 浓雾极限:雾太浓时(能见度<50米),信息已丢失,难以完美恢复

  2. 非均匀雾:如果雾的浓度在图像中变化很大,全局假设可能不成立

  3. 夜景雾图:夜间雾的物理模型不同,需要专门训练

  4. 计算资源:虽然比一些传统方法快,但仍需要GPU加速

改进方向:

DehazeNet(2016) → AOD-Net(2017) → GridDehazeNet(2019)
      ↓                 ↓                    ↓
 端到端学习     联合估计A和t     网格状结构,处理非均匀雾

八、实战应用

使用预训练模型:

import torch
import torchvision.transforms as transforms
from PIL import Image

def dehaze_with_dehazenet(image_path, model_path):
    # 1. 加载图像
    image = Image.open(image_path).convert('RGB')
    
    # 2. 预处理
    transform = transforms.Compose([
        transforms.Resize((480, 640)),  # DehazeNet训练尺寸
        transforms.ToTensor(),
    ])
    
    input_tensor = transform(image).unsqueeze(0)  # [1, 3, H, W]
    
    # 3. 加载预训练模型
    model = DehazeNet()
    model.load_state_dict(torch.load(model_path))
    model.eval()  # 评估模式
    
    # 4. 前向传播
    with torch.no_grad():
        transmission_map = model(input_tensor)  # 得到透射率图
        
    # 5. 估计大气光
    A = estimate_atmospheric_light(input_tensor, transmission_map)
    
    # 6. 恢复清晰图像
    clear_image = recover_image(input_tensor, transmission_map, A)
    
    return clear_image, transmission_map

训练自己的DehazeNet:

class DehazeNet(nn.Module):
    def __init__(self):
        super(DehazeNet, self).__init__()
        # 特征提取层
        self.conv1 = nn.Conv2d(3, 16, 3, padding=1)
        self.conv2 = nn.Conv2d(3, 16, 5, padding=2)
        self.conv3 = nn.Conv2d(3, 16, 7, padding=3)
        
        # 特征融合层
        self.fusion = nn.Sequential(
            nn.Conv2d(48, 16, 1),  # 1×1卷积降维
            nn.ReLU(),
        )
        
        # 非线性回归层
        self.regression = nn.Sequential(
            nn.Linear(16*H*W, 128),
            nn.ReLU(),
            nn.Linear(128, H*W),  # 输出透射率图
            BReLU()  # 自定义激活函数
        )
    
    def forward(self, x):
        # 多尺度特征提取
        feat1 = F.relu(self.conv1(x))
        feat2 = F.relu(self.conv2(x))
        feat3 = F.relu(self.conv3(x))
        
        # 特征拼接
        fused = torch.cat([feat1, feat2, feat3], dim=1)
        fused = self.fusion(fused)
        
        # 展平,全连接
        batch_size = fused.size(0)
        flattened = fused.view(batch_size, -1)
        
        # 回归透射率
        transmission = self.regression(flattened)
        transmission = transmission.view(batch_size, 1, H, W)
        
        return transmission

# 自定义BReLU
class BReLU(nn.Module):
    def forward(self, x):
        return torch.clamp(x, 0, 1)  # 限制在0~1

九、DehazeNet的思想延伸

超越去雾:同一思想的其他应用

DehazeNet的核心思想是:
“用神经网络学习逆物理模型参数”

同样思想可用于:
1. 水下图像增强(学习水的吸收系数)
2. 雨滴去除(学习雨滴的遮挡模型)
3. 阴影去除(学习光照传输模型)
4. 老照片修复(学习退化模型)

与最新技术的结合:

# DehazeNet + 注意力机制
# 让网络更关注雾浓的区域

# DehazeNet + GAN(生成对抗网络)
# 用判别器判断去雾效果是否真实

# DehazeNet + 物理约束
# 在损失函数中加入物理模型约束

十、总结:DehazeNet的精髓

一句话总结:

DehazeNet = 用深度学习“猜”出雾的浓度图,然后用物理公式“算”回清晰图

三大核心:

  1. 端到端学习:不依赖人工特征,让数据说话

  2. 多尺度分析:既看局部细节,又看全局分布

  3. 物理模型指导:不是蛮力恢复,而是基于大气散射模型

使用建议:

什么时候用DehazeNet?
- 图像有均匀的雾霾
- 需要快速批量处理
- 要求颜色自然保真

什么时候考虑其他方法?
- 雾非常不均匀
- 夜景或特殊光照
- 有大量同类数据可训练专用模型

最后记住:

雾图恢复就像破案:
证据(雾图) + 物理规律(散射模型) + 智能推理(神经网络)
= 真相(清晰场景)

DehazeNet就是那个聪明的侦探,
通过全局分析,还原被雾隐藏的真相!
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐