OpenISP 模块拆解 · 第14讲:伪彩抑制 (FCS)
模块定位
FCS,即 False Color Suppression,代码位于 model/fcs.py。它利用 edge map 判断边缘强度,在强边缘附近压低色度分量,从而减少 demosaic、混叠或锐化带来的伪彩。
FCS 通常工作在 YUV 后段,重点处理 U/V,而不是重新修改 RAW 采样。
背景原理
伪彩常出现在高频边缘、细密纹理和采样极限附近。Bayer demosaic 在这些位置容易把亮度变化误解释成颜色变化,产生红绿、蓝黄彩边。锐化如果作用过强,也可能让这些彩边更明显。
FCS 的基本思路是:强边缘处的色度信息可信度较低,可以适度降低饱和度;平坦区或弱边缘处保留原色度。
openISP 实现
FCS 输入参数:
img: 三通道图像,语义上更像 U/V 色度平面或 YUV 数据。edgemap: 来自 EE 的边缘响应图。fcs_edge: 两个边缘阈值。gain: 弱边缘区域的色度保留增益。intercept: 中间区间线性函数截距。slope: 中间区间线性函数斜率。
代码按像素计算 uvgain:
text
abs(edge) <= fcs_edge[0] -> uvgain = gain
fcs_edge[0] < abs(edge) < fcs_edge[1]
-> uvgain = intercept - slope * edge
abs(edge) >= fcs_edge[1] -> uvgain = 0
然后:
text
out = uvgain * img / 256 + 128
+128 表示把色度拉回无色中性点。uvgain 越小,色度越接近 128,伪彩越弱。
参数和调试
fcs_edge[0]: 低阈值,低于它基本保留色度。fcs_edge[1]: 高阈值,高于它强力去色。gain: 弱边缘处保留色度的比例。intercept/slope: 控制中间区间的线性衰减。
调试时看黑白边缘、斜线、细栅格、文字和织物。FCS 好的时候,彩边减少但真实彩色物体边缘不会明显变灰。
与 CNF 的区别
CNF 是 RAW 前段色度噪声过滤,目标是抑制噪声型彩斑。FCS 是后段伪彩抑制,目标是处理 demosaic/锐化/混叠导致的边缘彩色伪影。
两者都可能降低色度,但触发依据和位置不同。
实现注意点
代码在中间区间使用 intercept - slope * self.edgemap[y,x],但判断条件用的是 abs(edge)。如果 edge 为负,线性项会变成加法,可能导致正负边缘行为不对称。更常见写法会使用 abs(edge) 进入线性衰减。
另外当前实现对 img[y,x,:] 三个通道都做同样操作。如果输入是完整 YUV,这会连 Y 也一起改变;从 FCS 语义看,更合理的是只处理 U/V。使用时要确认传入数据的通道含义。
学习重点
- FCS 是基于边缘强度的色度压制。
- 强边缘处伪彩风险更高,色度可信度更低。
- FCS 过强会让彩色边缘变灰。
- FCS 和 CNF 位置不同、目标不同。
面试问答
Q1: 什么是 false color?
False color 是图像中本不该出现的彩色伪影,常由 Bayer 采样、demosaic、混叠或锐化造成。
Q2: FCS 为什么参考 edge map?
伪彩常集中在强边缘和高频区域,edge map 能帮助定位这些风险位置。
Q3: FCS 和降低饱和度有什么区别?
全局降低饱和度会影响整张图;FCS 是边缘自适应,只在高风险区域压低色度。
Q4: FCS 过强会怎样?
真实彩色边缘会变灰,画面饱和度下降,局部颜色可能不自然。
Q5: 如何测试 FCS?
用黑白线条、细密纹理、斜边和高饱和边缘测试,观察彩边是否减少,同时确认真实颜色没有被过度削弱。