3、鬼影检测算法总览:三类主流方法
鬼影检测,说白了就是找出多帧曝光序列里那些“不听话”的像素——它们违背了场景静止的假设。我做了这么多年HDR合成,踩过最多的坑就是鬼影检测没选对方法。今天我把三类主流思路给你捋一遍。
3.1 基于像素差异的检测
这类方法最直观。直接比较两帧之间对应像素的亮度或梯度变化。变化大的地方,就是鬼影候选区。
3.1.1 帧差法
帧差法就是逐像素算差值。我早期做监控HDR时用过这个,简单到令人发指——但坑也多。
// 伪代码:帧差法鬼影检测
for each pixel (x, y):
diff = abs(I_ref(x,y) - I_curr(x,y))
if diff > threshold:
mark as ghost candidate
else:
mark as static
帧差法的优缺点:
| 优点 | 缺点 |
|---|---|
| 计算极快,实时性高 | 对光照变化极度敏感 |
| 实现简单,容易部署 | 无法区分运动物体和曝光差异 |
| 适合静态场景 | 阈值选择困难 |
3.1.2 梯度差异法
帧差法只看亮度,梯度差异法看的是结构。你想想看,如果两帧亮度不同但边缘一致,那大概率是曝光差异,不是鬼影。梯度法能区分这个。
// 梯度差异法核心
grad_ref = sobel(I_ref)
grad_curr = sobel(I_curr)
grad_diff = |grad_ref - grad_curr|
// 结合亮度差异做决策
if grad_diff > grad_thresh AND diff > lum_thresh:
mark as ghost
我个人习惯用梯度差异法做预处理。它比帧差法鲁棒,但遇到纹理丰富的区域容易误报——树叶、水面这些地方,梯度变化本来就大。
3.2 基于特征匹配的检测
像素级方法搞不定大运动。如果场景里有行人走过、汽车开过,帧差法会检测出一大片鬼影。这时候需要特征匹配——先找图像里的关键点,再看这些点对不对得上。
3.2.1 SIFT特征点
SIFT是经典中的经典。尺度不变、旋转不变,光照变化也不怕。但说实话,SIFT太慢了。我在手机上试过,一张1200万像素的图要跑几百毫秒,根本没法实时。
// SIFT匹配流程
1. 提取参考帧和当前帧的SIFT特征点
2. 用欧氏距离做最近邻匹配
3. 用RANSAC剔除误匹配
4. 未匹配上的特征点区域 → 鬼影候选
| 特性 | SIFT | ORB |
|---|---|---|
| 尺度不变性 | 强 | 弱(需图像金字塔) |
| 旋转不变性 | 强 | 强 |
| 计算速度 | 慢 | 快(约10倍) |
| 专利限制 | 有 | 无 |
3.2.2 ORB特征点
ORB是SIFT的轻量替代。我最近几个项目都在用ORB——速度够快,精度也能接受。它用FAST检测角点,用BRIEF描述子,再搞个旋转补偿,整体效果在移动端很能打。
3.3 基于深度学习的检测
这是目前精度最高的路子。用CNN或U-Net直接学出鬼影概率图。说白了,你把一堆带鬼影和不带鬼影的图像扔给网络,让它自己学会什么是鬼影。
3.3.1 CNN方法
CNN做鬼影检测,本质是个二分类问题——每个像素是鬼影还是非鬼影。我试过用一个小型CNN做patch分类:把图像切成16×16的小块,每个块判断有没有鬼影。
// CNN鬼影检测网络结构(示意)
Input: 两帧图像堆叠 (H, W, 6)
↓
Conv3×3, 32 filters, ReLU
↓
Conv3×3, 64 filters, ReLU
↓
MaxPool 2×2
↓
Conv3×3, 128 filters, ReLU
↓
UpSampling 2×2
↓
Conv1×1, 1 filter, Sigmoid
↓
Output: 鬼影概率图 (H, W, 1)
3.3.2 U-Net方法
U-Net是CNN的升级版。它用编码器-解码器结构,加上跳跃连接,能保留更多细节。做鬼影检测时,U-Net输出的鬼影图边缘更清晰,不会像普通CNN那样糊成一片。
| 对比项 | 普通CNN | U-Net |
|---|---|---|
| 输出分辨率 | 可能降采样 | 保持原图大小 |
| 边缘保留 | 一般 | 好 |
| 参数量 | 少 | 多(约5倍) |
| 训练难度 | 容易 | 需要更多数据 |
我个人觉得,U-Net是目前鬼影检测的天花板。但代价也大——训练慢,推理慢,还得有GPU。如果你做的是离线合成,比如专业摄影后期,U-Net是首选。如果是手机实时预览,还是老老实实用ORB或者梯度法吧。
3.4 三类方法对比总结
| 维度 | 像素差异法 | 特征匹配法 | 深度学法 |
|---|---|---|---|
| 速度 | 快(<1ms) | 中(10-100ms) | 慢(>100ms) |
| 精度 | 低 | 中 | 高 |
| 光照鲁棒性 | 差 | 好 | 好 |
| 运动鲁棒性 | 差 | 中 | 好 |
| 部署难度 | 低 | 中 | 高 |
| 适用场景 | 静态场景、实时预览 | 轻度运动、移动端 | 复杂场景、离线合成 |