现在的位置: 首页 > 综合 > 正文

24位位图转灰度

2013年09月22日 ⁄ 综合 ⁄ 共 6057字 ⁄ 字号 评论关闭

 24位位图转灰度

本文介绍24位位图转灰度各种算法,比较各种算法,最后编程实现的是ITU-R BT.601算法,对其进行初步优化,如果那位有心情可以把所有算法都实现。

本文是个人学习笔记,代码完全属于本人所有

 

 

 

 

基础算法

彩色照片变成黑白照片,其实就是图片中的彩色信息变为灰度信息,是把每一种不同深浅的颜色分别用同等亮度的灰度值来替代。

根据国际照明委员会(CIE)的规定,RGB混合成白色时的比例是1:1:1。因此,纯灰色(中性灰)RGB混合比例也是1:1:1,也就是说灰色是RGB值相等的颜色。

一种颜色深浅度由他的RGB值决定,RGB值越大,颜色越亮,反之则越暗。例如RGB(80,80,80)R=G=B=80,这时这种颜色的灰度值为Gray=80,是一种较暗的灰色。

如果RGB值不相等时怎么办呢?这时我们需要根据RGB的值来计算灰度Gray的值。下面我们以一种橄榄绿色:RGB(140,153,115)为例,来分析一下灰度值的算法。

RGB值不相等时,要想转换成与之接近的灰色,最容易想到的是以下几种方法:

a. 灰度值取RGB之一

公式:Gray = R  Gray = G  Gray = B

取橄榄绿色RGB(140,153,115)G值,Gray=G=153

下面分别是Gray=RGray=GGray=B时的效果:

 

c=r

 

 

c=g

 

c=b

 

b. 灰度值取RGB的最大值或最小值

公式:Gray = Max(R, G, B)  Gray = Min(R, G, B)

取橄榄绿色RGB(140,153,115)RGB最大值,因为153>140>115,所以Gray=153

c=maxRGB

 

c=minRGB

由于人眼对亮的颜色比对暗的颜色更敏感,因此取最大值比取最小值的效果要好。

HSVV值就是取最大值来求的。

c. 灰度值取RGB的中间值

公式:Gray = Mid(R, G, B)

 取橄榄绿色RGB(140,153,115)RGB中间值,因为153>140>115,所以Gray=140

c=midRGB

d. 灰度值取RGB的最大值与最小值的平均值

公式:Gray = (Max(R,G,B) + Min(R,G,B)) / 2

取橄榄绿色RGB(140,153,115)RGB最大值153与最小值115的平均值,Gray=(153+115)/2=134

c=(maxRGB+minRGB)/2

 

HSLL值就是用这种方法来求的。

e. 灰度值取RGB的平均值

公式Gray = (R + G + B) / 3

取橄榄绿色RGB(140,153,115)RGB平均值,Gray=(140+153+115)/3=136

c=(r+g+b)/3

HSII值就是用这种方法来求的。

RGB加权算法

先来分析一下前面的基础算法。算法a单取某色通道的方法显然是不公平的;bc的效果稍好,但与a的效果十分接近;de的效果较好,但仍有不足之处。下面我们根据彩虹条转换的效果来看一下de算法的不足之处。

 

看出来了吧de转换的是很平均的。但是你有没有感觉到实际上绿色和黄色的部分要稍亮一些,而红、蓝部分稍暗一些呢?这是为什么呢?

1931年,国际照明委员会(CIE)通过颜色匹配实验,得出用红、绿和蓝三基色光匹配成白光时,所需要的红、绿和蓝基色光的光通量之比为1∶4.5907∶0.0601,从这个比例上可以看出,绿色的成份所占的比例比较大。

为了简化计算,CIE采用了平均的单位制,记作[R][G][B],它规定白光是由各为1个单位的三基色光组成。

W() = 1[R] + 1[G] + 1[B]

CIE在此基础上定义了CIE XYZ颜色空间,并画出了相应的色度图。下图(b)中的E点代表白光,它的坐标为(0.33,0.33)。从CIE1931色度图中我们可以看出,绿色与白色E点的距离要比红色和蓝色大得多。

 

 

 

CIE色度图是基于人眼对色彩的感知的,从人的视觉角度来讲,RGB配成白光的实际比例是不同的,因此要想调出更为接近人的视觉的灰度,需要通过给RGB加权来增大绿色的分量。

ITU-R BT.601

国际电信联盟(International Telecommunication UnionITU)定义了几个推荐(Recommendation)标准,最流行的是ITU-R BT.601(前称 CCIR 601-1,简称Rec 601-1)ITU-R BT.709(前称 CCIR 709,简称Rec 709)

