《Color constancy by characterization of illumination chromaticity》之色度色域最大化算法(二)

色度色域的面积 详细计算

一句话概括:把白平衡 + 色彩转换后的整幅图像像素,投影到二维色度平面,度量其色彩散布范围有多大 ,这个度量值就是。

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),统计有多少个格子里落了至少一个像素:

  1. 把色度坐标范围切成的格子(例如;
  2. 每个像素找到它落在哪个格子,做二维直方图累积;
  3. 计数非空格子的数量 ,用它作为色域面积的近似:(若要无量纲评分,直接用即可。)

优点:单次遍历一遍像素就能完成,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 个关键坑

  1. 必须是线性 RAW :伽马非线性会拉伸 / 压缩色度分布,直接扭曲色域形状,会算错。这也是 Real‑World‑11346 数据集 CCIC 性能受限的根源之一(论文 3.3 节提到)。
  2. 必须剔除饱和像素:饱和点色度被钳位,会制造虚假的大色域边界(或反过来污染直方图)。
  3. 网格 bin 大小要稳定 :28 个候选点要用同一套网格参数,否则面积不可比;建议固定M,只做相对比较即可,不必归一化成绝对面积)。

7、一句话总结

这一步的本质是**"用图像颜色在二维色度平面上的展开范围,给候选照明白点打分"** :把每个候选白点白平衡 + 转色后的全部有效像素投影到((R/G,B/G))平面,用凸包面积(或更常用的二维直方图非空格数)度量散布范围,得到,供下一步求\(CCT_{GMAX}\)使用 ------ 它只是压缩 CCT 搜索窗口的中间候选值,并不直接产出最终白平衡增益。

相关推荐
一只小小的芙厨8 小时前
【线性DP】
学习·算法·动态规划
奋发向前wcx9 小时前
CSP-J复赛模拟赛5 王晨旭补题 2026.10.5
算法
罗湖老棍子10 小时前
C Looooops(信息学奥赛一本通- P1640)
算法·数论·同余·裴蜀定理·扩展欧几里得
飘尘13 小时前
从"算子"到"AI Infra":大模型背后看不见的那群人在忙什么
人工智能·算法·面试
夏幻灵13 小时前
每日一题:LeetCode 3:无重复字符的最长子串——滑动窗口思路详解
算法·leetcode·职场和发展
CarIise14 小时前
Java实训阶段查漏补缺复习笔记2
java·linux·算法
无忧.芙桃14 小时前
C++ 并查集详解:原理、实现与应用
c语言·c++·算法·leetcode
蛋蛋的就会顺顺的14 小时前
hot100——二叉树
java·数据结构·算法·leetcode·力扣
Code_Solitude15 小时前
c语言:二分法的完整补充
c语言·开发语言·算法
一切皆是因缘际会15 小时前
掌控信息论:同源星际通信基础理论
人工智能·算法·ai