Butteraugli的架构先明确以下命名约定:

Opsin - 视网膜感光化学物质的动力学及其即时电处理。

Xyb - 混合了 反/三色的色彩空间,X大致是红色减去绿色。Y是黄色的。B是蓝色的。xyb值是根据opsin混合计算的,而不是直接从rgb计算的。

Mask - 用于视觉的掩码(或者翻译成遮罩?)

Hf - 根据空间高频特征做的色彩建模

Lf - 根据空间低频特征做的色彩建模

Diffmap - 到集群并在图像之间构建错误图像

Blur - 平滑代码

graph LR
A[main]
B[ButteraugliDiffmap]
C[ButteraugliComparator]
D[OpsinDynamicsImage]
E[SeparateFrequencies]
F[Diffmap]
G[SeparateFrequencies]
H[DiffmapPsychoImage]
I[OpsinDynamicsImage]
A–>B
B –> C
C –> D
D –> E
B –> F
F –> I
F –> H
I –> G

其中ButteraugliComparator耗时占比32.2%,主要工作是将第0张图像进行了处理,即opsin处理和separateFrequencies变换。
其中Diffmap耗时66.9%,主要工作是将第1张图像进行了处理,处理方式跟第0张相同,然后还把这两张进行了diff运算,即OpsinDynamicsImage函数,该函数耗时占比33.3%。

关键函数分析

1
2
3
4
5
6

ButteraugliDiffmap(rgb0, rgb1, hf_asymmetry, diffmap);
rgb0: 图像1
rgb1: 图像2
hf_asymmery: 参数为1,意义不明
diffmap:传址进去,用来存储2张图像的差值
1
2
3
4
ButteraugliComparator butteraugli(rgb0_image, hf_asymmetry);
rgb0_image: 图像1
hf_asymmery: 参数为1,意义不明
用rgb0来初始化好butteraugli变量
1
2
3
4
std::vector<ImageF> xyb0 = OpsinDynamicsImage(rgb0);
此函数里,先高斯模糊了rgb0的三通道,然后修正图像gamma值。
为什么要修正gamma值,做这一步的意义是什么,是因为yuv变换到rgb时,针对红黄蓝三色不能用同一个gamma值来做变换,因为人眼对于这三色的敏感程度不同,人眼对蓝色分辨率最低,因此使用调整后的gamma值重新计算图像rgb。
该函数再重新计算出rgb后,再映射到了xyb的色彩空间上。
1
2
3
4
5
SeparateFrequencies(xsize_, ysize_, xyb0, pi0_)
- 第一步在边缘加入了更多的能量,这样边缘跟背景就能更准确的区分开
- 第二步基于在红和绿的高频通道里亮度信息的变化,来进行压缩, 即先压缩红绿的高频信息...
- 第三步将xyb的低频信息转换成val空间,这样方便后续对低频进行简单的平方和差分。
pi0传址进去,即为3步后的计算结果。
1
2
3
4
5
butteraugli.Diffmap(rgb1_image, result_image)
result_image即ButteraugliComparator处理过后的图片。
- 第一步把rgb1放进OpsinDynamicsImage进行处理,做gamma校正。
- 第二步把校正后的xyb1放进SeparateFrequencies处理,其实跟第一张图处理流程一样。
- 第三步把两张处理过的img放进DiffmapPsychoImage进行对比。
1
2
DiffmapPsychoImage(pi1, result);
这两个图像经过一系列复杂的比较之后,最终diff的结果会存储回result里。