RGB图像转换到CIELab空间的研究及优化

article/2025/10/6 4:06:03

第一次写博客,没有太多经验,初入图像处理方向的炒鸡菜鸟,看着大神们都有自己的博客,而且总是学习大神的文章,心里除了满满的敬佩,还有一丝丝的失落,后悔自己当初读本科时没学计算机方向,现在研究僧半路出家学图像,没有太多计算机基础,很多东西都是自己重新学习摸索,非常吃力,编程神马的真是效率超低,本文的这个小程序整整花费一天才写好,,,无语了。。。
废话不多说,作为处女作,难免会有很多写的不周到的地方,还请大家批评指正。
************************ 忧桑的分割线 ***************************
此文主要参照了laviewpbt大神的两篇文章,目前仅仅做了RGB到Lab的转换,反变换暂时未做
CIELAB颜色空间的更多原理说明见:
http://en.wikipedia.org/wiki/Lab_color_space
laviewpbt大神的两篇文章:
http://www.cnblogs.com/Imageshop/archive/2013/01/31/2888097.html
http://www.cnblogs.com/Imageshop/archive/2013/02/02/2889897.html

下面仅仅是简单说明一下,因为细节问题在以上两篇博文里已经说的很详细了

(1)主要流程: RGB->XYZ->Lab

(2)公式:

R=γ(r255.0)G=γ(g255.0)B=γ(b255.0)r,g,b[0,255](1)

γ(x)=(x+0.0551.055)2.4x12.92x>0.04045otherwise(2)

XYZ=MRGB(3)

M=0.4339530.2126710.0177580.3762190.7151600.1094770.1898280.0721690.872765(4)

M的取值是直接取了laviewpbt大神文章中归一化好的值。
L=116f(YYN)16a=500[f(XXN)f(YYN)]b=200[f(YYN)f(ZZN)](5)

