传统 ISP Pipeline 全景:从 RAW 图到 YUV/JPEG 的完整流程

各位同学,今天我们来聊聊传统 ISP 的完整流程。说实话,这个 Pipeline 我摸了快十年,每次回头看都有新感悟。它就像一条流水线,把传感器捕捉的 RAW 数据,一步步加工成我们肉眼看着舒服的 YUV 或 JPEG 图像。

我刚开始做 ISP 时,总觉得这些模块是孤立的。后来踩了坑才明白——每个模块都在互相影响。你调了 AWB,可能就把 AE 的节奏打乱了。嗯,咱们今天就把这条线捋清楚。

2.1 整体流程概览

先看一张我手绘的流程图,把 ISP Pipeline 的核心模块串起来:

传统ISP Pipeline核心流程 传统ISP Pipeline核心流程 RAW 输入 (Bayer) 黑电平校正 (BLC) 镜头阴影校正 (LSC) 3A 模块 AWB · AE · AF Demosaic (去马赛克) 降噪 (Denoise) 锐化 · 色彩校正 · Gamma Sharpen · CCM · Gamma YUV / JPEG 输出 💡 关键点 3A 模块影响全局 降噪与锐化需平衡

这张图我画了很多遍。你看,从 RAW 进来,先做黑电平校正和镜头阴影补偿,然后进入 3A 模块——AWB、AE、AF 这三个家伙是 ISP 的大脑。之后才是 Demosaic、降噪、锐化、色彩校正,最后输出 YUV 或 JPEG。

核心观点:传统 ISP 是确定性的信号处理链。每个模块都有明确的数学模型。但问题在于——参数调优极其依赖经验。我见过有人调 AWB 调了一周,结果换了个 sensor 全废了。

2.2 3A 模块:ISP 的三大支柱

3A 模块是 ISP 里最让我头疼,也最让我着迷的部分。说白了,它们就是相机的「眼睛」和「大脑」。

2.2.1 自动白平衡 (AWB)

AWB 的目标很简单:让白色物体在任何光源下都呈现白色。但实现起来一点都不简单。

我做过一个项目,在荧光灯下拍出来的照片偏绿,AWB 怎么调都调不回来。后来发现是 sensor 的 R/G/B 通道响应曲线跟标准模型差太多。嗯,这里有个坑——AWB 的色温估计器必须跟 sensor 特性对齐。

常见的 AWB 方法:

  • 灰度世界法:假设场景平均色是灰色。简单,但遇到大面积纯色场景就崩。
  • 完美反射法:找场景中最亮的点作为白色参考。容易受高光干扰。
  • 色温曲线法:预标定不同色温下的 R/G、B/G 比值,查表匹配。我比较喜欢用这个,稳定。

我的经验:实际产品中,AWB 通常用混合策略。先灰度世界粗估,再用色温曲线细调。我曾经在日落场景翻过车——灰度世界把暖色当偏色给校正了,结果照片变成冷色调。后来加了场景分类器才解决。

2.2.2 自动曝光 (AE)

AE 控制 sensor 的曝光时间和增益,目标是让图像亮度落在目标区间。听起来简单,但动态范围是个大问题。

你看这个表格,不同场景的 AE 策略差异很大:

场景类型 目标亮度 (Y) 曝光策略 常见问题
室内正常光照 100-120 优先调曝光时间 闪烁 (50/60Hz)
夜景 60-80 先提增益,再延长时间 噪声放大
逆光 80-100 (人脸区域) 局部测光 + HDR 背景过曝
强光户外 120-140 缩短曝光 + ND 滤镜 高光裁切

我踩过最大的坑是 AE 收敛速度。有一次做安防摄像头,AE 从暗区切到亮区需要 2 秒才能稳定。客户直接退货。后来我加了前馈控制——根据场景切换直接给一个初始值,收敛时间降到 0.3 秒。

2.2.3 自动对焦 (AF)

AF 分两种:对比度检测和相位检测。传统 ISP 里,对比度检测用得更多。原理是找图像高频分量最大的位置——说白了,最清晰的位置就是对焦点。

但对比度 AF 有个致命问题:不知道往哪个方向转。它只能来回扫,找到峰值。我做过一个项目,AF 在低光照下反复震荡,像抽风一样。后来加了爬山算法 + 滞回比较才稳住。

注意:AF 和 AE 是耦合的。曝光变化会影响图像清晰度判断。我建议在 AF 搜索期间锁定 AE 参数,否则两个模块会打架。

