坏点校正(DPC):静态与动态坏点检测及校正强度调节
坏点校正,英文叫 Defect Pixel Correction,简称 DPC。说白了,就是处理 sensor 上那些「不听话」的像素点。有的永远亮着,有的永远暗着,还有的时好时坏。嗯,这节我们就来聊聊怎么搞定它们。
核心观点:坏点校正不是越强越好。校正过度,细节就没了;校正不足,画质就花了。关键在于「找得准、调得稳」。
3.1 坏点的两种类型
我在项目中遇到过不少 sensor,坏点问题千奇百怪。但归纳起来,就两类:
| 类型 | 定义 | 典型表现 | 处理难度 |
|---|---|---|---|
| 静态坏点 | 固定位置、固定亮度偏差 | 同一位置始终偏亮(白点)或偏暗(黑点) | 低(可离线标定) |
| 动态坏点 | 随温度、增益、曝光时间变化 | 高增益下突然冒出的亮点,低增益下消失 | 高(需实时检测) |
你想想看,静态坏点就像 sensor 出厂时的「胎记」,位置固定。动态坏点就麻烦多了,它像幽灵一样,温度一高、增益一拉就冒出来。我调过一款 1/2.3 英寸的 sensor,常温下好好的,一进 60°C 烘箱,满屏亮点。嗯,那就是典型的动态坏点。
3.2 静态坏点检测算法
静态坏点检测,我个人习惯用「离线标定 + 查表」的方式。流程很简单:
- 采集全黑帧:盖上镜头盖,拍 10~20 帧全黑图像。
- 采集全白帧:用均匀光源拍 10~20 帧过曝图像(接近饱和)。
- 统计偏差:对每个像素,计算全黑帧的均值与全白帧的均值。
- 标记坏点:全黑帧中亮度超过阈值(如 10 DN)的标记为亮点;全白帧中亮度低于阈值(如 1020 DN)的标记为暗点。
- 生成坏点表:将坐标写入 OTP 或校准文件。
我的经验:全黑帧建议多拍几帧做平均,避免随机噪声干扰。全白帧的亮度控制在饱和值的 80%~90% 比较稳妥,太接近饱和反而容易误判。
3.3 动态坏点检测算法
动态坏点没法提前标定,必须实时检测。我常用的方法是「邻域比较法」。核心思路:
- 对每个像素,取它周围 3x3 或 5x5 邻域的像素值。
- 计算邻域的中值或均值。
- 如果当前像素与邻域中值的偏差超过阈值,就判定为坏点。
举个例子,一个 3x3 的窗口:
原始像素值(假设中心像素是候选坏点):
[100, 102, 101]
[103, 250, 99 ]
[101, 100, 102]
邻域中值 = 101
中心像素 = 250
偏差 = 250 - 101 = 149
如果阈值设为 50,则判定为坏点。
为什么会这样?因为正常像素在局部区域内变化平缓,坏点则会出现「突兀」的跳变。阈值怎么设?我建议根据 sensor 的噪声水平动态调整。低增益下阈值可以设小一点,高增益下要适当放大。
注意:动态坏点检测最怕误判。图像边缘、纹理丰富区域,像素值本身变化就大,容易把正常细节当成坏点。我踩过这个坑——有一次把一条细电线上的高光点全当坏点给抹了,结果画面里电线断了。嗯,后来加了边缘保护逻辑才解决。
3.4 校正强度调节
找到坏点后,怎么修?常见方法有三种:
| 方法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 邻域均值替换 | 用周围像素的平均值替代坏点 | 实现简单,速度快 | 容易模糊细节 |
| 邻域中值替换 | 用周围像素的中值替代坏点 | 抗噪性好,不易受异常值影响 | 计算量稍大 |
| 自适应插值 | 根据边缘方向选择插值权重 | 保留边缘细节,效果最好 | 实现复杂,耗时 |
我个人习惯用「中值替换 + 自适应权重」的混合方案。具体来说:
- 先判断坏点是否在边缘区域(通过梯度检测)。
- 如果在平坦区域,直接用中值替换。
- 如果在边缘区域,沿边缘方向做加权插值。
这样既能去掉坏点,又能保住边缘。校正强度可以通过一个系数 α 来控制:
最终像素值 = (1 - α) × 原始值 + α × 校正值
α 的范围是 0~1。α=0 时不校正,α=1 时完全替换。我一般设 α=0.8~0.9,留一点原始值,避免校正痕迹太明显。
3.5 避免校正过度导致细节损失
这是 DPC 调试里最头疼的问题。校正过度,画面会变得「塑料感」——细节模糊,纹理丢失。怎么避免?
第一,加边缘保护。 检测到坏点后,先算一下它周围的梯度。如果梯度大(说明在边缘),就降低校正强度,甚至不校正。
第二,设置信度。 不是所有「疑似坏点」都要修。我习惯给每个候选坏点算一个置信度分数:
- 偏差越大,置信度越高。
- 邻域方差越小,置信度越高(平坦区域的可信度更高)。
- 只有置信度超过阈值,才执行校正。
第三,做多帧验证。 动态坏点检测时,不要单帧就下结论。连续 3~5 帧都在同一位置出现异常,再判定为坏点。这样可以避免把随机噪声当成坏点。
避坑指南:我曾经在一个项目中,把 sensor 的固定模式噪声(FPN)当成了坏点。结果校正算法把整行整列的像素都修了一遍,画面出现了明显的「网格感」。后来我加了空域滤波预处理,先把 FPN 去掉,再跑 DPC,问题就解决了。
3.6 DPC 调试流程总结
下面这张图是我自己整理的 DPC 调试流程,你可以参考:
3.7 调试中的常见问题与对策
| 问题 | 现象 | 可能原因 | 对策 |
|---|---|---|---|
| 坏点没修掉 | 画面仍有固定亮点/暗点 | 静态坏点表未更新,或动态阈值过高 | 重新标定坏点表,降低动态阈值 |
| 细节模糊 | 纹理区域被抹平 | 校正强度过大,或边缘保护不足 | 降低 α 值,增强边缘梯度检测 |
| 出现网格感 | 画面有规律性条纹 | 误将 FPN 当坏点处理 | 先做 FPN 校正,再跑 DPC |
| 动态坏点漏检 | 高增益下出现零星亮点 | 动态阈值未随增益调整 | 建立增益-阈值映射表 |
嗯,以上就是 DPC 调试的核心内容。坏点校正看似简单,但要做好、做稳,需要反复调参和验证。我建议你在调试时,多准备几组不同场景的测试图——暗场、亮场、纹理丰富的场景、边缘场景,都跑一遍,才能发现潜在问题。