2362 字
12 分钟
相机是怎么识别出颜色的:聊聊 CFA 阵列与 Demosaic

传感器记录的 RAW 图像不像一张完整彩色照片。Bayer 传感器上的每个感光位置只测量红、绿、蓝中的一个通道,其余两个通道需要根据周围样本估计。

把这张单通道马赛克重建成 RGB 图像的过程叫 Demosaic(去马赛克,demosaicing)。由于最常见的 CFA 是拜耳阵列,工程上这一步也常被叫作 Debayer,两种说法指的是同一件事。你在最终照片里看到的每个彩色像素,通常包含一个实测通道和两个估计通道,本文后面两种名称都会出现。

本文讨论线性 RAW 与常见 Bayer CFA。组件使用确定性合成场景,目的是说明坐标、邻域和采样限制。手机与相机中的实现还会结合噪声模型、坏点修复、饱和检测和硬件优化。

拜耳阵列:一个位置只测一种颜色#

硅感光单元主要测量到达它的光强。工程师在感光单元上方覆盖 CFA(Color Filter Array,彩色滤光阵列),让不同位置分别测量红光、绿光或蓝光。

Bayer 阵列是最常见的一种 CFA,以 2×2 单元重复。RGGB 的基本单元是:

R G
G B

四种常见 Bayer Pattern 使用相同的颜色比例,只改变坐标原点处的相位。

Pattern2×2 单元左上角通道
RGGBR G / G BR
BGGRB G / G RB
GRBGG R / B GG
GBRGG B / R GG

组件同时加入 RYYB 和 X‑Trans 作为对照。RYYB 使用黄色滤光位置,X‑Trans 使用 6×6 重复单元;它们不是 RGGB 的坐标相位变体,后续重建也需要匹配各自的采样结构。

CFA 排列

切换 CFA Pattern

CFA Pattern
RGGB 的 6×6 阵列预览
RGRGRGGBGBGBRGRGRGGBGBGBRGRGRGGBGBGB
RGGB

左上角从 R 开始,绿色占一半。

2×2 Bayer 单元R × 1,G × 2,B × 1

2×2 Bayer 单元
RGGB
主视图固定为 6×6,切换时不会改变组件尺寸。

绿色占一半采样位置。人眼的亮度敏感度以及自然图像中的大量空间细节都与绿色附近的响应关系密切,提高绿色采样密度能在颜色信息与空间细节之间取得实用平衡。

Pattern 描述坐标相位,并不代表四种去马赛克算法。裁掉一行、旋转图像或读错元数据,都可能改变坐标原点与 Pattern 的对应关系。

为什么需要 Debayer#

以 RGGB 为例,一张 2400 万像素的 RAW 矩阵包含 2400 万个数值。每个数值只属于 R、G、B 中的一个通道,并非 2400 万组完整 RGB。

Debayer 需要完成三件事:

  1. 根据坐标与 Pattern 判断每个 RAW 数字属于哪个通道。
  2. 保留当前位置的实测值。
  3. 从邻近同色样本估计另外两个通道。

下面的 NumPy 代码把 RGGB RAW 拆成三个稀疏平面。代码使用 mask 记录有效位置,避免把真实的黑色数值 0 误认为“没有样本”。

import numpy as np
def split_rggb(raw):
"""把 RGGB RAW 拆成稀疏通道与有效位置 mask。"""
rows, columns = raw.shape
red_mask = np.zeros((rows, columns), dtype=bool)
green_mask = np.zeros_like(red_mask)
blue_mask = np.zeros_like(red_mask)
red_mask[0::2, 0::2] = True
green_mask[0::2, 1::2] = True
green_mask[1::2, 0::2] = True
blue_mask[1::2, 1::2] = True
return (
np.where(red_mask, raw, 0.0),
np.where(green_mask, raw, 0.0),
np.where(blue_mask, raw, 0.0),
(red_mask, green_mask, blue_mask),
1 collapsed line
)

