4、基于深度学习的夜景增强:低光照图像增强网络与暗光目标检测的联合优化
说实话,传统图像增强做到极致,也就那样了。你想想看,直方图均衡化再怎么调,也补不回暗部丢失的纹理细节。Retinex 模型虽然经典,但遇到极端低光照场景,分解出来的反射分量还是会有大量噪声。
所以这一章,我们聊聊深度学习怎么解决这个问题。我个人习惯把这类方法分成两派:一派是端到端的像素回归网络,比如 LLNet;另一派是零参考的曲线估计网络,比如 Zero-DCE。它们各有各的脾气,适配移动端时也各有各的坑。
4.1 LLNet:从暗到亮的端到端映射
LLNet 的思路很直接——把低光照图像直接映射到正常光照图像。它用的是堆叠的稀疏去噪自编码器,结构上有点像 U-Net 的早期版本。
我在项目中遇到过一个问题:LLNet 训练时需要成对的低光/正常光数据。但真实场景下,同一场景拍两张曝光不同的照片,对齐误差非常大。后来我们改用合成数据——用 RAW 域模拟不同曝光时间,再转成 sRGB 训练,效果反而更稳定。
LLNet 的损失函数一般长这样:
L = α · L_MSE + β · L_SSIM + γ · L_perceptual
其中 L_MSE 是像素级均方误差,L_SSIM 保证结构相似性,L_perceptual 用预训练 VGG 的特征图做感知损失。嗯,这里要注意:L_MSE 权重不能太大,否则输出会偏灰,像蒙了一层雾。
| 组件 | 作用 | 移动端适配建议 |
|---|---|---|
| 编码器 | 提取暗部特征,抑制噪声 | 用 Depthwise Conv 替代标准 Conv |
| 解码器 | 重建亮度与细节 | 减少上采样层数,用 PixelShuffle |
| 跳跃连接 | 保留高频边缘信息 | 只保留前两层跳跃连接,减少计算量 |
4.2 Zero-DCE:没有参考图也能增强
Zero-DCE 是我个人非常欣赏的一个工作。它不需要成对数据,而是通过一系列轻量级的曲线估计网络,对输入图像做逐像素的亮度曲线调整。
说白了,它学的是「怎么调曲线」,而不是「目标长什么样」。这个思路在移动端特别友好——模型小,推理快,而且不会出现 LLNet 那种「把黑夜变成黄昏」的色偏问题。
Zero-DCE 的损失函数由四部分组成:
- 空间一致性损失:保持相邻像素的亮度关系不变
- 曝光控制损失:把平均亮度拉到 0.6 左右(RGB 空间)
- 颜色恒常性损失:防止颜色偏移,保持 RGB 三通道的比例
- 光照平滑损失:让曲线变化不要太剧烈,避免出现光晕
我曾经踩过一个坑:曝光控制损失的权重设得太高,结果画面整体发白,像过曝了一样。后来我把目标亮度从 0.6 降到 0.45,配合颜色恒常性损失,效果才自然起来。
4.3 暗光目标检测与分割的联合优化
增强完图像,下一步就是做检测和分割。但这里有个矛盾:增强网络会改变图像的统计分布,而检测网络是在正常光照数据上训练的。直接串联两个网络,精度反而可能下降。
我建议的做法是联合微调(Joint Fine-tuning)。把增强网络和检测网络拼在一起,用检测任务的损失反向传播到增强网络。这样增强网络会主动为检测任务保留关键特征,而不是追求人眼看起来舒服的效果。
对于分割任务,情况类似。我推荐使用多任务损失联合训练:
L_total = λ₁ · L_enhance + λ₂ · L_detect + λ₃ · L_segment
λ 的取值需要根据任务优先级调整。如果检测是主任务,λ₂ 可以设到 1.0,λ₁ 和 λ₃ 设到 0.1 左右。
4.4 移动端适配的关键点
把深度学习增强网络搬到手机上,有几个绕不开的坎:
- 模型量化:INT8 量化后,Zero-DCE 的曲线估计精度会下降,输出出现带状伪影。我建议对曲线参数做逐层量化校准,或者保留最后一层为 FP16。
- NPU 部署:LLNet 的跳跃连接在 NPU 上可能不被支持,需要手动改写为 concat + conv 的组合。
- 帧率要求:实时夜景增强至少需要 30fps。在 1080p 分辨率下,模型推理时间不能超过 33ms。Zero-DCE 的轻量版可以做到,LLNet 需要大幅裁剪通道数。