《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 搜索窗口的中间候选值,并不直接产出最终白平衡增益。

相关推荐
钓鱼的肝1 小时前
梳理(1-5)
c++·经验分享·笔记·算法·青少年编程
HZZD_HZZD1 小时前
CSDN_批发市场水电漏损归因算法LAM的原理与落地
嵌入式硬件·物联网·算法
shirsl3 小时前
算法 Day 5 树 / 二叉树 + DFS
数据结构·python·算法
木子算法4 小时前
非凸、离散、还耦合:论文里的求解方法是一条四步流水线
人工智能·算法·目标跟踪
虚无的纽扣4 小时前
【力扣刷题】第二天:无重复字符的最长字串、移动零问题
算法·leetcode·排序算法
张祥6422889044 小时前
牛顿迭代法求解开普勒方程:从RTKLIB源码到数值分析
人工智能·算法·机器学习
Niuguangshuo4 小时前
论文解读:Deep Speech 2,工业级英中端到端 ASR 系统报告
算法·音视频·语音识别
钓鱼的肝4 小时前
csp-j-s总结(2)
c++·经验分享·笔记·算法·青少年编程
奇妙之二进制4 小时前
机器人导航路径规划算法入门(6)Dijkstra(迪杰斯特拉)算法深入解析
算法·导航