第四章 坏点校正(DPC)

坏点校正,简称 DPC。说白了,就是处理传感器上那些「不听话」的像素点。

每个传感器都有坏点,这是物理规律。你买再贵的 sensor,也逃不掉。我刚入行时天真地以为高端 sensor 就没坏点,结果被产线数据狠狠打了脸。

核心认知: 坏点不是「有没有」的问题,而是「有多少」和「怎么修」的问题。

4.1 静态坏点检测

静态坏点,就是出厂时就存在的坏点。位置固定,亮度偏差也固定。这类坏点最好处理。

检测方法其实很直观:

  • 全黑帧检测: 盖上镜头盖,拍一张全黑图。正常像素输出应该接近 0,坏点会亮得刺眼。
  • 全白帧检测: 对着均匀光源,拍一张过曝图。正常像素输出接近饱和,坏点会暗一块。
  • 差值法: 连续拍多帧,计算每个像素的方差。方差异常的,基本就是坏点。

我习惯在产线标定阶段做静态检测。把坏点坐标存成一张表,后面直接用。

小技巧: 静态坏点表建议用 16 位坐标存储,别用 8 位。sensor 分辨率越来越大,8 位根本不够用。我吃过这个亏。

4.2 动态坏点校正

动态坏点,是使用过程中新产生的坏点。温度、电压、老化,都会催生新坏点。这类坏点位置不固定,检测起来麻烦很多。

动态检测的核心思路:看邻居。

一个正常像素,它的值和周围像素应该差不多。如果某个像素和周围 8 个邻居差距太大,那它大概率是坏点。

具体做法:

  1. 取当前像素 P(i,j) 和它的 8 邻域像素值
  2. 计算邻域的中值或均值
  3. 如果 P(i,j) 与中值的差超过阈值 T,标记为坏点
  4. 用邻域中值替换坏点
// 动态坏点检测伪代码
for each pixel (i, j) {
    neighbors = get_8_neighbors(i, j);
    median = compute_median(neighbors);
    diff = abs(pixel(i,j) - median);
    
    if (diff > threshold) {
        pixel(i,j) = median;  // 替换
        bad_pixel_count++;
    }
}

阈值 T 怎么定?我建议用自适应阈值。暗区阈值小一点,亮区阈值大一点。为什么?因为亮区的噪声本身就大,阈值太小会把正常像素误判为坏点。

避坑指南: 我曾经把阈值设得太死,结果在暗光场景下把大量正常像素当坏点修了。画面变得像磨皮过度一样,细节全没了。阈值一定要留余量。

4.3 坏点校正的工程实践

理论说完了,聊聊实际干活时要注意的事。

4.3.1 坏点校正的流程

坏点校正工程流程 传感器 RAW 数据 静态坏点表查询 动态坏点检测 坏点替换 说明:静态坏点表在标定阶段生成,运行时直接查表替换。 动态检测只针对静态表未覆盖的新生坏点,避免重复处理。 静态坏点:位置固定,亮度偏差固定 处理方式:查表替换,零开销 动态坏点:位置随机,亮度偏差不固定 处理方式:邻域检测 + 中值替换

4.3.2 坏点替换策略

替换方法 优点 缺点 适用场景
中值替换 抗噪性强,边缘保持好 计算量大一点 大多数场景
均值替换 计算快 容易模糊细节 平坦区域
插值替换 边缘方向性好 实现复杂 纹理丰富区域
相邻像素复制 最快 可能产生条纹 实时性要求极高

我个人习惯用中值替换。虽然慢一点,但效果最稳。你想想看,一个坏点周围如果有边缘,均值会模糊边缘,中值不会。

4.3.3 工程中的坑

  • 坏点扩散: 一个坏点修完,可能会影响周围像素的检测。我建议先修静态坏点,再做动态检测。
  • 阈值调优: 别指望一组阈值打天下。暗光、正常光、强光,阈值要分开调。
  • 性能优化: 动态检测要遍历每个像素,1080P 的图就是 200 万次计算。用 NEON 指令集或者 DSP 加速,别在 CPU 上硬算。
  • 边界处理: 图像边缘的像素没有完整的 8 邻域。我一般直接跳过边缘 1 行 1 列,或者用镜像填充。
血的教训: 我曾经在某个项目里,动态坏点检测没做边界处理。结果图像四边出现了一圈奇怪的条纹。排查了两天才发现是边界像素的邻域取到了无效值。从那以后,边界处理我都是第一个写。

4.3.4 坏点校正的评估指标

怎么判断 DPC 做得好不好?看三个指标:

  • 漏检率: 该修的坏点没修。画面会有亮点或暗点。
  • 误检率: 不该修的像素被修了。画面细节丢失。
  • 处理速度: 每秒能处理多少帧。实时系统要求至少 30fps。

这三个指标是互相矛盾的。漏检率低了,误检率可能就高了。怎么平衡?看产品需求。安防监控可以容忍一点误检,但医疗影像不行。

我的经验: 先保证漏检率低于 0.01%,再慢慢优化误检率。用户看到画面有亮点会直接退货,但细节稍微模糊一点,大部分人看不出来。

嗯,坏点校正就讲到这里。记住一句话:坏点校正不是把坏点修没,而是让用户看不出来有坏点。这两者区别很大,你品品。