3、坏点校正(DPC):静态坏点检测、动态坏点校正、坏点表管理、调试经验
坏点校正,圈内人常叫 DPC(Defect Pixel Correction)。说白了,就是处理 sensor 上那些「不听话」的像素点。
你想想看,一颗 500 万像素的 sensor,里面有几百万个感光单元。生产过程中难免有瑕疵,有些像素对光的响应就是不对——要么一直亮着(白点),要么一直暗着(黑点),要么响应曲线跟别人不一样。这些点如果不处理,拍出来的画面就会出现星星点点的噪点,尤其在低照度下特别明显。
我入行那会儿,第一次调试一颗 200 万像素的 sensor,满屏的坏点看得我头皮发麻。后来才明白,DPC 不是简单的「把坏点抹掉」,而是一套完整的检测、校正、管理机制。
核心思路:坏点校正 = 检测(找出谁坏了)+ 校正(用邻居的值替换)+ 管理(记住谁坏过)。三者缺一不可。
3.1 静态坏点检测
静态坏点检测,处理的是 sensor 出厂时就存在的「硬伤」。这些坏点的位置是固定的,不会随温度、增益变化而改变。
我习惯把静态检测分成两步走:
- 出厂标定:在模组厂,用均匀光源照射 sensor,采集全黑和全白两帧图像。全黑帧里亮着的点就是白点,全白帧里暗着的点就是黑点。
- 阈值判定:设定一个亮度阈值,超过或低于这个阈值的像素,标记为坏点。
我的经验:阈值不要设得太死。我遇到过一批 sensor,出厂标定显示坏点率 0.01%,但用了半年后坏点率飙升到 0.5%。静态检测只能管「出生就坏」的点,管不了「后天变坏」的点——那是动态校正的事。
静态坏点检测的典型流程:
// 伪代码:静态坏点检测
for each pixel (x, y) {
// 全黑帧检测白点
if (black_frame[x][y] > white_threshold) {
mark_as_defect(x, y, "white_pixel");
}
// 全白帧检测黑点
if (white_frame[x][y] < black_threshold) {
mark_as_defect(x, y, "black_pixel");
}
}
3.2 动态坏点校正
动态坏点校正,解决的是「活着活着就坏了」的问题。sensor 用久了,受温度、电压、物理损伤影响,原本正常的像素可能突然变坏。
动态校正的核心思路是:实时检测 + 实时替换。每一帧图像进来,都要判断当前像素是不是坏点,如果是,就用周围像素的值把它「补上」。
常用的动态检测方法有两种:
| 方法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 中值滤波法 | 取 3x3 邻域的中值,与中心像素比较 | 实现简单,硬件友好 | 容易误判边缘细节 |
| 梯度检测法 | 计算水平/垂直/对角方向的梯度,判断是否异常 | 对边缘保护更好 | 计算量大,需要调参 |
我个人更推荐梯度检测法。为什么?因为中值滤波在平坦区域表现不错,但一到纹理丰富的区域,很容易把正常的边缘细节当成坏点给抹掉。我曾经调试一个监控场景,画面里有一排栅栏,中值滤波直接把栅栏的竖条纹给抹平了——画面是干净了,但细节也没了。
注意:动态校正的强度不能开太大。强度过高,画面会变得「塑料感」——边缘模糊,纹理丢失。我一般建议动态校正的强度控制在 30%~50%,剩下的交给静态坏点表去兜底。
3.3 坏点表管理
坏点表,就是 sensor 的「黑名单」。每个坏点的坐标、类型、检测时间都记在里面。
坏点表的管理,我总结了三件事:
- 存储格式:常见的格式是
(x, y, type),type 用 0 表示白点,1 表示黑点。有些方案还会记录坏点的「置信度」,防止误标。 - 动态更新:动态校正检测到的新坏点,要不要写进坏点表?我的建议是:连续 N 帧(比如 10 帧)都检测到同一个位置是坏点,才写进去。避免单帧噪声导致的误报。
- 表容量:坏点表不是无限大的。一般预留 0.1%~0.5% 的像素数作为表容量。比如 500 万像素的 sensor,坏点表预留 5000~25000 个条目就够了。
关键点:坏点表要支持「读写分离」。ISP 运行时只读表,不写表;写表操作放在后台线程,或者通过上位机工具离线更新。否则一边校正一边写表,容易出 race condition。
3.4 调试经验
调试 DPC,说白了就是跟「误判」和「漏判」做斗争。误判是把好点当坏点,画面变糊;漏判是把坏点当好点,画面有噪点。
我踩过的坑,列几个给你参考:
- 坑一:静态检测时,光源不均匀。有一回我用一个旧灯箱做标定,结果 sensor 四角亮度比中心低了 20%,导致四角大量像素被误判为坏点。后来我学乖了,标定前先测光源均匀性,不均匀就换灯箱。
- 坑二:动态校正的阈值设得太低。低照度下,噪声本身就大,阈值设低了会把噪声当成坏点。我一般建议动态校正的阈值跟增益联动——增益越高,阈值越松。
- 坑三:坏点表不更新。有些方案出厂时烧录一次坏点表,之后就再也不动了。结果 sensor 老化后,新产生的坏点没人管。我建议至少每 1000 小时做一次坏点表增量更新。
调试小技巧:调试 DPC 时,我习惯先关掉所有降噪模块,只看 DPC 的效果。这样能清楚看到哪些坏点被校正了,哪些被漏掉了。等 DPC 调好了,再开降噪——否则降噪会把 DPC 的瑕疵盖住,让你误以为调好了。
最后说一句:DPC 不是万能的。它解决的是像素级别的缺陷,解决不了 sensor 的「块状缺陷」或「行缺陷」。那些问题,得靠别的模块去处理。嗯,DPC 就聊到这儿,记住:静态检测管出生,动态校正管成长,坏点表管记忆——三管齐下,画面才能干净。