2. 去鬼影算法全景概览:三大流派
HDR 合成里最让人头疼的问题是什么?我个人觉得,非「鬼影」莫属。你想想看,明明拍的是同一场景,结果合成出来人物边缘多出一层半透明的残影,或者树叶像被风吹散了一样。嗯,这就是鬼影——运动物体在多帧曝光之间位置不一致导致的。
去鬼影算法发展了这么多年,基本可以分成三大流派。我按自己的理解,把它们梳理成了一张全景图,你先看个大概。
2.1 基于光流的运动补偿法
这个流派的核心思路很直观:既然鬼影是因为物体动了,那我先把运动算出来,再把图像对齐,问题不就解决了?
具体来说,流程是这样的:
- 稠密光流估计——以参考帧为基准,计算其他帧每个像素的运动向量。我记得早期用 Farneback 光流,后来大家普遍转向 PWC-Net 或 RAFT 这类深度学习光流网络。
- 运动补偿 warp——根据光流向量,把非参考帧 warp 到参考帧坐标系下。说白了,就是把「跑偏」的像素拉回来。
- 遮挡检测与融合——运动补偿不是万能的。运动边界、新出现的物体、被遮挡的区域,光流会失效。这时候需要做遮挡掩膜,只融合可信区域。
我的经验:光流法对小位移、刚体运动效果很好。但遇到大运动、非刚性变形(比如飘动的头发、水面波纹),光流估计本身就会出错,鬼影反而更严重。我曾经在一个夜景 HDR 项目里,用 RAFT 光流做运动补偿,结果路灯下的行人被 warp 成了「面条人」——嗯,那之后我学会了加遮挡检测。
2.2 基于 PatchMatch 的纹理合成法
光流法走的是「对齐」路线,PatchMatch 则走了另一条路——「修补」。它不试图把运动物体对齐,而是直接从其他帧里找合适的纹理块,把鬼影区域「替换」掉。
PatchMatch 的核心是三个字:快、准、随机。
| 步骤 | 说明 | 我的备注 |
|---|---|---|
| 随机初始化 | 为鬼影区域的每个像素/块,随机分配一个来自其他帧的候选匹配位置 | 别小看随机,这是跳出局部最优的关键 |
| 传播 | 相邻像素的匹配结果互相「传染」,好的匹配快速扩散 | 有点像图像修复里的 inpainting 思路 |
| 随机搜索 | 在当前最佳匹配附近随机采样,尝试找到更优解 | 半径逐渐缩小,类似模拟退火 |
| 纹理合成 | 用找到的最佳匹配块,替换鬼影区域的像素 | 注意边界融合,否则会有接缝 |
避坑指南:我曾经在一个古建筑 HDR 项目里用 PatchMatch 去鬼影,结果砖墙纹理被替换成了完全不同的图案——因为 PatchMatch 只找「视觉相似」的块,不保证语义正确。所以,纹理重复区域要小心,最好结合语义分割做约束。
2.3 基于深度学习的端到端去鬼影网络
这是目前最「省心」也最「烧钱」的方案。端到端网络不显式做光流估计,也不做 PatchMatch 搜索,而是直接学习从多帧输入到无鬼影 HDR 结果的映射。
主流架构大概分这几类:
- 基于注意力机制——比如 AHDRNet,用非局部注意力让网络自己学会关注哪些区域是运动的、哪些是静止的。
- 基于可变形卷积——比如 DBCNN,用可变形卷积做隐式对齐,比光流 warp 更灵活。
- 基于 Transformer——最近 HDR-Transformer 这类工作,把多帧当成序列建模,全局感受野确实大。
我的看法:端到端网络的优势是「一个模型搞定一切」,不需要手工设计特征和规则。但代价也很明显——需要大量成对训练数据(多帧 LDR + 对应的无鬼影 HDR Ground Truth),而且模型泛化性是个玄学。我在一个室内场景测试集上跑得很好,换到户外强光场景就崩了。
2.4 三大流派对比:怎么选?
你可能会问:那我做项目时到底用哪个?嗯,我一般按这个原则来选:
| 场景特征 | 推荐流派 | 理由 |
|---|---|---|
| 小运动、刚体(如三脚架拍建筑) | 光流法 | 速度快,对齐精度高,遮挡少 |
| 大运动、复杂纹理(如人群、树叶) | PatchMatch | 不依赖运动估计,纹理替换更鲁棒 |
| 有大量训练数据、追求最佳质量 | 深度学习 | 端到端学习,上限最高 |
| 资源受限(手机端、实时) | 光流法(轻量版) | 计算量可控,工程优化成熟 |
一个小建议:实际工程中,我经常把光流法和 PatchMatch 混合使用——光流做粗对齐,PatchMatch 做细修补。这样既避免了光流在大运动区域的失效,又比纯 PatchMatch 快不少。嗯,算是一种「取长补短」吧。
好了,三大流派的全景概览就到这里。接下来我们会深入每个流派的具体实现和调试技巧。你心里先有个谱,后面遇到具体问题就知道该翻哪一页了。