f(t)={t37.787tt>0.008856otherwise(6)

XYZ->Lab的公式参考 冈萨雷斯的 数字图像处理 第3版 阮秋琦译 p273

(3) 优化

通过以上公式可以发现,整个计算过程中涉及到大量的浮点运算,对于PC应该还可以顶住,如果你的程序要在嵌入式系统中跑,这么大量的浮点运算对CPU是很大的开销,所以需要对其进行优化。优化的方法首先想到就是查表,用空间换时间,其次就是用移位代替除法,用整形替换浮点型。主要的需要用到优化的有以下几点:

  1. 公式(1)和公式(2)的自变量有256个固定的值,即[0,255],故公式中的除法与乘方运算可以将浮点型变成整型,做成查找表;
  2. M矩阵中全部为浮点型数据,需要转换成整形计算;
  3. 公式(6)又涉及到浮点型数据运算和有限个自变量的问题,依然需要转换类型并做成查找表;

RGB三通道的值在[0,255]之间变化,而且公式(2)的值域在[0,1]之间,为将浮点型转换成整型,对其放大1024倍,即左移10位,实现如下:

int gammatable[256];
memset(gammatable, 0, 256 * sizeof(int));
for(i = 0; i < 11; i++)gammatable[i] = (i / 3294.6) * 1024;
for(; i < 256; i++)gammatable[i] = (pow((i + 14.025) / 269.025, 2.4)) * 1024;

M矩阵放大 220 倍,即左移20位,用Matlab计算得到数据如下(我承认我偷懒了):

M3 =1.0e+05 *
4.5503    3.9449    1.9905
2.2300    7.4990    0.7567
0.1862    1.1479    9.1516

f(t) 的计算可以用查表,以为前面的计算总共移位30位,在计算出 [X,Y,Z]T 后需要先将处理M时所乘的 220 移回来的, f(t) 的值域为[0,1],充分利用还剩下的10位未移回来的位,将其放大1024倍,即:XYZ的三个分量仅有1024种取值,可以作为Lab的输入。

int ftable[1024];
memset(ftable, 0, 1024 * sizeof(int));
for(i = 0; i < 1024; i++)ftable[i] = (i > 9) ? pow((float)i / 1024, 1.0 / 3) * 1024 + 0.5 : (7.787 * i + 141.2413);

L 的值域为[0,100],a b <script type="math/tex" id="MathJax-Element-14">b</script>的值域分别为[-169,169],[-160,160],至于怎么知道的,我也忘了从哪里看的,总之它是对的,有了这个值域,就可以做查找表了,而且在之后的归一化到[0,255]范围内以方便显示查看是有帮助的。

    int Ltable[100];int atable[338];int btable[320];memset(Ltable, 0, 100 * sizeof(int));memset(atable, 0, 338 * sizeof(int));memset(btable, 0, 320 * sizeof(int));for(i = 0; i < 100; i++)Ltable[i] = (float)i / 100 * 255;for(i = 0; i < 338; i++)atable[i] = (float)i / 338 * 255;for(i = 0; i < 320; i++)btable[i] = (float)i / 320 * 255;

如此全部的优化工作做完,可以开森的查表了(可能有人会说:L,a,b的计算中只有整型除法,没必要查表,,,对于一个强迫症晚期的人来说,这种缺陷是无法容忍的)

(4) 实现

全部工作做完,给出全部代码,纯C版(其实我对C++很凌乱,不要鄙视我,我是半路出家学这玩意儿的,刚入门)

/*** @brief RGB空间转换到Lab空间,结果已经归一化到[0,255]以方便显示,效果与OpenCV自带函数效果一致* @param rgb* @param width* @param height* @return lab空间图像数据首地址*/
unsigned char* rgb2lab(unsigned char* rgb, int width, int height)
{unsigned char *lab;int gammatable[256];int ftable[1024];int Ltable[100];int atable[338];int btable[320];int L, a1, b1;long long *X, *Y, *Z;int i, r, g, b;unsigned char *pCur, *pEnd;if((lab = (unsigned char*)malloc(width * height * 3 * sizeof(unsigned char))) == NULL){printf("No space distributed for CIE_Lab!\n");return NULL;}if((X = (long long*)malloc(width * height * sizeof(long long))) == NULL){printf("No space distributed for X in CIE_XYZ!\n");return NULL;}if((Y = (long long*)malloc(width * height * sizeof(long long))) == NULL){printf("No space distributed for Y in CIE_XYZ!\n");return NULL;}if((Z = (long long*)malloc(width * height * sizeof(long long))) == NULL){printf("No space distributed for Z in CIE_XYZ!\n");return NULL;}//创建伽马校正的查找表,将浮点数转变成整数,放大1024倍memset(gammatable, 0, 256 * sizeof(int));for(i = 0; i < 11; i++)gammatable[i] = (i / 3294.6) * 1024;for(; i < 256; i++)gammatable[i] = (pow((i + 14.025) / 269.025, 2.4)) * 1024;// XYZ2LAB查找表memset(ftable, 0, 1024 * sizeof(int));for(i = 0; i < 1024; i++)ftable[i] = (i > 9) ? pow((float)i / 1024, 1.0 / 3) * 1024 + 0.5 : (7.787 * i + 141.2413);//归一化到[0,255]的查找表(由于涉及到浮点除法)memset(Ltable, 0, 100 * sizeof(int));memset(atable, 0, 338 * sizeof(int));memset(btable, 0, 320 * sizeof(int));for(i = 0; i < 100; i++)Ltable[i] = (float)i / 100 * 255;for(i = 0; i < 338; i++)atable[i] = (float)i / 338 * 255;for(i = 0; i < 320; i++)btable[i] = (float)i / 320 * 255;for(i = 0, pCur = rgb, pEnd = rgb + width * height * 3; pCur < pEnd; i++){b = *pCur++;g = *pCur++;r = *pCur++;//M矩阵系数被放大了2^20倍,结果需要移位20位X[i] = (gammatable[b] * 199049 + gammatable[g] * 394494 + gammatable[r] * 455033 + 524288) >> 20;Y[i] = (gammatable[b] * 75675 + gammatable[g] * 749900 + gammatable[r] * 223002 + 524288) >> 20;Z[i] = (gammatable[b] * 915161 + gammatable[g] * 114795 + gammatable[r] * 18621 + 524288) >> 20;}for(i = 0, pCur = lab, pEnd = lab + width * height * 3; pCur < pEnd; i++){L = (116 * ftable[Y[i]] - 16 * 1024) >> 10;a1 = (500 * (ftable[X[i]] - ftable[Y[i]])) >> 10;b1 = (200 * (ftable[Y[i]] - ftable[Z[i]])) >> 10;*pCur++ = Ltable[L];*pCur++ = atable[a1 + 169];*pCur++ = btable[b1 + 160];}free(X);free(Y);free(Z);return lab;
}

原图如下,来源于MSRA10K
MSRA_0_0_77
与OpenCV中的rgb2lab比较,可以得出如下结果:
RGB2Lab
OpenCV_lab是OpenCV版的结果,mxnLib_lab是本文中代码实现的结果,可以看出二者还是很一致的!
********************************** 我是分割线 ************************************
今天就写到这里把,总之都是第一次,第一次在CSDN写博客,第一次使用CSDN的markdown编辑器,在线学习了LaTex公式格式,很不熟练,花费了整整一晚上的时间才码完。欢迎各位提出意见,如果错误,请提出批评指正。


http://chatgpt.dhexx.cn/article/bCV653Fd.shtml

相关文章

CIC滤波器的matlab仿真与实现

CIC滤波器的matlab仿真与实现 介绍 在数字信号处理中&#xff0c;由于后级硬件如FPGA的处理速度无法跟上前级ADC的采样速度&#xff0c;因此需要对ADC的采样数据进行降速处理&#xff0c;也就是对采样数据进行抽取&#xff0c;简单的抽取描述就是对其中连续几个点取一个点进行…

RGB颜色空间与Lab颜色空间区别与联系(附转换代码)

RGB颜色空间 RGB颜色是红色&#xff08;Red&#xff09;、绿色&#xff08;Green&#xff09;和蓝色&#xff08;Blue&#xff09;三基色的字母缩写。RGB色彩模式是通过三种基本颜色的不同程度的迭加来产生各种各样的不同颜色。这个标准能够涵盖人类视力所能感知的所有颜色&am…

matlab中的xlabel, ylabel, zlabel

随时随地阅读更多技术实战干货&#xff0c;获取项目源码、学习资料&#xff0c;请关注源代码社区公众号(ydmsq666) 标注x&#xff0c;y和z轴 语法 xlabel(string) xlabel(fname) xlabel(...,PropertyName,PropertyValue,...) xlabel(axes_handle,...) h xlabel(...) ylabel…

在CIELab颜色空间下使用八方向Sobel算子实现边缘检测

参考河北师范大学硕士学位论文——基于八方向Sobel算子的边缘检测算法研究。 由于自己实现滤波器运算&#xff0c;计算速度很慢&#xff0c;以后有能力再进行改进。 算子定义如下&#xff1a; 算法思路&#xff1a; 1.将RGB图像转化为CIELab颜色空间的图像。 2.计算不同方…

RGB转Lab的那些事(一)

Matlab与OpenCV都有RGB转Lab的具体实现&#xff0c;然而两种版本给出的结果似乎并不一样&#xff0c;那么两者有何区别呢&#xff1f; 首先了解RGB转Lab的理论知识&#xff1a; 一般地&#xff0c;由RGB转Lab都需要先将RGB转为XYZ&#xff0c;再由XYZ转为Lab。通常我们获取的…

CIE颜色空间

国际照明委员会&#xff08;CIE&#xff0c;Commission Internationale de LEclairage / International&#xff09;的色度模型是最早使用的模型之一。它是三维模型&#xff0c;其中&#xff0c;x和y两维定义颜色&#xff0c;第3维定义亮度。 CIE 1931RGB 1.颜色匹配实验 根…

LAB色彩模型

LAB色彩模型 LAB色彩模式名称由来组成数值范围 优点设备无关。色域宽阔 Adobe photoshop中的LAB: LAB色彩模式 名称由来 Lab的全称是CIELAB&#xff0c;有时候也写成CIE Lab*。 是根据Commission International Eclairage&#xff08;CIE&#xff09;在1931年所制定的一种测定…

彻底搞懂Lab 颜色空间

本文参考wikipedia&#xff0c;并加入了自己的理解&#xff0c;有不对的地方多多指教~ 名称 在开始之前&#xff0c;先明确一下Lab颜色空间&#xff08;Lab color space&#xff09;的名字&#xff1a; - Lab的全称是CIELAB&#xff0c;有时候也写成CIE L*a*b* - 这里的CIE…

颜色空间之CIE色度模型

国际照明委员会&#xff08;CIE&#xff0c;Commission Internationale de LEclairage / International&#xff09;的色度模型是最早使用的模型之一。它是三维模型&#xff0c;其中&#xff0c;x和y两维定义颜色&#xff0c;第3维定义亮度。CIE在1976年规定了两种颜色空间。 一…

Matlab中CIC滤波器的应用

Matlab中CIC滤波器的应用 CIC滤波器基本原理 CIC&#xff08;积分梳状级联&#xff09;滤波器是工程上经常用的滤波器&#xff0c;因为CIC滤波器不需要乘法&#xff0c;CIC滤波器往往在级联抽取滤波器的第一级和级联插值滤波器的最后一级。这一节我们以CIC抽取滤波器为例来讲C…

OpenCV中Lab空间简介及RGB转Lab

Lab颜色模式简介&#xff1a; From&#xff1a;http://wenku.baidu.com/view/67b1b11f650e52ea551898f7.html OpenCV中使用cvCvtColor加CV_BGR2Lab转成CIELAB后取值范围&#xff1a; 有时根据需要&#xff0c;我们使用 cvCvtColor( img, img, CV_BGR2Lab );把色彩空间从RGB转换…

【CIC滤波器】基于MATLAB/FPGA的数字CIC滤波器的设计

FPGA代码&#xff1a; module down(i_clk,//输入时钟i_rst,//输入复位信号i_M, //抽取值i_data,//输入信号o_data,//输出信号r_clk);input i_clk;//输入时钟 input i_rst;//输入复位信号 input [7:0] i_M; //抽取值 input signe…

CIE RGB、CIE XYZ、 Lab空间转换

颜色空间转换 CIE RGB转化到CIE XYZCIE XYZ到Lab空间 CIE RGB转化到CIE XYZ 由于CIE RGB空间在描述色彩时会出现负值&#xff0c;因此为了方便计算&#xff08;1931年&#xff09;&#xff0c;CIE提出了一种新的色彩空间 CIE XYZ。 转换公式如下&#xff1a; 可见&#xff0c;…

【Matlab 图像】LAB 色彩空间分析

名称 在开始之前&#xff0c;先明确一下Lab颜色空间&#xff08;Lab color space&#xff09;的名字&#xff1a; Lab的全称是CIELAB&#xff0c;有时候也写成CIE Lab*这里的CIE代表International Commission on Illumination&#xff08;国际照明委员会&#xff09;&#xf…

C计算CIELAB、CIELUV均匀颜色空间中两种颜色的色差

C计算CIELAB、CIELUV均匀颜色空间中两种颜色的色差 ** 如何利用C语言计算两种颜色在CIELAB、CIELUV的总色差&#xff1f;例如&#xff1a;已知两颜色样品的色度值为&#xff1a;Y176.79&#xff0c;x10.4480&#xff0c; y10.3478&#xff1b;Y275.67&#xff0c;x20.4621&…

CIE颜色空间LCh、Lab、XYZ-sRGB介绍与转换关系(包含源码)

项目场景&#xff1a; 提示&#xff1a;在颜色科学中&#xff0c;LCh和Lab是比较常用的 LCh是由MATLAB计算出的数据&#xff0c;但是我所需要在Qt的q3dsurface绘制出这个切面&#xff0c;看了Qt官方Examples&#xff0c;墨西哥草帽算法的3D模型就是由XYZ组成的。所以我需要LC…

RGB和CIELAB颜色空间转换及偏色检测

RGB转为CIELAB 首先RGB是不可以直接转为CIELAB颜色空间的&#xff0c;RGB需要先转为CIEXYZ颜色空间&#xff0c;然后再由CIEXYZ颜色空间转为CIELAB颜色空间。关于这2个颜色空间的互转&#xff0c;主要参考了http://www.cnblogs.com/Imageshop/archive/2013/02/02/2889897.html…

sRGB转CIEXYZ转CIELAB,以及色彩距离

sRGB是标准色彩空间 是一个微软和惠普于1996年定义的标准色彩空间 如果想从sRGB转到CIEXYZ空间&#xff0c;要乘以这个矩阵&#xff1a; 得到CIEXYZ之后&#xff0c;可以再转成CIELAB&#xff1a; 其中 X 0 , Y 0 , Z 0 X_0, Y_0, Z_0 X0​,Y0​,Z0​是定义的参考白点&#…

深入理解color model(颜色模型)

什么是颜色 Wiki是这样说的&#xff1a;颜色或色彩是通过眼、脑和我们的生活经验所产生的一种对光的视觉效应。嗯&#xff0c;简单点说&#xff0c;颜色就是人对光的一种感觉&#xff0c;由大脑产生的一种感觉。感觉是一个很主观的东西&#xff0c;你怎么确定你看到的红色和我…

深度学习AI美颜系列---肤色相似度计算(CIELAB色差计算)

深度学习AI美颜系列---肤色相似度计算&#xff08;CIELAB色差计算&#xff09; 在AI美颜中&#xff0c;经常会用到肤色相似度计算&#xff0c;如何实现这个算法&#xff1f; 步骤如下&#xff1a; 1&#xff0c;人脸皮肤分割&#xff1b; 2&#xff0c;对人脸皮肤分割结果进…