33

如何计算 RGBA 颜色空间中两种颜色之间的相似度?(当然背景颜色是未知的)

我需要通过为图像中的每个像素找到最佳调色板条目来将 RGBA 图像重新映射到 RGBA 颜色调色板*。

在 RGB 颜色空间中,可以假定最相似的颜色是欧几里得距离最小的颜色。但是,这种方法在 RGBA 中不起作用,例如,从rgba(0,0,0,0)to的欧几里得距离rgba(0,0,0,50%)小于 to rgba(100%,100%,100%,1%),但后者看起来要好得多。

我正在使用预乘 RGBA 颜色空间:

r = r×a
g = g×a
b = b×a

我已经尝试过这个公式(编辑: 请参阅下面的答案以获得更好的公式):

Δr² + Δg² + Δb² + 3 × Δa²

但它看起来并不理想——在具有半透明渐变的图像中,它会发现导致不连续/锐边的错误颜色。不透明颜色和 alpha 之间的线性比例看起来很可疑。

最佳配方是什么?


*) 为简单起见,我忽略了误差扩散、伽马和心理视觉色彩空间。


稍微相关:如果你想在这个非欧几里得 RGBA 空间中找到最接近的颜色,vp-trees是最好的。

4

5 回答 5

18

Finally, I've found it! After thorough testing and experimentation my conclusions are:

  • The correct way is to calculate maximum possible difference between the two colors.
    Formulas with any kind of estimated average/typical difference had room for discontinuities.

  • I was unable to find a working formula that calculates the distance without blending RGBA colors with some backgrounds.

  • There is no need to take every possible background color into account. It can be simplified down to blending maximum and minimum separately for each of R/G/B channels:

    1. blend the channel in both colors with channel=0 as the background, measure squared difference
    2. blend the channel in both colors with channel=max as the background, measure squared difference
    3. take higher of the two.

Fortunately blending with "white" and "black" is trivial when you use premultiplied alpha.

The complete formula for premultiplied alpha color space is:

rgb *= a // colors must be premultiplied
max((r₁-r₂)², (r₁-r₂ - a₁+a₂)²) +
max((g₁-g₂)², (g₁-g₂ - a₁+a₂)²) +
max((b₁-b₂)², (b₁-b₂ - a₁+a₂)²)

C Source including SSE2 implementation.

于 2012-01-09T23:57:31.050 回答
3

Several principles:

  1. When two colors have same alpha, rgbaDistance = rgbDistance * ( alpha / 255). Compatible with RGB color distance algorithm when both alpha are 255.
  2. All Colors with very low alpha are similar.
  3. The rgbaDistance between two colors with same RGB is linearly dependent on delta Alpha.
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.0;
    return deltaAlpha * deltaAlpha / 2.0 + rgbDistanceSquared * a.A * b.A / (255 * 255);
}
于 2017-12-01T03:53:35.613 回答
1

My idea is integrating once over all possible background colors and averaging the square error.

i.e. for each component calculate(using red channel as example here)

Integral from 0 to 1 ((r1*a1+rB*(1-a1))-(r2*a2+rB*(1-a2)))^2*drB

which if I calculated correctly evaluates to:

dA=a1-a2
dRA=r1*a1-r2*a2
errorR=dRA^2+dA*dRA+dA^2/3

And then sum these over R, G and B.

于 2011-01-21T13:20:22.797 回答
1

First of all, a very interesting problem :)
I don't have a full solution (at least not yet), but there are 2 obvious extreme cases we should consider:
When Δa==0 the problem is similiar to RGB space
When Δa==1 the problem is only on the alpha 1-dim space
So the formula (which is very similar to the one you stated) that would satisfy that is:
(Δr² + Δg² + Δb²) × (1-(1-Δa)²) + Δa² or (Δr² + Δg² + Δb²) × (1-Δa²) + Δa²

In any case, it would probably be something like (Δr² + Δg² + Δb²) × f(Δa) + Δa²

If I were you, I would try to simulate it with various RGBA pairs and various background colors to find the best f(Δa) function. Not very mathematic, but will give you a close enough answer

于 2011-01-21T13:24:21.597 回答
0

我从来没有这样做过,但理论和实践表明,将图像和调色板中的 RGB 值转换为亮度-色度将帮助您找到最佳匹配。我会单独留下 alpha 通道,因为透明度应该与“看起来更好”部分几乎没有关系。

This xmass I made some photomosaics for presents using open-source software that matches fragments of the original image to a collection of images. That seems like a harder problem than the one you're trying to solve. One of them programs was metapixel.

Lastly, the best option should be to use an existing library to convert the image to a format, like PNG, in which you can control the palette.

于 2011-01-21T02:09:02.417 回答