传感器偷懒了------每个像素只记录一种颜色
很多人以为相机传感器拍出来的就是一张完整的彩色照片。实际上不是。
大部分图像传感器用的是拜尔阵列(Bayer Array):每个像素只记录红、绿、蓝三种颜色中的一种。排列方式通常是RGGB标准模式------绿色通道多排了一倍,以匹配人眼对绿色更敏感的特点。
所以传感器输出的Raw数据,本质上是一张黑白格子的谜题:每个像素只有一个颜色值,其他两个颜色通道是丢失的。
**去马赛克(Demosaicing)**要做的事,就是根据相邻像素的颜色信息,把每个像素缺失的两个通道猜出来。
猜对了,画面清晰锐利。猜错了------锯齿、伪色、莫尔纹、拉链噪声,全来了。

为什么说去马赛克决定了画质上限
ISP处理的每一个后续模块------白平衡、CCM(色彩校正矩阵)、Gamma、锐化------都是在已经重建好的RGB图像上操作。
重建的质量,决定了后续所有处理的基础。
白平衡调的再好,如果去马赛克已经产生了伪色,后期怎么调也调不掉。锐化再强,如果边缘已经出现了锯齿,越锐化锯齿越明显。
去马赛克的输出质量,就是整条ISP流水线的天花板。
三类插值算法横向对比
| 算法 | 核心思路 | 画质 | 硬件资源 | 延迟 | 适用场景 |
|---|---|---|---|---|---|
| 双线性插值 | 全方向平均 | 边缘糊、伪色多 | 低(3行缓存) | 低 | 文字/图形、低端IPC |
| 边缘引导插值 | 先判方向再插值 | 边缘清晰,纹理有缺陷 | 中(3行+梯度逻辑) | 中 | 通用场景,主流方案 |
| 自适应插值 | 色差恒常性+多方向投票 | 优秀,接近理论上限 | 高(5~7行+乘加阵列) | 中高 | 高端相机、医疗影像 |
算力参考:以4K@30fps为基准,双线性插值约0.5 GMAC/s,边缘引导约2 GMAC/s,自适应插值(5×5窗口)约15-25 GMAC/s,高阶方案(如Malvar)可达40-60 GMAC/s。
从最简单的方法说起
双线性插值(Bilinear Interpolation)
这是最直接的方法。对于R通道缺失的像素,用周围最近的R像素做平均。
R点位置(R33):已知
G点位置(G32、G23、G34、G43):取四个G的平均
B点位置(B22、B24、B42、B44):取四个B的平均
优点:实现简单,FPGA只需要少量行缓存和加法器,一个cycle就出结果。
缺点:边缘糊。因为在边缘处取平均,会把两边不同颜色的像素混在一起,产生伪色。画面里有锐利的黑白条纹时,结果就是一道模糊的灰带。
边缘引导插值(Edge-Guided)
这是双线性插值的改进思路:不取全方向的平均,先判断边缘方向,只在沿着边缘的方向上插值。

优点:边缘清晰度显著提高,伪色大幅减少。硬件成本只增加了梯度计算逻辑,不需要额外的行缓存。
缺点 :45°对角线和纹理密集区域还是有缺陷,梯度方向判断会出错。VNG(Variable Number of Gradients)算法通过同时评估8个方向的梯度来改进这一缺陷,但硬件资源消耗明显增加。
自适应插值(Adaptive Interpolation)
在边缘引导的基础上,引入了色差恒常性假设:相邻像素的色差(R-G、B-G)变化平缓。
核心思路:对每个像素位置,同时评估水平和垂直方向的插值质量,选择色差变化更平缓的方向进行插值。G通道优先重建,R/B通道在G通道基础上用色差恒常性恢复。
实际做法是分两步走:
第一步:重建绿色通道
用边缘引导法估算所有像素的G值,同时计算相邻像素的色差(G-R、G-B),用色差平滑性做修正。
第二步:重建红色和蓝色通道
已知G通道之后,直接用色差插值法恢复R和B:

优点:图像质量最好,几乎看不到锯齿和伪色。
缺点:硬件实现复杂。需要完成第一步的完整G通道插值后才能开始第二步,流水线深度增加;色差修正需要额外的line buffer来缓存中间结果。资源消耗大约是边缘引导法的2~3倍。
行业补充 :商用ISP中广泛采用Malvar-He-Cutler算法(微软研究院,2004),它基于色差恒常性假设,使用5×5线性滤波器同时插值所有通道,在画质和硬件开销之间取得了较好的平衡,是目前高端相机和手机ISP中应用最广的方案之一。
与CAR模块的衔接(系列第1篇管线联动)
系列第1篇ISP全景图中,去马赛克之后紧接彩色伪影抑制(CAR)模块。
为什么要单独立CAR模块:去马赛克本身会产生拉链噪声和伪色,无论算法多好,某些场景下(密集纹理、斜边)仍会残留。CAR专门处理这些已产生的伪影,两者分工不同:
-
去马赛克:从源头减少伪影产生(保真度优先)
-
CAR:在输出端检测并压制残留伪影(观感优化)
顺序不可变:去马赛克→CAR→白平衡→CCM。CAR必须在色彩校正之前做,否则伪色会随矩阵乘法扩散到相邻色域。
FPGA实现的核心挑战