BT.601-1是老的NTSC制使用的标准,它使用CIE定义的一种标准光源,叫做光源C(illuminant C)”,用钨丝光源并通过滤波来模拟普通日光,色温是 6774°K。它规定白色在CIE色度图中的坐标是(0.310063,0.316158),红、绿和蓝的坐标分别是(0.67,0.33,0)(0.21,0.71,0.08)(0.14,0.08,0.78),跟据这些数据计算出如下的公式来:

X = 0.606881*R + 0.173505*G + 0.200336*B

Y = 0.298912*R + 0.586611*G + 0.114478*B

Z = 0.000000*R + 0.066097*G + 1.116157*B

其中Y的值就是我们要的亮度值(灰度值)。因为编程时不需要那么高的精确度,所以一般软件用的是精确到小数点后面3位的公式:

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

c = 0.299*r + 0.587*g + 0.114*b

ITU-R BT.709

另一个普遍使用的推荐标准是BT.709,它使用的标准光源是D6565表示相关色温是6504°K,它的白色坐标为(0.312713,0.329016),这种标准的灰度(Y)值算法公式为:

Y = 0.212649*R + 0.715169*G + 0.072182*B

一般情况下精确到小数点后面3位,于是:

Gray = 0.213*R + 0.715*G + 0.072*B

c = 0.213*r + 0.715*g + 0.072*b

ITU标准(ITU standard)

近年来,ITU-R介绍了新的推荐标准,称为ITU标准(ITU/EBU 3213 standard)。它对RGB颜色空间中绿色坐标作了变动,但标准白光仍然是D65,坐标为(0.312713,0.329016),这种标准的灰度(Y)值算法公式为:

Y = 0.222015*R + 0.706655*G + 0.071330*B

精确到小数点后面3位:

Gray = 0.222*R + 0.707*G + 0.071*B

c = 0.222*r + 0.707*g + 0.071*b

LabL算法

 

 

观察上图的彩虹条,我们凭感觉可以看出绿色的部分亮度分布是比较均匀的,而BT.601的算法明显的在绿色范围的中央产生一个较暗的渐变色带。这是因为CIE色度图是个不规则的马蹄形,而RGB加权算法是线性的,所以有时我们需要通过Gamma修正来减小失真。

BT.601 Gamma 2.2的灰度公式:

Gray = (0.3*R2.2 + 0.59*G2.2 + 0.11*B2.2)1/2.2

c=(0.3*r^2.2 + 0.59*g^2.2 + 0.11*b^2.2)^(1/2.2)

Lab颜色空间是直接从CIE XYZ导出的,因此基于Lab的灰度算法是最标准的、最接近人视觉的算法。Phothshop的灰度模式(Grayscale)Lab模式ab的色度信息都为0时的效果。Lab(L)Lab模式的L亮度通道,比灰度模式稍亮。Lab的具体算法,将在关于Lab颜色空间的文章中详细讲述。

总结

本文讲述的所有灰度算法的比较图:

 

 

 

基础算法中的Gray=Max(R,G,B)Gray=(Max(R,G,B)+Min(R,G,B))/2这两个公式很重要,因为经常用到的HSVHSL颜色空间的亮度就是用它们来计算的。

ITU的标准,是目前应用最为普遍的计算亮度方法。YUVYIQYCbCrY值、JPEG图片、DVD、电视、电影基本上都是用了这三个标准之一。从网上流传的源代码来看,用ITU-R BT.601标准的最多,Photoshop中的标准亮度公式用的也是BT.601标准。

基于Lab的算法最接近人的视觉。

相关知识

CIE(国际发光照明委员会)

CIE,原文为Commission Internationale de L'Eclairage()International Commission on Illumination()。这个委员会创建的目的是要建立一套界定和测量色彩的技术标准。可回溯到1930年,CIE标准一直沿用到数字视频时代,其中包括白光标准(D65)和阴极射线管(CRT)内表面红、绿、蓝三种磷光理论上的理想颜色。

CCIR,ITU

与广播电视最密切的国际标准组织是原来的(Consultative Committee of International Radio Communication)CCITT(Consultative Committee of InternationalTelegraph and TelePhone) 一起分别负责广播电视和通信的全球协调,两者都曾是国际电信联盟ITU(Intenatioonal Telecommunication Union)的分支机构。

1993ITU进行重组,成为三个部门。199331日原CCIR更名为ITU-R(ITU-Radio Communication Sector)ITU-R的主要工作是确保无线电频率和卫星轨道为所有国家平等、有效和经济地得到利用。

 

编程实现ITU-R BT.601重点介绍

一、基础
  rgb2grayformulaGray = 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

  但是,虽说上一个公式是32位整数运算,但是根据80x86体系的整数乘除指令的特点,是可以用16位整数乘除指令来运算的。而且现在32位早普及了(AMD64都出来了),所以推荐使用上一个公式。

三、整数移位算法

  上面的整数算法已经很快了,但是有一点仍制约速度,就是最后的那个除法。移位比除法快多了,所以可以将系数缩放成 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

 

抱歉!评论已关闭.