颜色空间系列2: RGB和CIELAB颜色空间的转换及优化算法

本文探讨了RGB与CIELAB颜色空间之间的快速转换算法,通过XYZ颜色空间作为中介。作者强调了在转换过程中优化的重要性,如使用查表法和避免浮点运算,以提高效率。通过特定的数学处理和内存管理技巧,实现了高效的颜色空间转换,适用于大型图像处理任务。
摘要由CSDN通过智能技术生成

       颜色空间系列代码下载链接:http://files.cnblogs.com/Imageshop/ImageInfo.rar (同文章同步更新)

      在几个常用的颜色空间中,LAB颜色空间是除了RGB外,最常用的一种之一,不同于RGB色彩空间,Lab 颜色被设计来接近人类视觉。它致力于感知均匀性,它的 L 分量密切匹配人类亮度感知。因此可以被用来通过修改 a 和 b 分量的输色阶来做精确的颜色平衡,或使用 L 分量来调整亮度对比。这些变换在 RGB 或 CMYK 中是困难或不可能的,它们建模物理设备的输出,而不是人类视觉感知。

     关于CIELAB颜色空间的更多原理说明,可见:http://en.wikipedia.org/wiki/Lab_color_space

     本文研究的重点是RGB和LAB之间的快速转换过程。

     首先,RGB和LAB之间没有直接的转换公式,其必须用通道XYZ颜色空间作为中间层,关于RGB和XYZ颜色空间的转换及优化,详见颜色空间系列1

     XYZ------>LAB转换公式如下:一般情况下我们认为Yn,Xn,Zn都为1。

 

     \begin{align}   L^\star &= 116 f(Y/Y_n) - 16\\   a^\star &= 500 \left[f(X/X_n) - f(Y/Y_n)\right]\\   b^\star &= 200 \left[f(Y/Y_n) - f(Z/Z_n)\right] \end{align}

其中

     f(t) = \begin{cases}   t^{1/3} & \text{if } t > (\frac{6}{29})^3 \\   \frac13 \left( \frac{29}{6} \right)^2 t + \frac{4}{29} & \text{otherwise} \end{cases}

      在上述表达式中,X,Y,Z及t变量的取值范围都是[0,1],对应的L分量的取值范围为[0,100],A和B分量都为[-127,127],因此,如果把L拉升至[0,255],把A,B位移至于[0,255],就可以同RGB颜色空间表达为同一个范围了。即使这样映射后,一般来说,LAB各分量的结果仍为浮点数,这个和RGB不同,但是在很多情况下,为了速度计效率,我们这需结果的取整部分,得到类似于RGB空间的布局。因此,对这类结果的优化更有实际意义。

      关于这样的优化,OpenCv已经做了非常好的工作,各位看客也可以先看看OpenCv的代码,本文未直接沿用其优化,但本文的算法更简单明了,在保证结果无明显变化的同时,速度和效率都有30%以上的提升。

      第一步,我们来看看f(t)这个函数的优化,f(t)是个分段函数,如果直接在函数体中判断,会多一些跳转和比较语句,不利于CPU的流水线工作,因此,我考虑的第一步是是否能用查表法来做。

     在颜色空间系列1文章中,我们知道,转换后的XYZ值得范围是[0,255],而这里的t值范围为[0,1],把if t>(6/29)^3这个算法映射到[0,255],则为 if t>2.26 ,因为XYZ都为整数,即此条件和if t>2等价,可见这里会出现一些漏判点;考虑2.26这个数字的特点,如果我们在把这个结果放大4倍,即XYZ范围为[0,1020],则判断条件随之升级为if t>9.04,取整if t>9,则漏判现象大为减少。这是提的第一点。

     接着上面,这样的话我们就定义一个查找表,查找表大小应该和XYZ的域相同的,即上面的1020(我更喜欢1024),对于表中的元素值,为求速度,当然必须为int 类型,

也就是说,需要把计算出来的小数值放大一定倍数。这里不多说,见下面的代码:

    for (I = 0; I < 1024; I++)
    {
        if (I > Threshold)
            LabTab[I] = (int)(Math.Pow((float)I / 1020, 1.0F / 3) * (1 << Shift) + 0.5 );
        else
            LabTab[I] = (int)((29 * 29.0 * I / (6 * 6 * 3 * 1020) + 4.0 / 29) * (1 << Shift) + 0.5 );
    }

     C#语言是强类型语言,一定要注意运算式中各变量的类型,比如上式中的1.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值