# Algorithm to compare the likeness of or distance between two colours

This topic is 4382 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi Gamedev, was just wandering if anyone knew of or could point me in the direction of any algorithms that can compare how alike two colours are like in a percentage or scale value or the distance between each one based on their rgb components. For example say I have a method called compare() I would use it like this likeness = compareColour(0xFF0000,0xFFFF00) the value in likeness could be a percentage or something else maybe Just wandering. Thanks in advance. DarkStar UK

##### Share on other sites
I'd be tempted to simply use the euclidean distance in [0,1]3. Then, you could go looking for a chart determining ocular precision (which is greater in some areas of the cube, and smaller in others) and scale your distance based on this.

Then again, any distance is a valid distance in theory. Now, if you need specific properties to be true for that distance...

##### Share on other sites
It depends on what you mean by alike. For general purposes, just take the colors as 3D vectors and take the Euclidean distance between them as mentioned by ToohrVyk. Since RGB is an orthogonal space, it should be generally OK.

However, RGB is not a perceptually uniform space to human eyes (which is I think what ToohrVyk was getting at with ocular precision). Two colors that are an equal distance away from white might not look equally different from white, if that makes sense. Logluv is a perceptually uniform color space, if you really need it, but chances are all of this is overkill and RGB distance is good enough.

##### Share on other sites
maybe something like this, just a weighted euclidean distance...

(r1,g1,b1 and r2,g2,b2 float channels for the two colours)

float r3 = r1 - r2;
float g3 = g1 - g2;
float b3 = b1 - b2;

return sqrt( 0.2126f * r3 * r3 + 0.7152f * g3 * g3 + 0.0722f * b3 * b3 );

##### Share on other sites
I think the best you could do would be to convert from RGB to YUV, and then take the Eucledian distance as proposed above. A bit pseudo-code:
Y = 0.299R + 0.587G + 0.114B;U  = 0.492(B - Y);V  = 0.877(R - Y);clamp( Y, 0, 255 );clamp( U, 0, 255 );clamp( V, 0, 255 );dist = sqrt( (Y1-Y2)*(Y1-Y2) + (U1-U2)*(U1-U2) + (V1-V2)*(V1-V2) );

##### Share on other sites
Hi,

Just done this myself.

As others have stated a simple weighting/distance check will work, although you can drop the squareroot since you're comparing the same things. You may also want to try doing this with luminace and not actual colours, depending on the 'type' of matches you are looking for.

Also don't get fooled into checking for a 'near' distance fit, as this can lead to poor results. For example if you use (r*r)+(g*g)+(b*b) < 15 then both a colour that is 15 units out on the red, but not green or blue, will pass just as if each red,green,blue is out say 3 units each - i.e its the overall closeness of the components that is examined, not the closeness on a per component basis. So always look for a 'bestfit' its slower, but you'll get better results.

If you want to get more advanced have a look at Colour Metric and the C code snippet on that page. You might also want to browse through the colour space FAQ

##### Share on other sites
Quote:
 Orignial post by noisecrimeAlso don't get fooled into checking for a 'near' distance fit, as this can lead to poor results. For example if you use (r*r)+(g*g)+(b*b) < 15 then both a colour that is 15 units out on the red, but not green or blue, will pass just as if each red,green,blue is out say 3 units each - i.e its the overall closeness of the components that is examined, not the closeness on a per component basis. So always look for a 'bestfit' its slower, but you'll get better results.

This my thought when I first read the OP. Here's what I came up with just now as something that might work:

int r, g, b;r = abs(r1 - r2);g = abs(g1 - g2);b = abs(b1 - b2);if (r / 100 > 5)   return false;if (g / 100 > 5)   return false;if (b / 100 > 5)   return false;return true;

This checks that all component values are within 5 percent and returns false otherwise. Hope this help you out some [smile].

-AJ

1. 1
2. 2
Rutin
24
3. 3
4. 4
JoeJ
18
5. 5

• 14
• 23
• 11
• 11
• 9
• ### Forum Statistics

• Total Topics
631766
• Total Posts
3002235
×