Debayer 位于 RAW 处理管线的前段。点选下面任一阶段,可以看到它处理什么,以及顺序为什么重要。

RAW Pipeline

Debayer 在整条图像管线的什么位置

点击任一阶段查看作用
阶段 5 / 8

Debayer

保留实测通道,并从邻域估计每个位置缺失的两个通道。

输入
校正后的单通道马赛克
顺序说明
从这里开始,数据才从一张 RAW 矩阵变成完整 RGB 图像。

这是便于理解的典型顺序。具体 ISP 可能拆分、交换或联合执行其中部分阶段。

具体产品可能调整或联合执行部分步骤,但插值应在线性域中完成。Gamma 或强 Tone Curve 会改变平均值的物理意义。

插值算法:从复制到方向判断#

去马赛克算法需要在质量、计算量和硬件成本之间取舍。

方法做法典型问题
最近邻复制距离最近的同色样本色块、锯齿、通道错位
双线性对符合位置规则的同色邻居取平均边缘变软、假色、拉链纹
教学版方向感知比较水平与垂直变化,沿较平滑方向估计 G方向判断会受噪声、斜线和重复纹理影响
工业级算法使用更大邻域、色差模型、统计估计或学习方法计算与存储成本更高

完整的 Malvar-He-Cutler 算法使用固定的 5×5 线性滤波核。本文组件中的第三种方法只演示“先判断方向,再决定怎样平均”的思路,因此标为教学版方向感知

双线性怎样选择邻居#

双线性 Debayer 不会把周围八个数字混在一起平均。目标位置与目标通道共同决定邻域形状。

在 RGGB 的 R 位置,G 通常来自上、下、左、右四个绿色样本:

G^i,j=Gi1,j+Gi+1,j+Gi,j1+Gi,j+14\hat G_{i,j}= \frac{G_{i-1,j}+G_{i+1,j}+G_{i,j-1}+G_{i,j+1}}{4}

B 来自四个对角蓝色样本:

B^i,j=Bi1,j1+Bi1,j+1+Bi+1,j1+Bi+1,j+14\hat B_{i,j}= \frac{B_{i-1,j-1}+B_{i-1,j+1}+B_{i+1,j-1}+B_{i+1,j+1}}{4}

G 位置缺失的 R 与 B 分别来自水平或垂直方向,方向取决于当前 G 所在的 CFA 相位。

逐像素看完整计算过程#

整张图的 Debayer,就是同一套局部计算在各个坐标上重复执行。选择下面任意像素,再按步骤查看两个缺失通道从哪些位置取得样本。

逐像素演示

点击任意一格,看它怎样补齐颜色

插值算法
B已选第 6 行、第 6点击其他格可重新选择RAW 102
目标像素R 样本G 样本B 样本
1 步,共 4 步
步骤 1 / 4

这个位置实测的是 B

RAW[5, 5] 只有一个数字,另外两个通道还不存在。

BB[5, 5] = RAW[5, 5] = 102

图像边缘没有完整邻域。实验允许选择最外圈像素,并使用镜像填充:越过边界的坐标映射回图内。生产实现也可能复制边缘、缩小有效输出区域,或为边界设计专用滤波核。算法和测试代码必须采用同一种策略。

最近邻适合作为速度基线。双线性能得到更平滑的结果,但它假设局部颜色平滑变化。黑色栏杆与亮天空之间不满足这个假设,跨边缘平均会把两个物体混在一起。

同一份 RAW,不同算法会得到什么#

算法差异在高对比边缘和高频纹理上更容易观察。下面保持场景、Pattern 和显示位置不变,只切换重建方法。

整图实验

原图、RAW 和结果保持在同一个位置

测试场景
Debayer 算法
原始场景Ground truth
RAW 采样每格一个通道
重建结果双线性
现在应该看哪里

过渡更平滑,也更容易跨过边缘

平均邻居能消除块状感,但会把边界两侧混在一起,因此清晰轮廓可能变软。

