我正在寻找某种公式或算法来确定给定RGB值的颜色的亮度。我知道这不像把RGB值加在一起那么简单,更高的总和更亮,但我有点不知所措,不知道从哪里开始。


当前回答

下面是将sRGB图像转换为灰度的唯一正确算法,如在浏览器等中使用。

在计算内积之前,有必要对颜色空间应用伽玛函数的逆。然后你把函数应用到减少的值上。未能合并gamma函数可能导致高达20%的误差。

对于典型的计算机,颜色空间是sRGB。sRGB的正确数字约为。0.21 0.72 0.07。sRGB的Gamma是一个复合函数,近似取幂1/(2.2)。这是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)
    );
}

其他回答

再加上其他人说的话:

所有这些方程在实践中都工作得很好,但如果你需要非常精确,你必须首先将颜色转换为线性颜色空间(应用逆图像-gamma),对原色进行权重平均,如果你想显示颜色- 把亮度调回监控器伽马。

在深灰色中,忽略伽玛和正确伽玛之间的亮度差异高达20%。

基于所有这些答案,我的简单结论是,对于大多数实际用例,您只需要:

brightness = 0.2*r + 0.7*g + 0.1*b 

当r,g,b值在0到255之间时,亮度范围也在0(=黑)到255(=白)之间。

可以对它进行微调,但通常没有必要。

HSV的“V”可能就是你要找的。MATLAB有一个rgb2hsv函数,之前引用的维基百科文章充满了伪代码。如果RGB2HSV转换不可行,则较不准确的模型将是图像的灰度版本。

我认为你正在寻找的是RGB ->流光转换公式。

光度/数字ITU BT.709:

Y = 0.2126 R + 0.7152 G + 0.0722 B

数字ITU BT.601(给予R和B部分更多权重):

Y = 0.299 R + 0.587 G + 0.114 B

如果你愿意用准确性来换取性能,有两个近似公式:

Y = 0.33 R + 0.5 G + 0.16 B

Y = 0.375 R + 0.5 G + 0.125 B

这些可以快速计算为

Y = (R+R+B+G+G+G)/6

Y = (R+R+R+B+G+G+G+G)>>3

HSV色彩空间应该做的把戏,看维基百科文章取决于你正在工作的语言,你可能会得到一个库转换。

H是色调,是颜色的数值(即红色,绿色…)

S是颜色的饱和度,即它有多“强烈”

V是颜色的亮度。