图像处理-RBG图像和灰度图像

目录

1.国际照明委员会  
2.色度图 
3.RGB颜色空间  
4.灰度图像
5.RBG转灰度


国际照明委员会

CIECommission Internationale de L'Eclairage):国际照明委员会,根据其法语名称简写为CIE。其前身是1900年成立的国际光度委员会(International Photometric CommissionIPC),1913年改为现名。总部设在奥地利维也纳。CIE制订了一系列色度学标准,一直沿用到数字视频时代,其中包括白光标准(D65)和阴极射线管(CRT)内表面红、绿、蓝三种磷光理论上的理想颜色。

色度图

明度、色调和饱和度称为颜色视觉三特性。

  明度就是明亮的程度;

  色调是由波长决定的色别,如700nm光的色调是红色,579nm光的色调是黄色,510nm光的色调是绿色等等;饱和度就是纯度,没有混入白色的窄带单色,在视觉上就是高饱和度的颜色。光谱所有的光都是最纯的颜色光,加入白色越多,混合后的颜色就越不纯,看起来也就越不饱和。

国际照明委员会(CIE1931年制定了一个色度图,用组成某一颜色的三基色比例来规定这一颜色,即用三种基色相加的比例来表示某一颜色,并可写成方程式:

(Color)=R(R)+G(G)+B(B)   式中,(C)代表某一种颜色,(R)、(G)、(B)是红、绿、蓝三基色,RGB是每种颜色的比例系数,它们的和等于1,即R+G+B=1,“C”是指匹配即在视觉上颜色相同,如某一蓝绿色可以表达为:(C)=0.06(R)+0.31(G)+0.63(B)

如果是二基色混合,则在三个系数中有一个为零;如匹配白色,则RGB应相等。

色度图如下:

1.png

  任何颜色都用匹配该颜色的三基色的比例加以规定,因此每一颜色都在色度图中占有确定的位置。色度图中:

  X轴色度坐标相当于红基色的比例;

  Y轴色度坐标相当于绿基色的比例;

  图中没有Z轴色度坐标(即蓝基色所占的比例)。

  因为比例系数X+Y+Z=1Z的坐标值可以推算出来,即1-X+Y=Z

     色度图中的弧形曲线上的各点是光谱上的各种颜色即光谱轨迹,是光谱各种颜色的色度坐标。红色波段在图的右下部,绿色波段在左上角,蓝紫色波段在图的左下部。

  图下方的直线部分,即连接400nm700nm的直线,是光谱上所没有的、由紫到红的系列。靠近图中心的C是白色,相当于中午阳光的光色,其色度坐标为X=0.3101Y=03162,Z=0.3737

设色度图上有一颜色S,由C通过S画一直线至光谱轨迹O点(590nm),S颜色的主波长即为590nm,此处光谱的颜色即S的色调(橙色)。某一颜色离开C点至光谱轨迹的距离表明它的色纯度,即饱和度。颜色越靠近C越不纯,越靠近光谱轨迹越纯。S点位于从C590nm光谱轨迹的45%处,所以它的色纯度为45%(色纯度%=CS/CO)×100。从光谱轨迹的任一点通过C画一直线抵达对侧光谱轨迹的一点,这条直线两端的颜色互为补色(虚线)。从紫红色段的任一点通过C点画一直线抵达对侧光谱轨迹的一点,这个非光谱色就用该光谱颜色的补色来表示。表示方法是在非光谱色的补色的波长后面加一C字,如536G,这一紫红色是536nm绿色的补色。


RGB颜色空间

对图像处理而言,RGB是最为重要和常见的颜色模型,它建立在笛卡尔坐标系中,以红、绿、蓝三种基本色为基础,进行不同程度的叠加,产生丰富而广泛的颜色,俗称三基色模式。

RGB颜色空间是用一个单位长度的立方体来表示颜色的,黑蓝绿青红紫黄白8种常见颜色分别位居立方体的8个顶点,通常将黑色置于三维直角坐标系的原点,红绿蓝分别置于3根坐标轴土,整个立方体放在第1卦限内。如下图所示。

2.png

而其中的青色与红色、紫色(或称品红色)与绿色、黄色与蓝色是互补色。各参数的取值范围是:R0-255G0-255B0-255。参数值也称为三色系数或基色系数或颜色值,除以255后归一到0-1之间,但不是无穷多个而是有限多个值。由于每个灰度级都定为256,所以,红绿蓝分量全部组合起来共可表示256=2=16777216种不同的颜色。它比人眼能分辨的颜色种数多得多。因此,虽然自然界中的颜色非常多,但用RGB颜色空间来近似表达自然界中的颜色是完全够用了。

RGB颜色空间不能表示自然界所有的颜色,这一点可以从CIE的色度图得出。

3.jpg

上图中红、绿、蓝点分别表示三原色,连接这三点得出的三角形即为由三原色混合所得颜色的范围,三角形外的颜色均不能由三原色混合产生。而普通显示器因为技术原因,并不能发出纯正的单色光,故而所围成的三角形更小,显示的颜色更少。

4.png


灰度图像

灰度数字图像是每个像素只有一个采样颜色的图像。这类图像通常显示为从最暗黑色到最亮的白色的灰度,尽管理论上这个采样可以任何颜色的不同深浅,甚至可以是不同亮度上的不同颜色。灰度图像与黑白图像不同,在计算机图像领域中黑白图像只有黑白两种颜色,灰度图像在黑色与白色之间还有许多级的颜色深度。

 

RBG转灰度

灰度图片只有一个颜色通道,而RGB图片有三个颜色通道,因此RGB到灰度的转换需要特定的算法,下面给出常见的几个公式:

方法一:

很著名的心理学公式:

 Gray = R*0.299 + G*0.587 + B*0.114

方法二:

实际应用时,希望避免低速的浮点运算,所以需要整数算法。注意到系数都是3位精度的没有,我们可以将它们缩放1000倍来实现整数运算算法:

Gray = (R*299 + G*587 + B*114 + 500) / 1000

     RGB一般是8位精度,现在缩放1000倍,所以上面的运算是32位整型的运算。注意后面那个除法是整数 除法,所以需要加上500来实现四舍五入。

      由于该算法需要32位运算,我们需要更加简化的运算,所以该公式的近似公式为:

Gray = (R*30 + G*59 + B*11 + 50) / 100

代码实现:

Mat GrayscaleOperation(Mat& src)
{
    Mat dst(src.size(), CV_8UC1);
      for (int i = 0; i < src.rows; i++) {
        uchar *dstRow = dst.ptr(i);
      for (int j = 0; j < src.cols; j++)
      {
         uchar *psrc = src.ptr<uchar>(i, j);
         dstRow[j] = int((psrc[2]*30+psrc[1]*59+psrc[0]*11+50)/100);//Gray = (R * 30 + G * 59 + B * 11 + 50) / 100
       }
     }
  return dst;
}

运行结果:

5.png


方法三:

上面的整数算法已经很快了,但是还不够,上面的公式里有除法,而我们尽量不要除法。移位比除法快多了,所以可以将系数缩放成2的整数幂。习惯上使用16位精度,216次幂是65536,所以这样计算系数:

0.299 * 65536 = 19595.264 ≈ 19595
0.587 * 65536 + (0.264) = 38469.632 + 0.264 = 38469.896 ≈ 38469
0.114 * 65536 + (0.896) =   7471.104 + 0.896 = 7472

可能很多人看见了,我所使用的舍入方式不是四舍五入。四舍五入会有较大的误差,应该将以前的计算结果的误差一起计算进去,舍入方式是去尾法:

写成表达式是:

Gray = (R*19595 + G*38469 + B*7472) >> 16

220位精度的系数:

Gray = (R*1 + G*2 + B*1) >> 2
Gray = (R*2 + G*5 + B*1) >> 3
Gray = (R*4 + G*10 + B*2) >> 4
Gray = (R*9 + G*19 + B*4) >> 5
Gray = (R*19 + G*37 + B*8) >> 6
Gray = (R*38 + G*75 + B*15) >> 7
Gray = (R*76 + G*150 + B*30) >> 8
Gray = (R*153 + G*300 + B*59) >> 9
Gray = (R*306 + G*601 + B*117) >> 10
Gray = (R*612 + G*1202 + B*234) >> 11
Gray = (R*1224 + G*2405 + B*467) >> 12
Gray = (R*2449 + G*4809 + B*934) >> 13
Gray = (R*4898 + G*9618 + B*1868) >> 14
Gray = (R*9797 + G*19235 + B*3736) >> 15
Gray = (R*19595 + G*38469 + B*7472) >> 16
Gray = (R*39190 + G*76939 + B*14943) >> 17
Gray = (R*78381 + G*153878 + B*29885) >> 18
Gray = (R*156762 + G*307757 + B*59769) >> 19
Gray = (R*313524 + G*615514 + B*119538) >> 20

仔细观察上面的公式,这些精度实际上是一样的:3478101113141920。所以16位运算下最好的计算公式是使用7位精度,比先前那个系数缩放100倍的精度高,而且速度快:

Gray = (R*38 + G*75 + B*15) >> 7

其实最有意思的还是那个2位精度的,完全可以移位优化:

Gray = (R + (WORD)G<<1 + B) >> 2

 

方法四:

    这一种是 Adobe Photoshop 里的公式 Adobe RGB (1998) [gamma=2.20]

Gray = (R^2.2 * 0.2973 + G^2.2 * 0.6274 + B^2.2 * 0.0753)^(1/2.2)

该方法运行速度稍慢,但是效果很好。

代码实现:

Mat GrayscaleOperationPS(const Mat& src)
{
    Mat dst(src.size(), CV_8UC1);
    for (int i = 0; i < src.rows; i++) {
         uchar *dstRow = dst.ptr(i);
         for (int j = 0; j < src.cols; j++)
         {
             const uchar *psrc = src.ptr<uchar>(i, j);
             double result1 = pow(psrc[2], 2.2)*0.2973 + pow(psrc[1], 2.2)*0.6274 + pow(psrc[0], 2.2)*0.0753;
             double result2 = pow(result1,1.0/2.2);
             dstRow[j] = int(result2);
         }
    }
    return dst;
}

6.png

方法五:

     还有就是平均值方法

      GRAY = (RED+BLUE+GREEN)/3

    GRAY,GRAY,GRAY 替代 RED,GREEN,BLUE

     但是这样做的精度比较低,图像转化为灰度效果不是太好。

Mat GrayscaleOperationAvg(const Mat& src)
{
    Mat dst(src.size(), CV_8UC1);
    for (int i = 0; i < src.rows; i++) {
         uchar *dstRow = dst.ptr(i);
         for (int j = 0; j < src.cols; j++)
         {
             const uchar *psrc = src.ptr<uchar>(i, j);
             dstRow[j] = int((psrc[0]+ psrc[1] + psrc[2])/3);
         }
    }
    return dst;
}

7.png

参考文献

[1]百度百科.色度图. https://baike.baidu.com/item/%E8%89%B2%E5%BA%A6%E5%9B%BE/12732449 .

[2]CSDN博客:MathOnAir.色度图的问题.https://blog.csdn.net/dachuangmath/article/details/51037991. 2016-04-01

首页 所有文章 机器人 计算机视觉 自然语言处理 机器学习 编程随笔 关于