平均绝对误差8.0/ 255,越低越好

小房子场景适合检查轮廓、窗框和屋顶。高频斜纹接近 CFA 的采样极限,此时误差同时来自采样丢失与插值估计。

平均绝对误差可以比较同一合成场景中的方法,但它不能代替真实图像评价。工程验证还需要观察:

  • 中性高对比边缘是否出现红、青或紫色镶边;
  • 斜线附近是否出现交替明暗的拉链纹;
  • 织物、屏幕和栅栏是否出现大尺度波纹;
  • 不同噪声强度、饱和区域和 Pattern 相位下是否稳定。

假色、拉链纹与摩尔纹#

Debayer 常见的三类问题外观相近,成因并不相同。

现象画面表现主要原因
假色(False color)中性细节旁出现错误颜色各通道采样位置不同,插值把空间变化解释成颜色变化
拉链纹(Zippering)边缘出现交替明暗或彩色小齿邻域选择或方向判断在边缘两侧反复切换
摩尔纹(Moiré)细密纹理变成大尺度波纹场景频率超过像素或 CFA 的采样能力

镜头色差、运动、传感器串扰和过强锐化也会形成彩色边缘。排查时应比较线性 RAW、不同 Debayer 结果和未锐化版本。

摩尔纹不等于伪色#

摩尔纹属于亮度或结构混叠。灰度传感器也会产生摩尔纹。Bayer 传感器在不同位置采样 R、G、B,高频混叠再叠加通道相位差,可能产生额外伪色。

摩尔纹与伪色不是同一件事

提高纹理频率,再比较灰度采样和 Bayer 分通道采样。

灰度采样结果采样稳定
纹理频率12 cy/image
奈奎斯特上限48 cy/image
当前现象采样稳定
演示图案
传感器类型

纹理仍在当前采样能力内,主要结构保持稳定。

纹理频率超过奈奎斯特上限以后,传感器已经没有记录足够的信息。更复杂的插值可以利用先验知识减少伪影,却无法保证还原唯一真值。

常见缓解手段包括:

  • 光学低通滤镜在采样前压低过高的空间频率,代价是细节变软;
  • 更高的采样分辨率提高奈奎斯特上限;
  • 像素偏移通过多次曝光获得更完整的颜色采样,但要求场景和相机保持稳定;
  • 方向感知、色差插值和学习算法利用更大上下文约束估计结果。

工程实现还要处理什么#

教学代码省略了很多工业约束。实际实现至少要明确以下项目:

  • 数据范围:减黑电平后转换到 float32,避免无符号整数差值下溢。
  • 饱和样本:饱和数值不能提供可靠的颜色比例。
  • 坏点与噪声:插值会把异常样本传播到周围输出像素。
  • Pattern 与裁剪:裁掉奇数行列、旋转或翻转后要同步更新 CFA 相位。
  • 边界策略:镜像、复制或有效区域裁剪必须与测试参考一致。
  • 验证场景:同时覆盖平坦色块、斜边、细纹、噪声、饱和区和四种 Pattern。

算法输出需要保留中间精度。不要为了让每一步“看起来合法”而反复裁剪到 0 到 1;应在管线明确要求时处理越界值。

知识小测#

用五道题检查 CFA、插值、采样限制和方向判断。

理解检查 1 / 5

一个 RGGB RAW 位置实际测到了几个颜色通道?

Debayer 的核心限制来自输入数据:一个位置只实测一个通道,算法只能根据空间相关性估计缺失信息。邻域、边界、处理域和 Pattern 相位共同决定重建结果。

相机是怎么识别出颜色的:聊聊 CFA 阵列与 Demosaic
https://blog.cloudsir.top/posts/how-debayer-reconstructs-color-v2/
作者
CloudSir
发布于
2026-08-27
许可协议
CC BY-NC-SA 4.0
一文带你搞懂直流电机驱动(新版)
Ghostty 配置

下拉加载评论