色彩逻辑算法
我们正在构建一个体育应用程序,并希望在应用程序的各个部分中加入团队颜色。
现在每个团队都可以用几种不同的颜色来表示。
我想要做的是执行检查以validation两个团队颜色是否在彼此的特定范围内,以便我不显示两个相似的颜色。
因此,如果团队1的主要团队颜色的值为rgb(255,0,0)(或#FF0000),团队2的主要颜色相似,例如rgb(250,0,0),那么我们会选择不同的颜色其中一支球队的颜色。
如果可能,我可以采取什么方法来执行检查?
谢谢
这是一个理论上的解释
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)); }
这是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); }
此问题的大多数答案将建议在将RGB值映射到3D空间时计算两种颜色之间的距离。 该技术的问题在于具有相似色调但不同饱和度或亮度水平的两种颜色可以在3D RGB空间中比具有不同色调但具有非常相似的饱和度和亮度水平的两种颜色更远地彼此映射。 换句话说,蓝色和绿色在3D RGB空间中可能比两个红色阴影更接近。 在此应用中,确保团队颜色不同,色调差异的重量应远大于亮度和饱和度。
因此,我将颜色映射从RGB转换为色调,饱和度和亮度级别,然后仅检查色调值是否有足够的距离。
维基百科有一个将RGB转换为HSV的解释。 LiteratePrograms有一些示例代码。
我会使用两种颜色之间的3d距离,其中x,y,z是R,G,B值。
看看这个Perl库:
http://metacpan.org/pod/Color::Similarity::RGB
这很容易实现。
只要确保(R1-R2)^ 2 +(G1-G2)^ 2 +(B1-B2)^ 2> =阈值^ 2
维基百科有许多可用于此的算法的详细信息。
此前还有StackOverflow问题: 在颜色之间找到准确的“距离”
从算法的角度来看,这非常简单。 每种颜色代表3D空间中的一个点,颜色之间的差异是这些点之间的距离。
据推测,这里的要点是确保颜色明显不同。 如果是这种情况,决定最小距离可能会相当困难。 问题是(至少对于视力正常的人来说)一些差异比其他人更容易看到。 例如,大多数人对绿色阴影的微小差异比对红色或蓝色阴影的同样小的变化更敏感。 有一些算法可以将这一点考虑在内,但它们是基于人类的平均视觉,所以它们都不能保证对任何一个人都是正确的。
只是为了好玩,您可能想看看爱色丽的在线色彩视觉测试 。