Determine which color (red, blue, green or other) would be visible for a given RGB value combination?
Asked Answered
B

3

5

So basically, I need a method in which I can pass values of red, green and blue and the method should return whether that combination of RGB values result in a visibly Red-ish color Green-ish color or Blue-ish color. And if the combination doesn't result in any of those three colors it should return false.

I tried to do this by using conditional statements, tried a few variations, but nothing is accurate.

For example I tried:

if (B > 100 && B > G / 2 && B > R / 2)
{
    blueCount++;
}
else if (G > 100 && G > G / 2 && G > B / 2)
{
    greenCount++;
}
else if (R > 100 && R > G / 2 && R > B / 2)
{
    redCount++;
}

// R , G , B contains 0-255 values 
Bittencourt answered 22/1, 2020 at 9:36 Comment(5)
This has so many edge cases it makes my head spin, what would you call black? What are the greys? What about when GB both 100? would say it's more G than BLette
You may want to use HSV color model and check for H (Hue) and may be for S (Saturation): if we have a right Hue (say, Green) and not very low Saturation (not too colorless lake gray, white, black) we can say we have a greenish colorSeta
you see this answerLicht
@MarkDavies "And if the combination doesn't result in any of those three colors it should return false" - but I get your point that one should define when is a color [red|green|blue]-ishScintillator
Have you consider that your method, instead of returning true/false, could return a percentage of "pureness" of the color provided? As for example, 255;0;0 is a 100% pure color, 128;0;0 is a 50% pure color, 255;128;128 is a 50% pure color... I dunno, something like thatSavick
S
4

If you define "being color-ish" as:

  • the color value is above 100
  • the color value is at least twice as the 2 other values
    • your current code states "at least half of the 2 other values" but this can't work because if you have "R:199 G:101 B:102", you could say that it is green-ish because G is above 100 and more than half 199 and half 102 (when it's obviously red-ish)

then your code looks almost good (just replace / with *).

I would just use an enum for the result:

enum Ish
{
    Other, // 0 so this would be false if you convert it to bool
    Red,   // 1
    Green, // 2
    Blue   // 3
}
if (R>100 && R>G*2 && R>B*2)
    return Ish.Red;
if (G>100 && G>R*2 && G>B*2) // you had G>G/2 here /!\
    return Ish.Green;
if (B>100 && B>G*2 && B>R*2)
    return Ish.Blue;
return Ish.Other;

I used 2 for twice, but I think you can use other values as long as it is >1 (you can't say blue is dominant if B <= R for example)

This would be the redish values possible for R=100 (left image with factor 2, right image with factor 1):

Red-ish 100 fact 2 Red-ish 100 fact 1

And this for R=200 (left image with factor 2, right image with factor 1):

Red-ish 200 fact 2 Red-ish 200 fact 1

Therefore you could probably use a factor between 1 and 2

For R=200 you can see the red-ish colors depending on the factor below:

Red-ish 200 multifactor

Scintillator answered 22/1, 2020 at 10:6 Comment(5)
oh... simple maths , silly mistake.. thanks for pointing out.!Bittencourt
@Bittencourt You're welcome, it was quite fun to do that (I expanded the last screenshot so that you can really see what happens when factor gets below 1)Scintillator
@Bittencourt I also fixed a typo you had in your second if (G>G..)Scintillator
How did you get the color space images, @Rafalon?Arlina
@CălinDarie I actually created them with Excel VBA (you can see in the last screenshot the 2 textboxes that I used for parameters - Red value & factor) and I used MS Paint to add the arrows and "COLOR-ish" textsScintillator
S
3

I suggest using different color space: HSV or HSL instead of RGB.

Now, to declare the color being greenish you have to check

  1. If color has H (Hue) within some range (Green tinge dominates over other colors)
  2. If color has S (Saturation) above some threshold in order not to be too colorless (grayish)
  3. If color has V or L (Value or Luminocity) above some threshold in order not to be too dark (blackish)

https://vignette.wikia.nocookie.net/psychology/images/e/e0/HSV_cylinder.png/revision/latest?cb=20071105130143

Seta answered 22/1, 2020 at 9:49 Comment(1)
If you want to assign a name to the color, you could refer to xkcd.com/color/rgb and walk down the list until you find a good match.Makeup
S
2

Don't try to hard to encounter a perfectly accurate answer for this. After all, there is no such thing as a perfect defined line between red-ish and not red-ish.

The way I would approach this is: first, check that color is not too grey/black. This can be done using the sum of the three components (keep in mind that full black is 0;0;0 on RGB, greys are usually something like 55;55;55). For example, you could consider as too dark any color whose components sum up less than 300. Play a little bit with any RGB picker tool to find the threshold you like the most.

EDIT: from comment below I see sum of three components won't work, for example the 255;0;0 would be consider as too grey. So you have to use maximum value of the three components. For example, 20;0;0 would still be quite dark, but 100;0;0 not so much. Thanks to @rafalon for pointing this out.

Then, you would need to check that this color is close to a "pure" color, that is, red, green or blue. In order to do that, you would need to compare the most prominent component with the other two. You have to compare this highest component with the other two, individually. This is because a color like 255;0;255 is not redish at all, while a 255;128;128 could be considered as such. So combination of the two less prominents components won't do the trick.

You could consider a color to be red-ish if both Green and Blue have a value lower than some percentage of red. Take for example this percentage to be 50%. Then, you need to check that green is less than 0.5 * red AND blue is less than 0.5 * red. Again, you should play a bit with RGB colors to find a percentage that you think it suits.

TL;DR: for a color with components r, g and b, this color will be a "pure" color if:

  1. Max(r, g, b) > tooDarkValue

  2. r > somePercentage * Max(r, g, b) AND g > somePercentage * Max(r, g, b) AND b > somePercentage * Max(r, g, b)

Note that second condition will always be true for Max(r, g, b), (any number is greater than a percentage of itself), so no need to evaluate which component is highest and then have 3 different conditions

Savick answered 22/1, 2020 at 10:26 Comment(1)
"you could consider as too dark any color whose components sum up less than 300" - so you would consider 255;0;0 as too dark?Scintillator

© 2022 - 2024 — McMap. All rights reserved.