第2章:图像传感器与ISP基础

做车载摄像头开发这些年,我接触最多的就是图像传感器和ISP。说实话,这两个东西是车载视觉的基石。你算法再牛,传感器选不对、ISP调不好,出来的图像就是垃圾。今天咱们就聊聊CMOS vs CCD、拜耳阵列与RAW图,还有ISP Pipeline里的那些坑。

2.1 CMOS vs CCD:谁更适合车载?

先说说传感器类型。CCD和CMOS,本质都是把光信号转成电信号。但它们的架构完全不同。

CCD(电荷耦合器件):每个像素的电荷要逐行转移到输出放大器。优点是噪声低、动态范围高。但缺点也很明显——功耗大、速度慢、成本高。我记得早年做工业相机时,CCD是首选。但车载场景下,CCD基本被淘汰了。

CMOS(互补金属氧化物半导体):每个像素自带放大器,可以随机读取。功耗低、速度快、集成度高。现在车载摄像头99%都是CMOS。我参与过的项目,从100万像素到800万像素,清一色CMOS。

核心对比:

  • 功耗:CMOS比CCD低一个数量级。车载要长时间工作,散热是个大问题。
  • 速度:CMOS可以做到120fps甚至更高。CCD一般30fps就顶天了。
  • 噪声:CCD噪声更低。但CMOS这些年进步很大,加上ISP降噪,差距已经不明显。
  • 成本:CMOS便宜,CCD贵。车载要量产,成本是第一关。

我的经验:选传感器时,别只看分辨率。动态范围和信噪比更重要。车载场景下,逆光、隧道、夜间,这些才是考验传感器真功夫的地方。

2.2 拜耳阵列与RAW图

你买到的CMOS传感器,输出的原始数据叫RAW图。但RAW图不是彩色的。为什么?因为每个像素只能感知光的强度,不能感知颜色。

为了解决这个问题,传感器表面覆盖了一层彩色滤光片阵列。最常见的就是拜耳阵列(Bayer Pattern)。它用RGGB(红绿绿蓝)的排列方式,每4个像素为一组。绿色占一半,因为人眼对绿色最敏感。

我刚开始做车载时,有个同事问:为什么RAW图看起来是灰蒙蒙的?其实RAW图就是灰度图,每个像素只记录一个通道的值。要变成彩色,得靠后面的去马赛克算法。

注意:RAW图的数据格式通常是10bit或12bit。别用8bit去处理,会丢失大量细节。我曾经在项目里吃过这个亏,后来老老实实改成12bit处理。

RAW图的存储格式各家不同。常见的有:

  • Bayer RAW:最原始,每个像素一个值
  • Quad Bayer:四合一,高像素传感器常用
  • RGB-IR:带红外通道,夜视场景用

2.3 ISP Pipeline:从RAW到YUV

ISP(图像信号处理器)就是把RAW图变成人眼看得舒服的彩色图像。车载ISP Pipeline通常包含以下模块。我按处理顺序一个个说。

2.3.1 黑电平校正(Black Level Correction)

传感器在完全无光时,输出值不是0。因为电路有暗电流。黑电平校正就是减去这个偏移量。

怎么做?传感器会预留一些被遮挡的像素(光学黑区),取它们的平均值作为黑电平。然后每个像素减去这个值。

// 伪代码示例
uint16_t black_level = get_black_level_from_ob_pixels();
for (int i = 0; i < width * height; i++) {
    raw[i] = (raw[i] > black_level) ? (raw[i] - black_level) : 0;
}

避坑指南:黑电平会随温度变化。我曾经在夏天测试时发现图像偏色,查了半天,原来是黑电平没做温度补偿。后来加了查表法,问题解决。

2.3.2 去噪(Denoise)

传感器噪声主要有两种:固定模式噪声(FPN)和随机噪声。FPN可以通过黑帧减法去除。随机噪声就得靠滤波了。

