首页影像百科
2026年06月23日

色彩分析工具开发日志

色彩分析工具的实现记录、Imatest 对比排查、已知风险和后续修正计划。

工具简介

色彩分析工具用于在浏览器本地分析 ColorChecker 24 色卡照片。用户上传图片后,工具通过 ROI 区域采样 24 个色块,计算色差、饱和度偏差、白平衡、曝光和噪声相关指标。

相关链接

实现方式、计算公式与参考值

本工具仿照 Imatest 的 Colorcheck 模块,通过计算分析上传色卡照片的对应色块,并与标准色块参考值比较,得到色差、饱和度、白平衡、曝光和噪声结果。

当前核心流程:

  1. 用户上传照片。
  2. 用户调整 ROI,使 6 x 4 网格对应 ColorChecker 24 个色块。
  3. 工具采样每个色块中心区域的平均 RGB。
  4. 将采样 RGB 转换到 Lab。
  5. 将采样 Lab 与标准 Lab 参考值比较。
  6. 输出 ΔE00、ΔC00、白平衡、曝光和噪声相关结果。

当前色差计算使用:

  • ΔE00:用于衡量整体色差。
  • ΔC00:用于观察色彩饱和度/色度方向的差异。

当前颜色转换链路:

sRGB -> 线性 RGB -> XYZ -> CIELAB

参考值来源于 Imatest 内置的 X-Rite default: post-Nov2014 D50 ColorChecker 图卡数据。当前项目使用 STANDARD_COLORCHECKER_LAB 作为主要参考值来源。

附件

开发日志

2026-06-23|Imatest 对比排查:曝光口径差异

修改结论

本次没有修改算法。当前结论是:网页端工具与 Imatest 的色差结果在标准参考图场景下较接近;曝光相关差异更可能来自亮度口径不一致,但这仍然是推测,需要后续通过小实验验证。

当前应优先验证的方向是:保留现有 Lab / 色差计算链路,同时为曝光相关字段新增一个更接近 Imatest Pixel 字段的 8-bit sRGB 像素亮度口径。

问题现象

网页端标准参考图结果与 Imatest summary 存在差异,尤其是曝光相关字段。

Imatest 灰阶曝光区使用 Pixel 字段,例如:

  • 19 white: 241.3
  • 22 neutral 5: 121.0
  • 24 black: 50.0

网页端当前导出的 Y_meas 使用线性亮度乘以 255。对于中灰块,线性亮度数值会显著低于 gamma 编码像素亮度。

标准参考图场景下,网页端的 Delta-E 00 / Delta-C 00 与 Imatest summary 中对应字段接近:

Patch网页端 DE00Imatest DE00网页端 DC00Imatest DC00
1 dark skin0.25950.260.25790.26
2 light skin0.17460.180.16340.17
18 cyan3.28423.293.07503.08
24 black0.50470.490.49410.48

这些数值接近是结果事实。是否完全由四舍五入造成,仍属于推测,需要更细粒度的原始计算过程验证。

排查过程

本次对比使用了三份文件:

  • Imatest 读取下载参考图的 summary CSV。
  • 网页端直接读取默认参考图导出的 CSV。
  • 网页端上传本地下载参考图导出的 CSV。

网页端默认参考图和网页端上传本地下载参考图的对比结果显示:

  • R_detected / G_detected / B_detected 一致。
  • R_ref / G_ref / B_ref 一致。
  • DE00 / DC00 一致。
  • Y_meas / Y_ref 一致。
  • 主要差异是 SampledPixels

本地上传参考图每个色块采样像素约为 33.5 万,网页端默认参考图每个色块采样像素约为 1.7 万。

Imatest summary 写明:

  • Color space: sRGB
  • Reference: X-Rite default, post-Nov2014 D50
  • Fill factor: 0.65
  • ROI WxH pixels: 8000, 5333

Imatest 表中 L-ideal / a*-ideal / b*-ideal 与项目 STANDARD_COLORCHECKER_LAB 基本对应。

基于以上事实,当前推测如下:

  • 曝光口径不一致是主要候选原因。依据是 Imatest 使用接近 gamma 编码 8-bit 像素亮度的 Pixel 字段,而网页端当前 Y_meas 使用线性亮度。
  • ROI / canvas 缩放不是当前最强候选原因。依据是网页端默认参考图与网页端本地上传参考图在 RGB、DE00、DC00、Y 字段上保持一致。
  • 参考 Lab 与色差公式目前看起来不是主要问题。依据是标准参考图场景下,网页端与 Imatest 的 Delta-E 00 / Delta-C 00 接近。

这些仍然只是当前阶段的分析,不是最终定位结论。

2026-06-23|Imatest 对齐排查:CSV 口径与前端显示对齐

修改结论

本次已完成三类轻量修改:

  1. 曝光相关字段改为使用更接近 Imatest Pixel 字段的 8-bit sRGB 像素亮度口径。
  2. CSV 导出字段改为更接近 Imatest summary 的展示顺序,先展示结果,再展示参与计算的数据,最后展示辅助参考数据。
  3. 页面色块表中的参考 RGB 显示改为 Imatest R-ref / G-ref / B-ref 小数值,避免页面与 CSV 参考值口径不一致。

