Calculate the value depending on the amount of green versus blue and red

A bit stuck on this one.

Here's my predicament:

A color has 3 elements: red, green and blue (RGB).

All colors have a value between 0 and 255.

eg:

var red:int = 53; 
var green:int = 150;
var blue:int = 28;

      

My scoring system works that green will be higher than 10.

So:

var red:int = 0; 
var green:int = 255;
var blue:int = 0;

      

Would have gotten the highest score (10) and:

var red:int = 255; 
var green:int = 0;
var blue:int = 255;

      

will get the lowest result (0).

I need to create some kind of equation. Is Bayes' Theorum where should I be?

really has no idea.

+3


source to share


6 answers


I worked out a way to get it right.

review the below code:

var color = parseInt(colorString);
var fitness:Number = 0;
var red:int = (color>> 16) & 0xFF;
var green:int = (color>> 8) & 0xFF;
var blue:int = color & 0xFF;
var greenPercentage = (green/255)*100;
var redAndBluePercentage = ((red+blue)/510)*100;
fitness = greenPercentage-redAndBluePercentage;
fitness = (fitness+100)/2;
trace(fitness);

      

The math works like this: take your color, divide it into red, green, and blue.

Take the percentage of green. (X / 255)



take the percentage of red and blue (x / 510)

subtract your red and blue percentage from your green.

add some math to give you a possible score from 0 to 100.

colorFitness("0xFF00FF"); //Outputs 0
colorFitness("0x00FF00"); //Outputs 100

      

0


source


Unfortunately I am not a doog in the Action script so can provide real code, but I think I have some ideas that might help you. AFAIU your problem is that you want to measure the "greenish colors" of a given RGB color with all three components in mind so that

  • green will receive a 100% rating.
  • red or blue or magenta will get 0%
  • white (an equal mix of all 3) will get something in between.

If I needed to design a scheme like this, I would switch from RGB to a different coloring scheme like YUV or rather a href = "https://en.wikipedia.org/wiki/HSL_and_HSV" rel = " nofollow noreferrer "> HSL / HSV. In fact, the "H" aka Hue component seems to be what you want. Joining the wiki

Hue is one of the basic properties (called colorization parameters) of color, technically defined (in the CIECAM02 model) as "the degree to which a stimulus can be described as being similar to or different from stimuli that are described as red, green, blue and yellow."

To calculate Hue, you first need to determine the Max and Min components and the difference between them:

 M = max(R, G, B) 
 m = min(R, G, B) 
 C = M - m

      

then

If Red is the Max, then Hue = (G - B)/C
If Green is the Max, then Hue = 2.0 + (B - R)/C
If Blue is the Max, then Hue = 4.0 + (R - G)/C

      



This gives values ​​in the range [-1, 5]. You can convert it to more normal degrees by multiplying by 60 and wrapping arround in fir [0, 360], but that doesn't matter as it's just a linear scale. Thus, using the Hue

one calculated as previously defined, you can measure the "greenish colors" of a color using a value Hue

close to 2 (or in degrees up to 120).

Note that from this formula "greenishess" for colors close to green (that is, where green is the Max component) is calculated as

"greenishess" = abs(B - R)/(G - min(B,R))

      

which makes sense to me. The part where B = R sets the color saturation and only the "excess" of R or B over the other shifts the color from "pure" green to yellow or blue.

Note that you will need to assign some arbitrary "greenish" value for all "grays" from black to white, since there C

will be 0 and you cannot divide by 0.

Finally, you don't need to use Hue

directly. A more complex formula can be built on its basis. For example, you can put some cut-off points to give 0% rating to pure red and blue, i.e. Anything outside [0; 4] (or [0; 240] in degrees). By default, Hue only assigns 0% to Magenta, which is {Red = 255, Green = 0, Blue = 255}. Something like

"greenishness" = [2 - abs(min(4, max(0, Hue)) - 2)] / 2 * 100%

      

You can also "curve" the measurement by applying some non-linear transformation.

+1


source


Your problem is choosing the right function (r,g,b)

that returns values ​​from 0 to 10. You are claiming that you (0,255,0)

should return 10.0, while other values ​​should return less and (255,0,255)

should return 0. So you need to choose at least two parameters for this functions. One is the value in (x,x,x)

