从RGB到Lab色彩空间的转换

来源:互联网 发布:苹果ios软件开发 编辑:程序博客网 时间:2024/05/18 22:11

导读:RGBLab色彩空间的转换,色彩模型除了最常见的RGB以外,故人们一般也只能找到XYZLab之间的转换,而RGBLab的转换只能使用XYZ作为中间模式间接进行,我们可以先观察RGBXYZ的转换:,RGB是经过Gamma校正的色彩分量:R=g(r),其中rgb为原始的色彩分量,以及XYZLab的转换:,非RGB色彩数据的绝对值并不重要,上面的从XYZLab的转换乍一看起来很奇怪,从RGBLab色彩空间的转换。色彩模型除了最常见的RGB以外,还有HSBYCbCrXYZLab等。HSB一般仅仅作为图像处理过程中的临时模式,YCbCr常常用于图像的压缩处理,而XYZ则严格按照人眼对光信号的敏感度进行分布。

这里将要稍作讨论的便是Lab模型。网络上诸多的介绍都说Lab是基于XYZ的,故人们一般也只能找到XYZLab之间的转换,而RGBLab的转换只能使用XYZ作为中间模式间接进行。可惜的是,这种现状源于误解。而在图像处理软件中(比如Photoshop),往往采用一个更为简单的算法。

我们可以先观察RGBXYZ的转换:

[X,Y,Z] = [M] *[R,G,B]

其中M为一3x3矩阵:

[M] = [0.4125,0.3576, 0.1805;

0.2126, 0.7152,0.0722;

0.0193, 0.1192,0.9505]

RGB是经过Gamma校正的色彩分量:R=g(r)G=g(g)B=g(b)

其中rgb为原始的色彩分量。

gGamma校正函数:

x < 0.018时,g(x) = 4.5318 *x

x >= 0.018时,g(x) = 1.099 *d^0.45 - 0.099

rgb以及RGB的取值范围则均为[0,1)。计算完成后,XYZ的取值范围则有所变化,分别是:[0, 0.9506)[0, 1)[0, 1.0890)

以及XYZLab的转换:

L = 116 * f(Y1)- 16

a = 500 * (f(X1)- f(Y1))

b = 200 * (f(Y1)- f(Z1))

其中f是一个类似Gamma函数的校正函数:

x > 0.008856时,f(x) = x^(1/3)

x <= 0.008856时,f(x) = ( 7.787 *x ) + ( 16 / 116 )

X1Y1Z1分别是线性归一化之后的XYZ值,也就是说,它们的取值范围都是[0, 1)。此外,函数f的值域也和自变量一样都是[0, 1)

计算完成后,L的取值范围[0, 100),而ab则约为[-169, +169)[-160, +160)在观察这些貌似复杂的变换之前,我们必须确定的一个假设是:在图像处理软件中,非RGB色彩数据的绝对值并不重要,重要的是他们能够尽可能准确的还原成RGB图像以显示在屏幕等相关设备上。这个假设是我们的简化得以成立的理由。

上面的从XYZLab的转换乍一看起来很奇怪,但若是仔细观察,不难发现LY1只是一个简单的同区间映射关系,这个映射其实可有可无(如果进行了映射反而必定导致色阶丢失)。

这样,我们取得的第一个简化是:L = Y1

接下来接着看ab的映射过程。大家不难发现,ab其实是一个色差信号(跟CbCr的性质差不多)。至于它们的转换系数500200,大家可以完全忘记,因为他们的值域并不符合8位整数值的表达需要。我们将会稍后计算出合适的因数,使得ab都处在[0, 255]的范围内。

因为XYZ必须归一化转为X1Y1Z1,那么我们其实可以在转换矩阵M中作出这个修改,令每行乘以一个系数以使得每行各数之和为1

[M1] = [0.4339,0.3762 0.1899;

0.2126, 0.7152,0.0722;

0.0177, 0.1095,0.8728]

于是乎,我们得出一个半成品:

L = Y1 = 0.2126* R + 0.7152 * G + 0.0722 * B

a = Fa * (X1 -Y1) + Da

b = Fb * (Y1 -Z1) + Db

其中的Fx是调整值域用的系数,Dx是一个正数,用来消除ab的负值。FxDx的选取必须令ab满足值域在[0, 255]上的分布。

接下来我们来确定FxDx的值。通过M1我们很容易计算出X1-Y1的值域(极端情况)为[-86.784, +86.784),而Y1-Z1的值域则为[-204.9536, +204.9536)。于是乎,Fa的值为1.4749Fb的值为0.6245DaDb则都是128

这时,代入M1有:

L = Y1 = 0.2126* R + 0.7152 * G + 0.0722 * B

a = 1.4749 *(0.2213 * R - 0.3390 * G + 0.1177 * B) + 128

b = 0.6245 *(0.1949 * R + 0.6057 * G - 0.8006 * B) + 128

其中RGBLab的取值范围都是[0,255]

最后的一点工作是算法的优化。我们可以将这个方程组转换成常整数乘法与移位的方式(相当于使用定点数)。为了方便阅读,我仍然将移位写为除法。

所以我们的最终结果为:

L = Y1 = (13933* R + 46871 * G + 4732 * B) div 2^16

a = 377 * (14503* R - 22218 * G + 7714 * B) div 2^24 + 128

b = 160 * (12773* R + 39695 * G - 52468 * B) div 2^24 + 128

至于逆变换则可以用类似的方法推导出来:

L1=La1=(a-128)*174b1=(b-128)*410,有:

R = L1 + (a1 *100922 + b1 * 17790) div 2^23

G = L1 - (a1 *30176 + b1 * 1481) div 2^23

B = L1 + (a1 *1740 - b1 * 37719) div 2^23

其中RGBLab的取值范围都是[0,255],再经过逆Gamma函数取得原始的rgb

以上的算法在Delphi中编译通过。经测试,运算得出的直方图与图片观感和我手头的Photoshop CS的结果非常相似,但也有一些幅度上的差别,且容以后慢慢细察。


0 0
原创粉丝点击