当前页面主结果仍使用项目原有的未四舍五入计算结果。Delta-E 00 / Delta-C 00 公式本身没有修改。

问题现象

网页端与 Imatest 的 Delta-E 00 / Delta-C 00 已经非常接近,但部分色块仍存在约 0.01 级别差异,例如标准参考图场景下:

PatchImatest DE00网页端 DE00差异
18 cyan3.2903.284-0.006
19 white0.4700.483+0.013
24 black0.4900.505+0.015

本次对比还确认:Lab 保留 2 位后再计算、保留 3 位后再计算、以及原始未四舍五入计算三种方式中,保留 3 位与原始未四舍五入结果最接近 Imatest。保留 2 位并不能解释差异。

排查过程

本次使用网页端导出的 color-analysis-result CSV 与 Imatest summary CSV 对比。

对比结果事实:

  • R-meas / G-meas / B-meas 与 Imatest 表格在 3 位小数显示层面一致。
  • L-meas / a*-meas / b*-meas 与 Imatest 表格基本一致,典型差异约为 0.00 到 0.01。
  • L-ideal / a*-ideal / b*-ideal 与 Imatest 表格一致。
  • 因为输入 Lab 已基本一致,0.01 级别的 Delta-E 00 / Delta-C 00 差异目前不应再优先归因于 RGB 或 Lab 输入数据。

已完成的代码事实:

  • pixelLuminance 使用 0.2126729 * R + 0.7151522 * G + 0.072175 * B,不做 sRGB 线性化,用于曝光 Y19 / Y22 / Y24、CSV Pixel value / Y_meas
  • CSV 当前按以下顺序导出:Pixel valueSaturation%Delta-E 00Delta-C 00Delta-C 00(corr)WB_ERR_S_HSVL-meas / a*-meas / b*-measL-ideal / a*-ideal / b*-idealR-meas / G-meas / B-measR-ideal / G-ideal / B-idealR-ref / G-ref / B-ref
  • R-ideal / G-ideal / B-idealR-ref / G-ref / B-ref 当前写入的是本次 Imatest summary 表中的参考数据。
  • Delta-C 00(corr) 当前项目没有对应计算公式,CSV 暂时保留空列,没有伪造数据。

当前只保留以下判断:

  • 0.01 级别差异是事实。
  • RGB 与 Lab 输入基本一致是事实。
  • 差异是否来自 CIEDE2000 / Delta-C00 公式实现细节、内部精度或 Imatest 的校正项,目前仍未定位,不能下结论。

2026-06-23|噪声与 SNR 对齐:二阶去趋势版本

修改结论

本次完成噪声与 SNR 的第一版 Imatest 对齐:

  1. CSV 主表继续保留色准相关结果。
  2. CSV 下方新增独立的 Noise / SNR for gray patches 19-24 区域,输出 19-24 灰阶块的 Y-SNR(dB) / R-SNR(dB) / G-SNR(dB) / B-SNR(dB)
  3. 噪声计算改为先对采样区域做二维二阶趋势拟合,再使用残差标准差计算 SNR。
  4. 前端 SNR 模块统一显示 19-24 色块的 Y-SNR(dB)
  5. CSV 和前端增加视觉噪声名称:Omega (Total Visual Noise 1) @ L*=50

阶段性结论:色差、曝光、CSV 口径、灰阶 SNR 与前端显示已经达到基本可用状态。后续仍可以继续优化与 Imatest 的少量差异,但当前不再属于阻塞基本功能的问题。

问题现象

初版 SNR 使用采样区域内原始像素标准差计算:

SNR(dB) = 20 * log10(signal / noise)

公式本身与 Imatest 说明一致,但实拍图中网页端的 SNR 明显低于 Imatest。对比发现主要原因是网页端直接把色块内部渐变、照明不均、局部阴影也计入 noise,导致 noise 偏大。

排查过程

查阅 Imatest 噪声资料后确认:Imatest 会对色块区域的低频趋势进行处理,再计算 noise。基于该事实,本次实现了轻量二阶去趋势:

value = a + b*x + c*y + d*x*x + e*x*y + f*y*y
noise = std(value - fittedValue)
SNR(dB) = 20 * log10(signal / noise)

实拍图 D65-300LUX-1 对比结果显示,二阶去趋势后 19-24 灰阶块 SNR 已明显接近 Imatest:

指标平均绝对差最大差
Y-SNR(dB)0.17 dB0.31 dB
R-SNR(dB)0.08 dB0.21 dB
G-SNR(dB)0.17 dB0.31 dB
B-SNR(dB)0.18 dB0.52 dB

对比事实:

  • 二阶去趋势前,Y-SNR(dB) 最大差异约 6.73 dB。
  • 二阶去趋势后,Y-SNR(dB) 最大差异约 0.31 dB。
  • 这说明主要差异来自 noise 口径,而不是 SNR(dB) 公式本身。

仍需保留的限制说明:

  • 当前实现是轻量拟合版本,不声称完整复刻 Imatest 所有噪声选项。
  • Delta-C 00(corr) 当前仍未实现,CSV 保留空列。
  • Omega (Total Visual Noise 1) @ L*=50 使用项目当前视觉噪声估算逻辑,后续如需严格对齐 Imatest,需要单独继续排查。