2.3 Demosaic:从 Bayer 到 RGB

传感器输出的 RAW 图是 Bayer 格式——每个像素只记录 R、G、B 中的一个通道。Demosaic 的任务就是把缺失的两个通道插值出来。

最简单的办法是双线性插值。但效果嘛……边缘全是锯齿和伪色。我早期做手机摄像头时,用双线性插值拍出来的文字边缘全是彩边,被测试骂惨了。

后来换成了方向自适应插值:

  1. 先判断边缘方向(水平、垂直、对角)
  2. 沿边缘方向插值,避免跨边缘模糊
  3. 对 G 通道优先插值,因为人眼对绿色最敏感

再后来,我用了基于梯度导向的插值,效果更好。但计算量也上去了。嗯,这就是 ISP 的永恒矛盾——质量 vs 速度。

2.4 降噪与锐化:一对冤家

降噪和锐化是 ISP 里最需要平衡的两个模块。你降噪太狠,图像就糊了;你锐化太猛,噪声就放大了。说白了,它们是一对冤家。

2.4.1 降噪 (Denoise)

传统 ISP 的降噪分两步:亮度降噪和色度降噪。人眼对亮度噪声敏感,对色度噪声不敏感——所以色度降噪可以下重手。

我常用的方法:

  • 双边滤波:保边降噪,但计算量大。我在 FPGA 上实现过,一个 1080p 帧要跑 15ms。
  • 非局部均值 (NLM):效果好,但慢。适合后处理,不适合实时。
  • 小波降噪:频域处理,对高斯噪声效果好。我做过一个项目,用 3 层小波分解,降噪后 PSNR 提升了 3dB。

避坑指南:我曾经在夜景模式里把降噪强度拉满,结果星星全没了,变成一片死灰。降噪一定要保留纹理——尤其是天文摄影和医疗影像,降噪过度等于废片。

2.4.2 锐化 (Sharpen)

锐化的本质是增强高频分量。最经典的是非锐化掩模 (Unsharp Mask):

// 非锐化掩模核心逻辑
blur = gaussian_filter(image, sigma);
detail = image - blur;
sharpened = image + alpha * detail;

alpha 是锐化强度,一般取 0.5~1.5。sigma 控制锐化半径——半径越大,锐化越粗。

但这里有个坑:锐化会放大噪声。我做过一个实验,在 ISO 3200 的夜景图上做锐化,结果噪声比信号还明显。后来我加了边缘掩模——只在边缘区域做锐化,平坦区域不做。效果立竿见影。

2.5 色彩校正与 Gamma

色彩校正 (CCM) 是把 sensor 的 RGB 空间映射到标准色彩空间 (sRGB、BT.709)。说白了,就是让红色更红,蓝色更蓝。

CCM 是一个 3x3 矩阵:

R_out = a11*R_in + a12*G_in + a13*B_in
G_out = a21*R_in + a22*G_in + a23*B_in
B_out = a31*R_in + a32*G_in + a33*B_in

这个矩阵怎么来的?标定。用 24 色卡拍一张图,然后最小二乘法拟合。我做过一次标定,发现 sensor 的红色通道响应偏弱,CCM 矩阵里 a11 系数要拉到 1.8 才能校正回来。但系数太大,噪声也会被放大——嗯,又是 trade-off。

Gamma 校正就更直观了:把线性光强映射到人眼感知的非线性空间。标准 Gamma 是 2.2。但不同显示设备不一样——手机屏幕 Gamma 1.8 到 2.4 都有。我建议 ISP 输出时保留线性数据,Gamma 留给显示端处理。

2.6 输出格式:YUV 与 JPEG

最后一步,把处理好的 RGB 数据转成 YUV 或 JPEG。

  • YUV:亮度 (Y) 和色度 (UV) 分离。人眼对亮度更敏感,所以 UV 可以降采样。4:2:0 是最常见的格式——UV 分辨率只有 Y 的一半。
  • JPEG:有损压缩。核心是 DCT 变换 + 量化 + 熵编码。量化表决定了压缩比和质量——我一般用标准量化表,但遇到文字图像会调低高频量化系数,避免文字边缘模糊。

总结一下:传统 ISP Pipeline 是一条确定性很强的信号处理链。每个模块都有成熟的算法,但参数调优需要大量经验。我做了这么多年,最大的体会是——没有万能参数。同一个 sensor,白天和晚上的参数完全不同。同一个场景,不同用户偏好也不同。嗯,这就是为什么后来 AI ISP 开始介入——让网络去学这些复杂的映射关系。