
色度色域的面积
详细计算
一句话概括:把白平衡 + 色彩转换后的整幅图像像素,投影到二维色度平面,度量其色彩散布范围有多大 ,这个度量值就是
。
1、整条链路里做了什么
前面已经完成:对候选白点做了白平衡增益校正、再做了传感器 RGB→sRGB 色彩转换。现在手里是一堆转换后的 sRGB 像素 (每个像素是
三元组)。
这些像素在 "只看颜色、不看明暗" 的意义下,铺开的范围到底有多大?
因为这个范围大小,就是判断候选白点准不准的打分依据------ 颜色铺得越开,说明白点越接近真实光源。
2、关键预处理:把三维 RGB 降成二维色度
sRGB 像素是三维的,直接算体积又慢又不直观。论文和工程惯例都扔掉亮度信息,只保留色度。
最常见的两种二维色度坐标选择:
方式 A:比值色度(论文主用,和式 (2) 一脉相承)
每个像素得到二维点((r',b'))。
方式 B:xy 色度(sRGB→XYZ→xy)
每个像素得到((x,y))。
选择哪种取决于下游想怎么比。论文的
候选点本身就是
形式,所以通常用方式 A,保持同坐标系。
⚠️注意:只取未饱和像素。饱和像素的色度值被钳位、失去真实色度信息,混进去会扭曲色域形状。这就是为什么本模块(和整套 CCIC)都要求输入线性 RAW、并先剔除饱和块。
3、核心问题:怎么度量 "这堆二维点的散布范围"
这一步有三种量级递进的做法,从精确到工程近似:
做法① 凸包 + 面积(精确、概念最清晰)
把所有投影得到的色度点当作二维平面上的点集,计算它们的凸包(convex hull),再求凸多边形面积。
- 几何意义:凸包是 "能包住所有色度点的最小凸多边形",它的面积直观反映了颜色能展开到的最大范围;
- 面积公式(鞋带公式 Shoelace Formula,对凸包顶点按顺序排列后):
其中\((x_k,y_k)\)为凸包顶点,按逆时针顺序,n为顶点数,
。
优点 :数学上严谨、可解释性强,直接对应 "色域面积" 这个直观概念。 缺点:每遍历一个候选白点都要对全图像素算一次凸包,28 个候选点要算 28 遍,计算开销偏大。
做法② 二维直方图覆盖格数(论文实际采用的工程近似)
这是工程上最推荐、也最贴合 CCIC 低开销定位的做法。
不构建凸包,而是把二维色度平面划分成固定网格(bin),统计有多少个格子里落了至少一个像素:
- 把色度坐标范围
切成
的格子(例如
;
- 每个像素找到它落在哪个格子,做二维直方图累积;
- 计数非空格子的数量
,用它作为色域面积的近似:
(若要无量纲评分,直接用
即可。)
优点:单次遍历一遍像素就能完成,28 个候选点就是 28 次直方图填充,速度快、内存固定,非常适合嵌入式 / ARM 场景;
缺点:格子大小的选取会影响精度 ------ 格子太粗会高估面积(把分开的颜色并在一起),太细会低估并放大噪声。
做法③ 更粗糙的近似:色度方差 / 主成分散布
如果只需要一个 "相对打分",甚至可以不画凸包,直接用色度点的方差和 或协方差矩阵行列式 :
其中是色度点协方差矩阵的两个特征值。
优点:极快,对噪声平滑;
缺点:对离群彩色像素敏感,且不严格等于 "色域面积",只适合快速排序,不适合做论文那种精确比较。
4、为什么 "面积越大 = 白点越准"?
这一步的逻辑是理解整个色域最大化算法的钥匙:
- 候选白点接近真实光源 时:白平衡增益校正准确,中性物体保持中性,色彩转换后场景里红橙黄绿青蓝紫都能各归其位、铺展开来 → 色域面积大;
- 候选白点偏离真实光源 时:引入了系统性偏色(如整体偏蓝或偏红),大量像素被色偏挤到色度平面的某一角落 → 色域被压缩,面积变小。
论文特别针对 "通道光谱高度重叠、对角模型失效" 的廉价模组指出一个放大效应:
- 白点 CCT 过高(偏蓝)→ 图像偏红 → 像素压向红调 → 色域被压缩到红调区域;
- 白点 CCT 过低(偏红)→ 图像偏蓝 → 像素压向蓝调 → 色域被压缩到蓝调区域。
色彩转换矩阵会把这个色偏进一步放大,使得 "错误白点的色域面积" 和 "正确白点的色域面积" 差距更明显,便于区分。
5、算法循环(伪代码)
cpp
for 候选白点 i in C_CCT 集合(28个):
G_WB,i = 由候选色度 c_i=(R/G_i,B/G_i) 构造对角增益矩阵 # 式(17)
x_wb = G_WB,i · x_raw # ①白平衡校正
x_srgb = M_cam2srgb · x_wb # ②传感器RGB→sRGB
# ③剔除饱和像素,只保留有效像素
pts = [ (r/g, b/g) for (r,g,b) in x_srgb if 未饱和 ]
# ④计算色度散布面积(任选做法②,工程最常用)
S_i = 二维直方图非空格数( pts ) # 本句展开的内容
# ⑤取最大面积
S_max = max(S_i)
CCT_peak = 对应S_max的色温
# ⑥鲁棒处理(论文2.2.2末尾)
Omega = { i | S_i ≥ 0.95·S_max 且 CCT_i 介于 CCT_peak 与 CCT_GW 之间 }
if Omega 非空: CCT_GMAX = mean(Omega 的色温)
else: CCT_GMAX = CCT_peak
6、工程复现的 3 个关键坑
- 必须是线性 RAW :伽马非线性会拉伸 / 压缩色度分布,直接扭曲色域形状,
会算错。这也是 Real‑World‑11346 数据集 CCIC 性能受限的根源之一(论文 3.3 节提到)。
- 必须剔除饱和像素:饱和点色度被钳位,会制造虚假的大色域边界(或反过来污染直方图)。
- 网格 bin 大小要稳定 :28 个候选点要用同一套网格参数,否则面积不可比;建议固定M,只做相对比较
即可,不必归一化成绝对面积)。
7、一句话总结
这一步的本质是**"用图像颜色在二维色度平面上的展开范围,给候选照明白点打分"** :把每个候选白点白平衡 + 转色后的全部有效像素投影到((R/G,B/G))平面,用凸包面积(或更常用的二维直方图非空格数)度量散布范围,得到
,供下一步求\(CCT_{GMAX}\)使用 ------ 它只是压缩 CCT 搜索窗口的中间候选值,并不直接产出最终白平衡增益。