(if you want it to be equal, or the parameter would be a function of X) and the other is the interpolation rule for non-extreme values. So your function should look like this:

function score(r,g,b:int):Number {
    var rc:int=Math.max(0,Math.min(255,r)); // clamp
    var gc:int=Math.max(0,Math.min(255,g));
    var bc:int=Math.max(0,Math.min(255,b));
    const GRAY:Number=5.0; // value at (x,x,x)
    if ((rc==rg) and (rc==rb)) return GRAY;
    return ir(r,g,b); // interpolation rule
}

      

In fact, you can specify values ​​in all 8 angles and simply interpolate them with whatever law you can imagine. For example, relative distance. Like this:

const SCORES:Array=[
    0, // black, (0,0,0)
    0, // red, (255,0,0)
    10, // green, (0,255,0)
    6.66666, // yellow, (255,255,0)
    0, // blue, (0,0,255)
    0, // magenta, (255,0,255)
    6.66666, // cyan, (0,255,255)
    5.0 // white, (255,255,255)
];
const POINTS:Array=[
    {r:0;g:0;b:0},
    {r:255;g:0;b:0},
    {r:0;g:255;b:0},
    {r:255;g:255;b:0},
    {r:0;g:0;b:255},
    {r:255;g:0;b:255},
    {r:0;g:255;b:255},
    {r:255;g:255;b:255}
]; // respective points

function score(r,g,b:int):Number {
    var rc:int=Math.max(0,Math.min(255,r)); // clamp
    var gc:int=Math.max(0,Math.min(255,g));
    var bc:int=Math.max(0,Math.min(255,b));
    var dists:Array=new Array();
    var td:Number=0;
    for (var i:int=POINTS.length-1;i>=0;i--) 
        var dist:Number=distance({r=rc;g=gc;b=bc},POINTS[i]); // TODO
        if (dist<1e-6) return SCORES[i]; // we're at the corner
        dists.unshift(1.0/dist);
        td+=1.0/dist;
    }
    var result:Number=0;
    for (i=POINTS.length-1;i>=0;i--) 
        result+=SCORES[i]*dists[i]/td;
    return result;
}

      

+1


source


You have not specified what you want this equation for. I believe it was already said that you have a function with 3 parameters, but you only give the expected output for two single parameter cases, and there are many functions that could live up to your expectations, but between the two outputs, the work is completely different.

I do not know. If you have noticed this, but, for example, yours colorFitness

gives a rating 50

for 0x000000

- is this what you expect?

For the current state of your question, I might also suggest something like this.

function score(c:uint) {
    var g:uint = (c >>> 8) & 0xFF;
    var s:uint = g + (c >>> 16 & g ^ g);
    s = (s + (c & 0xFF & g ^ g)) / 0x2FD * 100;
    trace("score for", c.toString(16), ":", s);
}

score(0x00FF00); //100
score(0x000000); //0
score(0xFF00FF); //0
score(0xFF7FFF); //16
score(0xFFFFFF); //33
score(0x00FFFF); //66
score(0xFFFF00); //66
score(0x7FFF7F); //66

      

But it would be nice if you could tell us that you need this formula to more accurately define what it should do.

+1


source


If you just check the color value to extract the estimate 0 - 10

from the range 0 - 255

, just do:

score = Math.round( (green / 255 ) * 10 );

      

So, with this logic, we can see that where:

green = 253 gives a rating of 10
green = 190 gives a rating of 7
green = 128 gives a rating of 5
green = 47 gives a rating of 2

There is a threshold where if a number is higher than X but less than Y, it will give the same score, for example, anything green

between 243 and 255 will give a score of 10.

PS: Some testable codes:

var score:int = 0;
var green:int = 128; //#change this for testing
score = Math.round( (green / 255 ) * 10 );

trace ("score is : " + score);

      

0


source


It's a bit tricky because there are 3 components, but if I understand correctly, only one of the components determines your rating.

You can completely ignore red-blue components and ranks only at level 0-255 green; the result would be that the two colors green = 64 but with the red and blue values ​​changed, for example rgb [100, 64, 50] and rgb [50, 64, 100] will evaluate the same since both have the same the amount of green. This result means that the green count is the projection of the 3D RGB coordinate onto the "green axis".

0


source







All Articles