传感器与RAW数据:CMOS vs CCD传感器特性,Bayer阵列与RAW图格式,黑电平校正原理与实战
各位同学,咱们今天聊点实在的。传感器选型,说白了就是给相机挑“眼睛”。我见过不少项目,算法调得再好,传感器选错了,一切白搭。这一节,咱们就把CMOS和CCD那点事儿、Bayer阵列的排列逻辑、RAW数据的原始模样,以及黑电平校正这个“第一道工序”彻底讲透。
CMOS vs CCD:两种“眼睛”的较量
先问个问题:为什么现在工业相机几乎全是CMOS?CCD是不是被淘汰了?嗯,这个问题我十年前也纠结过。
简单说,CCD是“全局快门”的鼻祖,电荷逐行转移,图像均匀性好。但它的致命伤是功耗高、帧率低、成本贵。CMOS呢,每个像素自带放大器,可以做到“卷帘快门”或“全局快门”,速度快、功耗低、集成度高。但早期CMOS的噪声大、动态范围窄,被CCD压着打。
转折点在哪?我记得2015年左右,索尼的Pregius系列CMOS传感器出来,全局快门性能直接对标CCD,噪声控制得也漂亮。从那以后,工业相机市场就变天了。
核心差异速览:
- 读出方式:CCD是电荷耦合逐行读出,CMOS是每个像素独立寻址读出。
- 噪声:CCD噪声低(尤其暗场),CMOS有固定模式噪声(FPN)和行噪声。
- 帧率:CMOS碾压CCD,高分辨率下也能跑上百帧。
- 功耗:CCD需要多路高压时钟,功耗是CMOS的5-10倍。
- 成本:CCD工艺复杂,大靶面价格惊人;CMOS成本低,适合量产。
但别急着下结论。如果你做的是天文观测、高端显微镜这种对噪声极度敏感的应用,CCD依然有它的位置。工业缺陷检测嘛,我建议优先选全局快门CMOS,性价比最高。
Bayer阵列:RAW数据的“马赛克”密码
传感器本身是色盲的,它只能感知光的强度,分不清颜色。那彩色图像怎么来的?靠的是传感器表面的滤光片阵列——最常见的就是Bayer阵列。
Bayer阵列的排列规律是:RGGB。为什么绿色占一半?因为人眼对绿色最敏感。你想想看,自然界里绿色信息最多,所以传感器多采点绿光,视觉上更自然。
每个像素只记录一种颜色,那其他两种颜色怎么办?这就靠“去马赛克”(Demosaic)算法来插值。比如一个红色像素,它缺绿色和蓝色,就从周围像素“借”数据。
实战经验:我在做PCB焊点检测时,发现Bayer插值后的图像在焊点边缘会有伪彩色。后来我直接拿RAW数据做分析,绕过了插值,检测精度反而提升了。所以,做缺陷检测,尽量用RAW图,别让ISP的“美化”干扰了判断。
RAW图格式:最原始的“底片”
RAW图就是传感器输出的原始数据,没经过任何处理。它包含的信息量最大,但也最“难看”——灰蒙蒙的,动态范围很宽。
常见的RAW格式有:
- Bayer RAW:每个像素一个值,排列就是Bayer模式。
- RGB RAW:有些传感器用RGBW或RCCC阵列,但工业上还是Bayer为主。
- 单色RAW:黑白传感器,没有滤光片,每个像素就是灰度值。
RAW图的位深通常是10bit、12bit或14bit。注意,不是8bit。8bit只能表示0-255,12bit能表示0-4095。动态范围差了多少?4倍。所以,做高精度检测,12bit RAW是底线。
避坑指南:我曾经遇到一个项目,客户说“图像很暗”,我一看,他把12bit RAW当成8bit来显示,直接截断了低4位,暗部细节全丢了。记住:RAW图必须按原始位深来解析,否则信息损失不可逆。
黑电平校正:ISP的第一道工序
传感器在完全无光的情况下,输出值不是0。为什么?因为像素本身有暗电流,读出电路也有偏置。这个非零的“底噪”就是黑电平(Black Level)。
黑电平校正的目的很简单:把暗场下的输出值拉到0。否则,整个图像的亮度会偏亮,对比度也会受影响。
校正公式也很直白:
校正后像素值 = 原始像素值 - 黑电平值
但黑电平值怎么取?通常有两种方法:
- OB(Optical Black)像素:传感器边缘有一圈被遮挡的像素,它们永远接收不到光,它们的平均值就是黑电平。
- 暗场标定:盖上镜头盖,拍一张全黑图,统计全图均值。
我个人习惯用OB像素,因为它实时更新,能跟踪温度变化。暗电流随温度升高而增大,OB像素能自动补偿。
实战代码片段(Python + OpenCV):
import cv2
import numpy as np
# 假设raw_data是12bit Bayer RAW,shape=(H, W)
# OB像素位于图像左侧前64列
ob_region = raw_data[:, :64] # 取OB区域
black_level = np.mean(ob_region) # 计算黑电平
# 校正
corrected = raw_data.astype(np.float32) - black_level
corrected = np.clip(corrected, 0, 4095) # 12bit范围
corrected = corrected.astype(np.uint16)
注意,校正后可能会出现负值,必须截断到0。另外,黑电平值可能随增益变化,所以自动增益控制(AGC)开启时,黑电平也要动态调整。
知识体系总览
下面这张图,把传感器、RAW数据、黑电平校正的流程串起来了。你仔细看,每一步都有坑,每一步都影响最终图像质量。
从传感器选型开始,到Bayer阵列的排列,再到RAW数据的输出,最后到黑电平校正——每一步都决定了后续ISP处理的上限。你想想看,如果黑电平没校正好,后面的白平衡、伽马校正都会带着偏差,图像质量能好吗?
实战中的黑电平校正陷阱
最后分享一个我踩过的坑。有一次做玻璃划痕检测,图像总是有固定的竖条纹。我查了传感器数据手册,发现黑电平校正用的是固定值,没有用OB像素。但那个项目环境温度变化大,固定黑电平跟不上暗电流漂移,导致行噪声残留。
解决方案:改用OB像素实时校正,同时做行噪声滤波。从那以后,我再也不敢偷懒用固定黑电平了。
小技巧:如果你用的传感器支持,建议把OB像素区域的数据单独读出来,做滑动平均滤波,这样黑电平更稳定。另外,校正后记得检查直方图,看0值附近有没有被截断的痕迹。