车载场景下,我推荐用双边滤波非局部均值滤波。别用高斯滤波,会模糊边缘。车道线检测对边缘清晰度要求很高。

嗯,这里要注意:去噪强度不能太大。太强了,图像像油画,特征点都丢了。太弱了,噪声又影响后续算法。我一般会留一个可调参数,让算法团队自己调。

2.3.3 白平衡(White Balance)

不同光源下,白色物体看起来颜色不同。白平衡就是让白色在任何光源下都呈现白色。

经典方法是灰度世界法:假设整幅图像的平均颜色是灰色。然后计算R、G、B三个通道的增益,让平均值相等。

// 灰度世界法示例
float avg_r, avg_g, avg_b;
// 计算各通道平均值
float gain_r = avg_g / avg_r;
float gain_b = avg_g / avg_b;
// 应用增益
for each pixel:
    r_out = r_in * gain_r;
    b_out = b_in * gain_b;

车载场景的特殊性:隧道出口、树荫下,色温变化剧烈。固定白平衡不行,得用自动白平衡(AWB)。我建议用色温估计+查表法,比纯算法稳定。

2.3.4 去马赛克(Demosaic)

这是把拜耳阵列的RAW图变成全彩图的关键步骤。每个像素只有一种颜色,需要从周围像素插值出缺失的两种颜色。

最简单的双线性插值,效果一般。现在主流是自适应插值,根据边缘方向选择插值方向。还有基于深度学习的去马赛克,效果更好,但车载上算力有限,用得少。

我做过一个对比:双线性插值在边缘处会有伪彩色,自适应插值就好很多。但自适应插值计算量大,得用NEON指令集优化。

2.3.5 色彩校正(Color Correction)

传感器对颜色的响应和人眼不一样。色彩校正就是通过一个3x3矩阵,把传感器颜色空间映射到标准颜色空间(如sRGB)。

// 色彩校正矩阵
[R_out]   [a11 a12 a13]   [R_in]
[G_out] = [a21 a22 a23] * [G_in]
[B_out]   [a31 a32 a33]   [B_in]

这个矩阵怎么来?用色卡标定。我建议用24色卡,在标准光源下拍摄,然后最小二乘法拟合。别偷懒用默认矩阵,不同传感器差异很大。

注意:色彩校正矩阵会放大噪声。如果矩阵系数很大,说明传感器颜色响应差,得考虑换传感器。

2.3.6 Gamma校正(Gamma Correction)

人眼对暗部细节更敏感,对亮部不敏感。Gamma校正就是做非线性映射,让图像更符合人眼视觉特性。

标准Gamma曲线:输出 = 输入^(1/2.2)。但车载上我建议用分段Gamma。暗部用低Gamma提亮,亮部用高Gamma防止过曝。这样在隧道出口场景下,暗部和亮部细节都能保留。

// 分段Gamma示例
if (input < 0.3) {
    output = input * 2.0;  // 暗部提亮
} else if (input < 0.7) {
    output = pow(input, 1/2.2);  // 标准Gamma
} else {
    output = 0.7 + (input - 0.7) * 0.5;  // 亮部压缩
}

2.4 ISP调优实战建议

ISP调优是个细活。我总结几个经验:

  • 先调黑电平,再调白平衡。顺序不能乱,否则后面全白费。
  • 去噪和去马赛克要一起调。先降噪再去马赛克,效果更好。
  • Gamma放在最后。因为Gamma是非线性的,会影响前面的色彩校正。
  • 车载场景下,动态范围比色彩准确更重要。别为了色彩好看牺牲动态范围。

核心要点:ISP不是一步到位的。我建议先调出一版基础参数,然后拿到实车场景下测试。逆光、夜间、雨天,每个场景都要调。车载ISP,稳定比什么都重要。

好了,这一章就到这里。下一章我们聊聊车载摄像头标定,包括内参、外参、畸变校正。这些都是算法部署前必须做好的准备工作。