颜色逻辑算法

IT技术 java javascript algorithm colors
2021-03-07 18:24:28

我们正在构建一个体育应用程序,并希望在应用程序的各个部分中加入球队颜色。

现在每个团队都可以使用几种不同的颜色来表示。

我想要做的是做一个检查,验证两个团队的颜色是否在一定范围内,这样我就不会显示两个相似的颜色。

因此,如果团队 1 的主要团队颜色值为 rgb(255,0,0)(或 #FF0000),而团队 2 的主要颜色相似,例如 rgb(250,0,0),那么我们将选择不同的其中一支球队的颜色。

如果可能,我可以采取什么方法进行检查?

谢谢

6个回答

这是一个理论解释

C中的算法:

typedef struct {
    unsigned char r, g, b;
} RGB;

double ColourDistance(RGB e1, RGB e2)
{
    long rmean = ( (long)e1.r + (long)e2.r ) / 2;
    long r = (long)e1.r - (long)e2.r;
    long g = (long)e1.g - (long)e2.g;
    long b = (long)e1.b - (long)e2.b;
    return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
}
该算法是否可以在预定义颜色中找到最接近的颜色?
2021-04-22 18:24:28
@bluenote10 几年前我写了一篇关于此的博客文章。godsnotwheregodsnot.blogspot.com/2012/09/...)编写它的人做得非常出色。它实际上与 CIEdE2k 相比非常有利,因为它只是尺寸的一小部分。它基本上可以很好地捕捉对色彩空间和权重的最大最重要修复。
2021-04-26 18:24:28
rgb 值是否标准化为区间 0..1 或常规值在范围 0..255?
2021-04-28 18:24:28
最好添加一个注释,说明该算法与维基百科色差文章中描述的技术的比较,例如。CIEDE2000。
2021-05-01 18:24:28
@Thariama 它们是 0-255,如无符号字符(1 字节)所示
2021-05-05 18:24:28

这是 Java 中的 pgras 算法:

public double ColourDistance(Color c1, Color c2)
{
    double rmean = ( c1.getRed() + c2.getRed() )/2;
    int r = c1.getRed() - c2.getRed();
    int g = c1.getGreen() - c2.getGreen();
    int b = c1.getBlue() - c2.getBlue();
    double weightR = 2 + rmean/256;
    double weightG = 4.0;
    double weightB = 2 + (255-rmean)/256;
    return Math.sqrt(weightR*r*r + weightG*g*g + weightB*b*b);
} 
你还没有申请“>>8”?
2021-04-29 18:24:28
为什么不好?你能解释一下我的学习目的吗?
2021-05-02 18:24:28
@sam_k:>>8是一种糟糕的写作方式/256
2021-05-08 18:24:28
@sam_k:应编写易于阅读的代码。>>8当你的意思是“除以 256”时,写作并没有明确说明意图,因此更难以理解。有些人这样做的原因是他们相信(错误地)这会使代码更快。它没有 - 即使是最愚蠢的优化器也足够聪明,可以自动进行优化。
2021-05-14 18:24:28

这个问题的大多数答案都会建议在将 RGB 值映射到 3D 空间时计算两种颜色之间的距离。这种技术的问题在于,与具有不同色调但饱和度和亮度级别非常相似的两种颜色相比,具有相似色调但不同饱和度或亮度级别的两种颜色在 3D RGB 空间中可能映射得更远。换句话说,在 3D RGB 空间中,蓝色和绿色可能比红色的两种色调更接近。在这个应用程序中,确保团队颜色不同,色调差异应该比亮度和饱和度更重要。

因此,我会将颜色映射从 RGB 转换为色调、饱和度和亮度级别,然后仅检查色调值是否有足够的距离。

维基百科有关于将 RGB 转换为 HSV 的解释。 LiteratePrograms 有一些示例代码。

正如 OP 所说,目标是一次只比较两种颜色。如果 RGB 距离方法给出的结果不足,我建议此方法是尝试的替代方法。正如我对此的更多思考一样,在比较具有较高饱和度和亮度值的颜色时,仅比较色调值会得到很好的结果,而在比较具有低亮度或低饱和度的颜色时则会失败。这种方法的改进是在检查色调差异之前检查至少一种颜色具有足够高的饱和度和亮度值。
2021-04-24 18:24:28
如果 OP 只有六个团队,这就足够了;但如果有 20 或 30+,那么他必须考虑饱和度和亮度。链接 pgras 声称他们的算法比 HSV-distance 给出了更好的结果(这当然是主观的)。
2021-05-14 18:24:28
我在第一次阅读时错过了 Java 标签。java.awt.Color 类具有用于转换的 RGBtoHSB 方法。
2021-05-15 18:24:28

我会使用两种颜色之间的 3d 距离,其中 x、y、z 是 R、G、B 值。

看看这个 Perl 库:

http://metacpan.org/pod/Color::Similarity::RGB

这很容易自己实现。

只要确保 (R1-R2)^2 + (G1-G2)^2 + (B1-B2)^2 >= threshold^2

根据您的应用程序,您可以使用不同的算法。这个是最简单的。您还可以将 RGB 因子缩放 22、43、35 并获得更好的结果。尽管由 Thiadmer Riemersma 编写,但这里称为 pgras 的 redmean 公式是一个进步。然后你继续使用 CIEdE2000,它开始拉伸和拉动色彩空间,使眼睛越来越均匀。它还取决于诸如 XYZ 之类的东西,它可以让您更轻松地解释色盲等问题。
2021-04-23 18:24:28
是的,我会说两种颜色看起来有多相似(而不是它们有多相似),我会使用 pgras 算法。人类的眼睛远非完美:我们对绿色比红色或蓝色更敏感,我们的亮度感知是对数的,等等。
2021-05-11 18:24:28
我不得不承认这对于计算机视觉非常有效,但我并没有真正将解剖学考虑到这个答案中。
2021-05-12 18:24:28

维基百科有许多可用于此的算法的详细信息。

还有这个以前的 StackOverflow 问题:寻找颜色之间的准确“距离”