4、去马赛克(Demosaicing):双线性插值、边缘导向插值、基于深度学习的去马赛克
好,咱们进入第四章。去马赛克,英文叫 Demosaicing,是 RAW 域处理里绕不开的一步。说白了,就是把你相机传感器上那个 Bayer 阵列的「黑白灰」数据,还原成一张彩色图像。
为什么会有这一步?因为大多数 CMOS 传感器每个像素只能感知亮度,分不清颜色。得靠一个彩色滤波阵列(CFA),最常见的就是 Bayer 模式——每个像素只记录 R、G、B 中的一个通道。剩下的两个颜色去哪了?丢了。去马赛克就是把这些「丢了的颜色」给猜出来。
我刚开始接触这个模块时,觉得不就是插值嘛,有啥难的?后来被实际项目狠狠教育了一回——插值不好,满屏的伪色和锯齿,比没颜色还难看。
4.1 双线性插值:最朴素的方法
双线性插值,思路很简单:对每个缺失的颜色通道,直接用周围最近的同色像素做加权平均。权重由距离决定,越近贡献越大。
举个例子,一个 Bayer 模式的 G 通道,在 R 像素位置上是缺失的。那就取上下左右四个 G 像素,算个平均值填进去。R 和 B 通道同理,只不过采样模式不同。
核心公式(以 G 通道在 R 像素位置为例):
G(i,j) = ( G(i-1,j) + G(i+1,j) + G(i,j-1) + G(i,j+1) ) / 4
R 和 B 通道在 G 像素位置,需要取对角线方向的同色像素做平均。
这个方法的好处是快,计算量极小。坏处也很明显——它假设颜色变化是线性的,但真实场景哪有那么平滑?边缘处会糊,纹理区会出现彩色摩尔纹。
我记得有一次做手机摄像头调试,用双线性插值拍了一张百叶窗的照片,结果窗格边缘全是红蓝交替的伪色,像万花筒一样。从那以后,我对这种「省事」的算法就多留了个心眼。
| 方法 | 计算量 | 边缘质量 | 伪色控制 | 适用场景 |
|---|---|---|---|---|
| 双线性插值 | 极低 | 差(锯齿明显) | 差(伪色严重) | 低功耗、实时预览 |
| 边缘导向插值 | 中等 | 较好 | 中等 | 通用消费级相机 |
| 深度学习去马赛克 | 高 | 优秀 | 优秀 | 高端相机、后期处理 |
4.2 边缘导向插值:聪明一点的猜法
双线性插值的问题在于「一视同仁」。不管图像内容是什么,都按固定模板算。边缘导向插值就聪明多了——它会先判断当前像素是在平坦区域还是边缘上,然后沿着边缘方向插值,而不是跨过边缘。
具体怎么做?以 G 通道插值为例,先计算水平和垂直两个方向的梯度:
// 水平梯度
delta_H = |G(i,j-1) - G(i,j+1)|
// 垂直梯度
delta_V = |G(i-1,j) - G(i+1,j)|
如果 delta_H 小于 delta_V,说明水平方向更平滑,就用水平方向的 G 像素做平均。反之用垂直方向。如果两者差不多,那就回到双线性平均。
我个人的一个小技巧: 在实际工程中,梯度计算不要只看 G 通道,可以结合 R 和 B 通道的梯度做加权。比如在红色像素位置插值 G,可以同时看 R 通道的梯度,因为 R 和 G 在边缘处往往有相关性。这样能进一步减少伪色。
边缘导向插值比双线性好不少,但也不是万能的。遇到密集纹理(比如布料、头发),方向判断容易出错,还是会出现 zipper effect(拉链效应)——就是那种沿着边缘一明一暗的条纹。
我曾经在一个工业检测项目里用过边缘导向插值,拍的是电路板上的细密走线。结果算法把走线边缘误判成了平坦区域,插值出来的颜色在走线两侧出现了明显的锯齿。后来我加了一个后处理步骤——用中值滤波专门去伪色,才算勉强过关。
4.3 基于深度学习的去马赛克:让网络自己学
传统方法说到底,都是人手工设计的规则。深度学习就不一样了——它让网络从大量数据里自己学出插值的规律。
目前主流做法是用一个端到端的卷积神经网络,输入是 Bayer 模式的 RAW 图(单通道),输出是完整的 RGB 三通道图。网络结构通常包含:
- 浅层特征提取: 几个卷积层,把 Bayer 数据映射到高维特征空间
- 残差学习: 让网络学习的是「缺失的细节」,而不是直接输出整张图
- 注意力机制: 让网络关注纹理和边缘区域,平坦区域少花算力
我见过一个比较经典的网络叫 DemosaicNet,它把 Bayer 模式拆成 4 个通道(R、G1、G2、B),然后通过一个 U-Net 结构的网络做重建。效果确实好,伪色几乎看不出来,边缘也锐利。
注意: 深度学习去马赛克虽然效果好,但有两个坑:
- 训练数据要匹配传感器: 不同相机的 Bayer 模式、噪声特性、量子效率都不一样。用 A 相机数据训练的模型,直接用在 B 相机上,效果可能还不如边缘导向插值。
- 计算量问题: 手机端跑一个 U-Net 做去马赛克,功耗和延迟都不小。我见过一些方案是在 ISP 流水线里用轻量级网络(比如 MobileNet 变体)做,但精度会打折扣。
4.4 三种方法的对比与选型建议
你可能会问:那我到底该用哪种?
我的建议是看场景:
- 实时预览、低功耗设备: 双线性插值 + 一个简单的后处理去伪色,够用
- 消费级相机、手机主摄: 边缘导向插值,配合自适应中值滤波,性价比最高
- 专业摄影、后期 RAW 处理: 深度学习去马赛克,效果最好,但需要硬件支持
嗯,这里还要提一句:不管用哪种方法,去马赛克之后通常都会接一个 伪色抑制 的步骤。因为插值本质上是在「猜」,猜错了就会有颜色异常。常见的做法是用一个 3x3 或 5x5 的中值滤波,只对色度通道(Cb、Cr)做平滑,亮度通道不动,这样既能去伪色又不损失细节。
4.5 本章知识结构图
下面这张图把三种方法的核心流程和关系梳理了一下,方便你对照理解:
从这张图可以看得很清楚:三种方法共享同一个输入和输出,区别在于中间的计算策略。双线性插值最简单,边缘导向插值加了一个方向判断,深度学习则完全交给网络去学。无论选哪种,最后都建议接一个伪色抑制的后处理——这是我在多个项目里踩坑踩出来的经验。
一句话总结: 去马赛克没有银弹。低功耗场景用双线性,通用场景用边缘导向,追求极致画质上深度学习。但不管选哪个,后处理伪色抑制这一步别省。