3、Bayer域处理:Bayer Pattern格式、黑电平校正(BLC)、镜头阴影校正(LSC)、坏点校正(DPC)

各位好,欢迎来到第三章。前面我们聊了传感器和色彩基础,今天要进入真正的ISP处理流水线第一站——Bayer域。

为什么叫Bayer域?说白了,这时候图像数据还是“半成品”。每个像素只记录了红、绿、蓝中的一种颜色,像马赛克一样排列。我们所有后续处理,都得先在这个原始域里把底子打好。

我个人习惯把Bayer域处理比作“打地基”。地基不稳,后面调得再好也白搭。今天我们就来拆解这四个核心模块:Bayer格式、黑电平校正、镜头阴影校正、坏点校正。

核心观点: Bayer域处理的质量,直接决定了整条ISP pipeline的上限。很多画质问题(偏色、暗角、亮点)追根溯源,都是这步没做好。

3.1 Bayer Pattern格式:传感器的“方言”

先聊聊Bayer阵列。最常见的格式是RGGB,也就是一个2x2单元里,一个红、两个绿、一个蓝。人眼对绿色最敏感,所以绿色通道采样率翻倍。

但注意,不同传感器厂商的Bayer排列可能不一样。我遇到过几次坑:项目拿到一款新传感器,默认用RGGB去解,结果画面偏紫。查了半天,发现人家是BGGR排列。

Bayer排列 第一行 第二行 常见传感器
RGGB R G R G ... G B G B ... Sony IMX系列
BGGR B G B G ... G R G R ... 部分OmniVision
GRBG G R G R ... B G B G ... 部分三星传感器
GBRG G B G B ... R G R G ... 较少见
调试技巧: 拿到新传感器,第一件事就是确认Bayer排列。拍一张均匀白板,看raw数据里哪个通道值最高。如果R通道最高,大概率是RGGB或GRBG;B通道最高则是BGGR或GBRG。再结合行方向规律就能确定。

除了排列,还有位深。常见的是10bit、12bit、14bit。位深决定了动态范围的上限。我个人建议,能选12bit就别用10bit,后期调校空间大很多。

3.2 黑电平校正(BLC):把“零”找回来

黑电平校正,名字听着玄乎,其实道理很简单。传感器在完全无光的情况下,输出并不是0,而是一个偏置值,比如64(12bit下)。这个偏置就是黑电平。

为什么要校正?你想想看,如果黑电平是64,那么暗部细节就被抬高了,画面会发灰、发雾。更严重的是,它会影响后面的白平衡和色彩校正,导致偏色。

校正公式很简单:

// 伪代码示例
for each pixel:
    corrected_pixel = raw_pixel - black_level
    if corrected_pixel < 0:
        corrected_pixel = 0

但实际项目中,黑电平不是固定值。它会随温度、增益、曝光时间变化。我做过一个项目,手机打游戏发热后,黑电平漂了4个LSB,暗部直接偏绿。

避坑指南: 我曾经在调试一款安防摄像头时,发现夜间画面有奇怪的条纹。查了两天,最后发现是BLC没做动态补偿——增益提高后,黑电平也跟着涨了,但校正值没变。结果暗部被剪裁,出现了伪轮廓。

所以,成熟的ISP方案都会提供多组黑电平校正参数,按增益分段线性插值。调试时,建议至少标定3个增益点:低增益(1x)、中增益(4x)、高增益(16x)。

3.3 镜头阴影校正(LSC):拯救“暗角”

镜头阴影,也叫暗角或亮度衰减。镜头中心光线直射传感器,亮度高;边缘光线斜射,亮度低。再加上镜头本身的cos⁴衰减,边缘可能比中心暗30%-50%。

LSC的原理就是给边缘像素乘以一个大于1的增益,把亮度补回来。但这里有个陷阱——增益不能太大,否则噪声会被放大。

LSC参数通常以网格形式存储。比如把图像分成16x16的网格,每个网格顶点存一个增益值,中间区域双线性插值。

网格位置 R通道增益 Gr通道增益 Gb通道增益 B通道增益
中心 (8,8) 1.00 1.00 1.00 1.00
左上角 (0,0) 1.45 1.38 1.40 1.50
右下角 (15,15) 1.42 1.36 1.38 1.48
调试技巧: 标定LSC时,用均匀照明的积分球或灯箱。拍一张raw图,计算每个通道的亮度分布。注意,R和B通道的衰减通常比G通道严重,因为波长越长,折射率越低,边缘衰减越明显。所以LSC要分通道做,不能一刀切。

我个人习惯,LSC校正后,边缘亮度要控制在中心亮度的95%以上。低于90%的话,边缘噪声会明显增加。如果镜头本身暗角太严重,建议先换镜头,别指望LSC硬拉。

3.4 坏点校正(DPC):消灭“星星”和“黑洞”

坏点,就是传感器上那些“不听话”的像素。有的永远亮着(亮点),有的永远黑着(暗点),还有的随机闪烁(噪点)。

坏点校正分两步:检测和替换。检测就是找出坏点,替换就是用周围正常像素的值把它填上。

检测方法主要有两种:

  • 静态坏点检测: 出厂时标定,存一张坏点坐标表。优点是准,缺点是无法应对使用中产生的新坏点。
  • 动态坏点检测: 实时判断。比如当前像素值比周围8个像素都高很多,就认为是亮点。优点是自适应,缺点是可能误判(比如拍星空)。

替换方法也有讲究:

// 中值替换示例(Bayer域)
// 假设当前坏点是R像素,取周围4个同色R像素的中值
uint16_t neighbors[4] = {pixel[-2][0], pixel[2][0], pixel[0][-2], pixel[0][2]};
// 排序取中值
uint16_t median = get_median(neighbors, 4);
corrected_pixel = median;
避坑指南: 我曾经在调试一款车载摄像头时,动态坏点检测把路上的白色车道线误判为坏点,导致车道线被抹掉。后来加了边缘保护逻辑——如果当前像素与周围像素的梯度方向一致,就不做校正。这个坑,做ADAS的朋友一定要留意。

坏点校正的阈值设置很关键。阈值设得太低,好像素被误杀,画面变模糊;阈值设得太高,坏点漏检,画面出现“星星”。我一般建议,亮点阈值设为周围平均值的3-4倍,暗点阈值设为平均值的1/4-1/3。

3.5 知识体系总览

下面这张图,把Bayer域处理的四个模块串起来了。你可以看到,数据从传感器出来,先过BLC去掉偏置,再过LSC补偿亮度,最后DPC清理坏点。每一步都在为后面的Demosaic打基础。

Bayer域处理流程框架图 Bayer域处理流水线 Sensor Raw Data 黑电平校正 (BLC) 减去偏置,恢复真实黑电平 镜头阴影校正 (LSC) 补偿边缘亮度衰减,分通道增益 坏点校正 (DPC) 检测并替换异常像素 Clean Bayer Data 注意点 • BLC需动态补偿 • LSC分通道标定 • DPC防误判 调试顺序 1. 先标定BLC 2. 再标定LSC 3. 最后做DPC