Formula to determine brightness of RGB color

前端 未结 20 3087
猫巷女王i
猫巷女王i 2020-11-21 23:16

I\'m looking for some kind of formula or algorithm to determine the brightness of a color given the RGB values. I know it can\'t be as simple as adding the RGB values toget

相关标签:
20条回答
  • 2020-11-21 23:37

    I have made comparison of the three algorithms in the accepted answer. I generated colors in cycle where only about every 400th color was used. Each color is represented by 2x2 pixels, colors are sorted from darkest to lightest (left to right, top to bottom).

    1st picture - Luminance (relative)

    0.2126 * R + 0.7152 * G + 0.0722 * B
    

    2nd picture - http://www.w3.org/TR/AERT#color-contrast

    0.299 * R + 0.587 * G + 0.114 * B
    

    3rd picture - HSP Color Model

    sqrt(0.299 * R^2 + 0.587 * G^2 + 0.114 * B^2)
    

    4th picture - WCAG 2.0 SC 1.4.3 relative luminance and contrast ratio formula (see @Synchro's answer here)

    Pattern can be sometimes spotted on 1st and 2nd picture depending on the number of colors in one row. I never spotted any pattern on picture from 3rd or 4th algorithm.

    If i had to choose i would go with algorithm number 3 since its much easier to implement and its about 33% faster than the 4th.

    Perceived brightness algorithm comparison

    0 讨论(0)
  • 2020-11-21 23:37

    To determine the brightness of a color with R, I convert the RGB system color in HSV system color.

    In my script, I use the HEX system code before for other reason, but you can start also with RGB system code with rgb2hsv {grDevices}. The documentation is here.

    Here is this part of my code:

     sample <- c("#010101", "#303030", "#A6A4A4", "#020202", "#010100")
     hsvc <-rgb2hsv(col2rgb(sample)) # convert HEX to HSV
     value <- as.data.frame(hsvc) # create data.frame
     value <- value[3,] # extract the information of brightness
     order(value) # ordrer the color by brightness
    
    0 讨论(0)
  • 2020-11-21 23:39

    Here's a bit of C code that should properly calculate perceived luminance.

    // reverses the rgb gamma
    #define inverseGamma(t) (((t) <= 0.0404482362771076) ? ((t)/12.92) : pow(((t) + 0.055)/1.055, 2.4))
    
    //CIE L*a*b* f function (used to convert XYZ to L*a*b*)  http://en.wikipedia.org/wiki/Lab_color_space
    #define LABF(t) ((t >= 8.85645167903563082e-3) ? powf(t,0.333333333333333) : (841.0/108.0)*(t) + (4.0/29.0))
    
    
    float
    rgbToCIEL(PIXEL p)
    {
       float y;
       float r=p.r/255.0;
       float g=p.g/255.0;
       float b=p.b/255.0;
    
       r=inverseGamma(r);
       g=inverseGamma(g);
       b=inverseGamma(b);
    
       //Observer = 2°, Illuminant = D65 
       y = 0.2125862307855955516*r + 0.7151703037034108499*g + 0.07220049864333622685*b;
    
       // At this point we've done RGBtoXYZ now do XYZ to Lab
    
       // y /= WHITEPOINT_Y; The white point for y in D65 is 1.0
    
        y = LABF(y);
    
       /* This is the "normal conversion which produces values scaled to 100
        Lab.L = 116.0*y - 16.0;
       */
       return(1.16*y - 0.16); // return values for 0.0 >=L <=1.0
    }
    
    0 讨论(0)
  • 2020-11-21 23:39

    RGB Luminance value = 0.3 R + 0.59 G + 0.11 B

    http://www.scantips.com/lumin.html

    If you're looking for how close to white the color is you can use Euclidean Distance from (255, 255, 255)

    I think RGB color space is perceptively non-uniform with respect to the L2 euclidian distance. Uniform spaces include CIE LAB and LUV.

    0 讨论(0)
  • 2020-11-21 23:40

    The HSV colorspace should do the trick, see the wikipedia article depending on the language you're working in you may get a library conversion .

    H is hue which is a numerical value for the color (i.e. red, green...)

    S is the saturation of the color, i.e. how 'intense' it is

    V is the 'brightness' of the color.

    0 讨论(0)
  • 2020-11-21 23:43

    Below is the only CORRECT algorithm for converting sRGB images, as used in browsers etc., to grayscale.

    It is necessary to apply an inverse of the gamma function for the color space before calculating the inner product. Then you apply the gamma function to the reduced value. Failure to incorporate the gamma function can result in errors of up to 20%.

    For typical computer stuff, the color space is sRGB. The right numbers for sRGB are approx. 0.21, 0.72, 0.07. Gamma for sRGB is a composite function that approximates exponentiation by 1/(2.2). Here is the whole thing in C++.

    // sRGB luminance(Y) values
    const double rY = 0.212655;
    const double gY = 0.715158;
    const double bY = 0.072187;
    
    // Inverse of sRGB "gamma" function. (approx 2.2)
    double inv_gam_sRGB(int ic) {
        double c = ic/255.0;
        if ( c <= 0.04045 )
            return c/12.92;
        else 
            return pow(((c+0.055)/(1.055)),2.4);
    }
    
    // sRGB "gamma" function (approx 2.2)
    int gam_sRGB(double v) {
        if(v<=0.0031308)
            v *= 12.92;
        else 
            v = 1.055*pow(v,1.0/2.4)-0.055;
        return int(v*255+0.5); // This is correct in C++. Other languages may not
                               // require +0.5
    }
    
    // GRAY VALUE ("brightness")
    int gray(int r, int g, int b) {
        return gam_sRGB(
                rY*inv_gam_sRGB(r) +
                gY*inv_gam_sRGB(g) +
                bY*inv_gam_sRGB(b)
        );
    }
    
    0 讨论(0)
提交回复
热议问题