views:

569

answers:

6

We are building a sports application and would like to incorporate team colors in various portions of the app.

Now each team can be represented using several different colors.

What I would like to do is to perform a check to verify whether the two team colors are within a certain range of each other, so that I do not display two similar colors.

So, if team 1's primary team color has a value of rgb(255,0,0) (or #FF0000), and team 2's primary color is similar, say rgb(250,0,0), then we would choose a different color for one of the teams.

If possible, what approach could I take to perform the check?

Thanks

+4  A: 

I would use 3d distance between two colors where x,y,z are R,G,B values.

Take a look at this Perl Library:

http://search.cpan.org/~mbarbon/Color-Similarity-0.01/lib/Color/Similarity/RGB.pm

This is easy to implement yourself.

Just make sure that (R1-R2)^2 + (G1-G2)^2 + (B1-B2)^2 >= threshold^2

Hamish Grubijan
I have to admit that this worked quite well for computer vision, but I am not really taking anatomy into account with this answer.
Hamish Grubijan
Yeah, I'd say for how similar two colors LOOK (rather than how similar they ARE), I'd use pgras' algorithm. Human eyes are far from perfect: we're more sensitive to green than red or blue, our brightness perception is logrithmic, etc.
BlueRaja - Danny Pflughoeft
+2  A: 

Wikipedia has details on a number of algorithms which can be used for this.

There is also this previous StackOverflow question: Finding an accurate “distance” between colors

matt b
+9  A: 

Here is a theoretical explanation

And the algo in 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));
}
pgras
+1 for great link, code (though OP asked for Java)
BlueRaja - Danny Pflughoeft
+1  A: 

From an algorithm viewpoint, this is fairly simple. Each color represents a point in a 3D space, and the difference between colors is the distance between those points.

Presumably the point here is to ensure that the colors are visibly different. If that's the case, deciding on the minimum distance is probably going to be fairly difficult. The problem is that (at least for people with normal vision) some differences are easier to see than others. For example, most people are more sensitive to small differences in shades of green than equally small changes in shades of red or blue. There are algorithms to take this into account, but they're based on average human vision, so none of them is guaranteed to be precisely correct for any one person.

Just for fun, you might want to take a look at X-rite's online color vision test.

Jerry Coffin
That page almost made me puke
BlueRaja - Danny Pflughoeft
+2  A: 

Most answers for this question will suggest calculating the distance between two colors when mapping the RGB values into a 3D space. The problem with this technique is that two colors with similar hues, but different saturation or brightness levels may map further away from each other in 3D RGB space than two colors with different hues, but very similar saturation and brightness levels. In other words, a blue and a green may be closer in 3D RGB space than two shades of a Red. In this application, ensuring team colors differ, hue differences should weigh much more heavily than brightness and saturation.

So I would convert the color mapping from RGB to hue, saturation, and brightness levels, and then check just the hue values for sufficient distance.

Wikipedia has an explanation for converting RGB to HSV. LiteratePrograms has some sample code.

Mr. Berna
I missed the Java tag on first reading. The java.awt.Color class has an RGBtoHSB method for the conversion.
Mr. Berna
That is sufficient if the OP has only half-a-dozen teams; but if there are 20 or 30+, then he **has** to take saturation and brightness into account. The link pgras gave claims their algorithm gives better results (which is of course subjective) than HSV-distance.
BlueRaja - Danny Pflughoeft
As the OP says, the goal is to compare just two colors at at time. I suggested this method is an alternative to try if the RGB distance methods give insufficient results.As I think more on this, comparing just hue values will give good results when comparing colors with higher saturation and brightness values, and fail when comparing colors with either low brightness or low saturation. An improvement to this method would be to check that at least one of the colors has sufficiently high saturation and brightness values before checking hue differences.
Mr. Berna
+6  A: 

Here is pgras' algorithm in Java:

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);
} 
BlueRaja - Danny Pflughoeft