RGBA 颜色空间中的颜色相似度/距离

发布于 2024-10-13 11:52:42 字数 844 浏览 9 评论 0原文

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

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

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

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

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

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

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

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

最佳公式是什么?


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


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

How to compute similarity between two colors in RGBA color space? (where the background color is unknown of course)

I need to remap an RGBA image to a palette of RGBA colors by finding the best palette entry for each pixel in the image*.

In the RGB color space the most similar color can be assumed to be the one with the smallest euclidean distance. However, this approach doesn't work in RGBA, e.g., Euclidean distance from rgba(0,0,0,0) to rgba(0,0,0,50%) is smaller than to rgba(100%,100%,100%,1%), but the latter looks much better.

I'm using premultiplied RGBA color space:

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

and I've tried this formula (edit: See the answer below for better formula):

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

but it doesn't look optimal — in images with semitransparent gradients it finds wrong colors that cause discontinuities/sharp edges. Linear proportions between opaque colors and alpha seem fishy.

What's the optimal formula?


*) for simplicity of this question I'm ignoring error diffusion, gamma and psychovisual color spaces.


Slightly related: if you want to find nearest color in this non-Euclidean RGBA space, vp-trees are the best.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小瓶盖 2024-10-20 11:52:42

终于,我找到了!经过彻底的测试和实验,我的结论是:

  • 正确的方法是计算两种颜色之间的最大可能差异。
    具有任何估计平均值/典型差异的公式都有不连续的空间。

  • 我无法找到一个工作公式来计算距离而不将 RGBA 颜色与某些背景混合。

  • 无需考虑所有可能的背景颜色。它可以简化为分别为每个 R/G/B 通道混合最大值和最小值:

    1. 通道=0为背景混合两种颜色的通道,测量平方差
    2. channel=max为背景混合两种颜色的通道,测量平方差
    3. 两者中取较高者。

幸运的是,当您使用预乘 Alpha 时,与“白色”和“黑色”混合是微不足道的。

预乘 Alpha 颜色空间的完整公式为:

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 源代码,包括 SSE2 实现

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.

陌生 2024-10-20 11:52:42

几个原则:

  1. 当两种颜色具有相同的alpha时,rgbaDistance = rgbDistance * (alpha / 255)。当两个 alpha 均为 255 时,兼容 RGB 颜色距离算法。
  2. 所有具有非常低 alpha 的颜色都是相似的。
  3. 具有相同 RGB 的两种颜色之间的 rgbaDistance 与 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);
}

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);
}
单身情人 2024-10-20 11:52:42

我的想法是对所有可能的背景颜色进行一次积分并平均平方误差。

即对于每个分量计算(此处使用红色通道为例)

从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 求和。

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.

所有深爱都是秘密 2024-10-20 11:52:42

首先,一个非常有趣的问题:)
我没有完整的解决方案(至少还没有),但我们应该考虑两种明显的极端情况:
Δa==0 时,问题类似于 RGB 空间
Δa==1 时,问题仅出现在 alpha 1 维空间上
因此,满足该条件的公式(与您所说的非常相似)是:
(Δr2 + Δg2 + Δb2) × (1-(1-Δa)2) + Δa2(Δr2 + Δg2 + Δb2) × (1-Δa2) + Δa2

无论如何,它可能会类似于 (Δr² + Δg² + Δb²) × f(Δa) + Δa²

如果我是你,我会尝试用各种 RGBA 对来模拟它,各种背景颜色来找到最佳的 f(Δa) 函数。不是很数学,但会给你一个足够接近的答案

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

请恋爱 2024-10-20 11:52:42

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

今年圣诞节,我使用开源软件为礼物制作了一些马赛克照片,该软件将原始图像的片段与图像集合相匹配。这似乎是一个比您要解决的问题更难的问题。其中一个程序是metapixel

最后,最好的选择应该是使用现有的库将图像转换为某种格式,例如 PNG,您可以在其中控制调色板。

I've never done it, but theory and practice say that converting the RGB values in the image and the palette to luminance–chrominance will help you find the best matches. I'd leave the alpha channel alone, as transparency should have little to nothing to do with the 'looking better' part.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文