Finding nearest RGB colour

2019-02-07 10:29发布

I was told to use distance formula to find if the color matches the other one so I have,

struct RGB_SPACE
{
    float R, G, B;
};

RGB_SPACE p = (255, 164, 32);  //pre-defined
RGB_SPACE u = (192, 35, 111);  //user defined

long distance = static_cast<long>(pow(u.R - p.R, 2) + pow(u.G - p.G, 2) + pow(u.B - p.B, 2));

this gives just a distance, but how would i know if the color matches the user-defined by at least 25%?

I'm not just sure but I have an idea to check each color value to see if the difference is 25%. for example.

float R = u.R/p.R * 100;
float G = u.G/p.G * 100;
float B = u.B/p.B * 100;

if (R <= 25 && G <= 25 && B <= 25)
{
   //color matches with pre-defined color.
}

标签: c++ colors rgb
3条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-02-07 10:59

I would suggest not to check in RGB space. If you have (0,0,0) and (100,0,0) they are similar according to cababungas formula (as well as according to casablanca's which considers too many colors similar). However, they LOOK pretty different.

The HSL and HSV color models are based on human interpretation of colors and you can then easily specify a distance for hue, saturation and brightness independently of each other (depending on what "similar" means in your case).

查看更多
时光不老,我们不散
3楼-- · 2019-02-07 11:09

"Matches by at least 25%" is not a well-defined problem. Matches by at least 25% of what, and according to what metric? There's tons of possible choices. If you compare RGB colors, the obvious ones are distance metrics derived from vector norms. The three most important ones are:

  • 1-norm or "Manhattan distance": distance = abs(r1-r2) + abs(g1-g2) + abs(b1-b2)
  • 2-norm or Euclidean distance: distance = sqrt(pow(r1-r2, 2) + pow(g1-g2, 2) + pow(b1-b2, 2)) (you compute the square of this, which is fine - you can avoid the sqrt if you're just checking against a threshold, by squaring the threshold too)
  • Infinity-norm: distance = max(abs(r1-r2), abs(g1-g2), abs(b1-b2))

There's lots of other possibilities, of course. You can check if they're within some distance of each other: If you want to allow up to 25% difference (over the range of possible RGB values) in one color channel, the thresholds to use for the 3 methods are 3/4*255, sqrt(3)/4*255 and 255/4, respectively. This is a very coarse metric though.

A better way to measure distances between colors is to convert your colors to a perceptually uniform color space like CIELAB and do the comparison there; there's a fairly good Wikipedia article on the subject, too. That might be overkill depending on your intended application, but those are the color spaces where measured distances have the best correlation with distances perceived by the human visual system.

查看更多
何必那么认真
4楼-- · 2019-02-07 11:11

Note that the maximum possible distance is between (255, 255, 255) and (0, 0, 0), which are at a distance of 3 * 255^2. Obviously these two colours match the least (0% match) and they are a distance 100% apart. Then at least a 25% match means a distance less than 75%, i.e. 3 / 4 * 3 * 255^2 = 9 / 4 * 255 * 255. So you could just check if:

distance <= 9 / 4 * 255 * 255
查看更多
登录 后发表回答