如何计算RGBA色彩空间中两种颜色之间的相似度?(当然背景颜色未知)
我需要通过为图像中的每个像素找到最佳调色板条目,将RGBA图像重新映射到RGBA颜色调色板。
在RGB颜色空间中,可以假设最相似的颜色是欧氏距离最小的颜色。但是,这种方法在RGBA中不起作用,例如,从rgba(0,0,0,0)
到rgba(0,0,0,50%)
的欧几里德距离小于rgba(100%,100%,100%,1%)
,但后者看起来要好得多。
我正在使用预乘的RGBA色彩空间:
r = r×a
g = g×a
b = b×a
我尝试过这个公式(编辑: See the answer below for better formula):
Δr² + Δg² + Δb² + 3 × Δa²
但看起来不是最佳 - 在具有半透明渐变的图像中,它会找到导致不连续/锐边的错误颜色。不透明颜色和alpha之间的线性比例看似腥。
什么是最佳公式?
*)为了简化这个问题,我忽略了误差扩散,伽玛和心理视觉色彩空间。
略有关联:如果你想在这个非欧几里德RGBA空间中找到最接近的颜色,vp-trees是最好的。
答案 0 :(得分:12)
最后,我找到了它!经过彻底的测试和实验,我的结论是:
正确的方法是计算两种颜色之间最大的可能差异 具有任何估计平均值/典型差异的公式具有不连续性的空间。
我无法找到一个计算距离的工作公式,而不会将RGBA颜色与某些背景混合。
无需考虑所有可能的背景颜色。它可以简化为每个R / G / B通道分别混合最大值和最小值:
幸运的是,当您使用预乘alpha(r = r×a
)时,与“白色”和“黑色”混合是微不足道的。
完整的公式是:
max((r₁-r₂)², (r₁-r₂ - a₁+a₂)²) +
max((g₁-g₂)², (g₁-g₂ - a₁+a₂)²) +
max((b₁-b₂)², (b₁-b₂ - a₁+a₂)²)
答案 1 :(得分:2)
几个原则:
double DistanceSquared(Color a, Color b)
{
int deltaR = a.R - b.R;
int deltaG = a.G - b.G;
int deltaB = a.B - b.B;
int deltaAlpha = a.A - B.A;
double rgbDistanceSquared = (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB) / 3;
return deltaAlpha * deltaAlpha / 2.0 + rgbDistanceSquared * a.A * b.A / (255 * 255);
}
答案 2 :(得分:1)
我的想法是在所有可能的背景颜色上进行一次积分,并对平方误差求平均值。
即。为每个组件计算(这里以红色通道为例)
从0到1的积分((r1 * a1 + rB *(1-a1)) - (r2 * a2 + rB *(1-a2)))^ 2 * drB
如果我正确计算得到:
dA=a1-a2
dRA=r1*a1-r2*a2
errorR=dRA^2+dA*dRA+dA^2/3
然后将这些加在R,G和B上。
答案 3 :(得分:1)
首先,一个非常有趣的问题:)
我没有完整的解决方案(至少现在还没有),但我们应该考虑两个明显的极端情况:
当Δa==0
问题类似于RGB空间时
当Δa==1
问题仅出现在alpha 1-dim空间上时
因此,满足该公式的公式(与您所述的公式非常相似)是:
(Δr² + Δg² + Δb²) × (1-(1-Δa)²) + Δa²
或(Δr² + Δg² + Δb²) × (1-Δa²) + Δa²
无论如何,它可能类似于(Δr² + Δg² + Δb²) × f(Δa) + Δa²
如果我是你,我会尝试使用各种RGBA对和各种背景颜色来模拟它,以找到最佳的f(Δa)
功能。不是很数学,但会给你一个足够接近的答案
答案 4 :(得分:0)
我从来没有这样做,但理论和实践表明,将图像和调色板中的RGB值转换为luminance–chrominance将帮助您找到最佳匹配。我会单独留下alpha通道,因为透明度与“看起来更好”的部分几乎没有任何关系。
这个xmass我使用开源软件为礼物做了一些photomosaics,它将原始图像的片段与图像集合相匹配。这似乎比你想要解决的问题更难。其中一个项目是metapixel。
最后,最好的选择应该是使用现有的库将图像转换为PNG等格式,您可以在其中控制调色板。