挑战一:line buffer的深度
去马赛克的输入是逐行像素流,而每个G点计算需要上下两行的信息。这意味着至少需要3行line buffer(当前行+上一行+下一行)。
4K分辨率下,单行4096个像素 × 14bit(Raw精度)× 3行 ≈ 168Kbit。彩色插值还需要更多的行缓存。实际工程中line buffer占用的BRAM比大部分ISP模块都多。
挑战二:流水线的实时性
高级去马赛克算法需要多pass执行------第一pass算G通道,第二pass重建R/B。
注意 :多pass延迟取决于具体实现方式。仅在无行缓存、依赖DDR全帧存储的架构下,才会产生整帧延迟。使用逐行流水线+行缓存的架构,多pass可以在行缓存层面重叠执行,新增延迟仅为几行像素的时间,无需等待整帧完成。
逐行处理的延迟通常是几行到十几行,逐帧处理则是一帧起步。前者损耗小,后者在某些低延迟场景(实时取景、直播)不能接受。
挑战三:方向判断的硬件化
边缘方向判断依赖梯度比较,在纹理密集区域很容易出错。硬件里做像素级自适应,不像CPU能跑复杂的迭代优化,只能用有限的计算单元做近似的方向判别。
工程技巧:使用多尺度梯度------从小区域(3×3)做快速初判,再从大区域(7×7或9×9)做投票修正。但需要注意:7×7需要7行line buffer(约50KB BRAM),9×9需要9行(约65KB),资源消耗显著增加,适用于资源充裕的场景。资源受限时可用3×3初判加5×5修正的简化方案。
挑战四:紫边(Purple Fringing)的处理
高对比度边缘处,去马赛克算法在R和B通道插值时会"溢色"到暗区,产生一条紫色或蓝色的边。这不是传感器的问题,是插值算法的工瘤。
Verilog防溢出处理示意:

应对措施:在去马赛克之后加一道紫边抑制模块,检测亮度突变的边缘,对两侧像素的R、B增益做软限制。
静态图像 vs 高速视频流的插值窗口选型
插值窗口的选型------3×3、5×5、7×7------不能只看画质,必须考虑帧率和功耗约束:
| 场景 | 推荐窗口 | 理由 |
|---|---|---|
| 4K@60fps视频 | 3×3 + 边缘引导 | 满足带宽约束下取舍画质 |
| 4K@30fps视频 | 5×5(BRAM充足时) | 画质与带宽较均衡 |
| 高帧率视频(120fps+) | 3×3(简化版) | 带宽受限,延迟敏感,画质退让 |
| 静态图像(拍照) | 5×5~7×7 | 无帧率约束,可用更高画质方案 |
| 医疗/工业检测 | 5×5以上 | 画质优先,允许较高延迟 |
注意事项
- 去马赛克和降噪的顺序
先降噪再去马赛克。因为降噪是消除传感器热噪声和读出噪声,在Raw域直接做效果最好。如果先去马赛克再降噪,噪声已经被插值扩散到相邻颜色通道,变成彩色云纹噪声,处理起来困难得多。
流程建议:Raw域降噪 → 去马赛克 → CAR → 后续处理。
- 拜尔排列不是只有RGGB
市面上还有RGBIr(加红外通道)、RCCC(红清透透清,安防专用)、RCCB(红清清蓝,低照度增强)等多种排列方式。每种排列的插值逻辑都不一样,不要用一个模板套所有sensor。
补充:RGBIr需要额外处理红外与可见光的分离;RCCC只有红色和透明通道,颜色重建依赖大量猜测;RCCB的蓝色通道稀疏,插值权重需要重新分配。使用非标准CFA时,不能直接套用RGGB的插值模板。
- 去马赛克和低通滤波的协调
去马赛克前通常会做个轻度的抗混叠低通滤波,消除传感器采样带来的频谱折叠。但滤波太强会把细节一起过滤掉。建议调参时配合测试图卡(CIPA DC-008分辨率卡),量化MTF50的衰减程度,不要凭肉眼判断。
- 算法评价不要只看PSNR
PSNR在去马赛克评价上是不够的。两个算法PSNR相近,一个边缘锐利但锯齿明显,一个边缘柔和但纹理自然,PSNR看不出来区别。建议补充感知评价:S-CIELAB色差、SSIM结构相似度、主观视觉对比。
FAQ
Q:3×3的简单去马赛克和5×5的高级去马赛克,实际差距有多大?
A:在平坦区域几乎没区别。在纹理密集区域(草地、头发、织物),差距非常明显------3×3会产生明显的拉链噪声和伪色,5×5基本看不到。如果ISP主要处理的是文字或人工图形,3×3够用。如果是自然场景,建议至少用5×5。
Q:为什么有些CMOS传感器内置去马赛克?
A:那种是相机级传感器,内部集成了ISP流水线,输出直接就是RGB格式(MIPI CSI-2),不需要外部再做去马赛克。但这种传感器的色彩参数是固定的,外部做不到sensor级的黑白电平校准和坏点补偿。要求高的场景,推荐用Raw输出+外部ISP的方案。
Q:去马赛克参数调到什么程度算合格?
A:按测试图卡的标准:灰度阶跃边缘无可见伪色、ISO 12233斜边边缘1像素内完成过渡且不产生叠影、色卡色差ΔE*ab < 5。三个条件同时满足,基本就是合格线。
Q:FPGA实现去马赛克的位宽要求?
A:对于10bit或12bit的Raw输入,建议内部计算链保持16bit(Raw数据 + 2~4bit头空间跑乘加)。最终输出时根据目标格式截断到8bit或10bit。4bit的头空间保证了中间计算不会溢位,也避免了反复的饱和钳位逻辑。
下篇预告
去马赛克重建出RGB图像只是第一步。下一层的关键是色彩校正矩阵(CCM)------传感器拍到的红绿蓝,和你眼睛看到的红绿蓝,是两码事。
什么叫线性变换的适用范围?为什么纯色块标定OK但自然场景色偏?CCM和AWB的耦合怎么解?下篇来拆。
FPGA定制开发、项目调试、IP定制。需要开发服务可私。