RGB转Lab的那些事(一)

article/2025/10/6 13:43:25

Matlab与OpenCV都有RGB转Lab的具体实现,然而两种版本给出的结果似乎并不一样,那么两者有何区别呢?

首先了解RGB转Lab的理论知识:

一般地,由RGB转Lab都需要先将RGB转为XYZ,再由XYZ转为Lab。通常我们获取的图片往往是sRGB格式的

sRGB (“standard RGB” [41]) was developed (jointly by Hewlett-Packard and Microsoft) with the goal of creating a precisely specified color space for these applications, based on standardized mappings with respect to the col-orimetric CIE XYZ color space.

Several standard image formats, including EXIF (JPEG) and PNG are based on sRGB color data, which makes sRGB the de facto standard for dig-ital still cameras, color  rinters, an d other imaging devices at the consumer level.

Thus, in practice, working with any RGB color data almost always means dealing with sRGB.

sRGB is a nonlinear color space with respect to the XYZ coordinate system, and it is important to carefully distinguish between the linear and nonlinear RGB component values. The nonlinear values (denoted R', G', B') represent the actual color tuples, the data valu es read from an image file or received from a digital camera.

也就是说我们通常获取的图片是非线性颜色空间的sRGB格式,需要将sRGB转为线性颜色空间的RGB

格式(这一步即为gamma矫正过程)

 

注意:Matlab与OpenCV的gamma常数好像都是取得0.04045,而不是0.03928

XYZ转Lab的公式如下:

至此,RGB转Lab的理论说明已经很清楚,其实大致的步骤和网络上的资源也很类似,只是细节方面有一些不一样的地方。Matlab与OpenCV的差别就在于

线性映射矩阵M_RGB与白色参考点,Matlab用的是D50,而OpenCV用的是D65。

首先来看一看Matlab的RGB转Lab的D65、D50实现:

function [L, a, b] = sRGB2LabD50(sR, sG, sB)
% SRGB2LAB convert sRGB to CIELAB(Matlab implemention).
% 
if nargin == 1sB = double(sR(:,:,3));sG = double(sR(:,:,2));sR = double(sR(:,:,1));
end% normalize for [0 1]
if max(max(sR)) > 1.0 || max(max(sG)) > 1.0 || max(max(sB)) > 1.0sR = double(sR) / 255;sG = double(sG) / 255;sB = double(sB) / 255;
end[M, N] = size(sR);
s = M * N;
sRL = reshape(sR, 1, s);
sGL = reshape(sG, 1, s);
sBL = reshape(sB, 1, s);% gamma correction (gamma 2.2)
gammaConst = 0.04045; 
sRL = ( sRL<=gammaConst ) .* sRL  ./ 12.92 +  ...( ( sRL>gammaConst  ) .* (0.055 + sRL) ./ 1.055 )  .^2.4;
sGL = ( sGL<=gammaConst ) .* sGL  ./ 12.92 +  ...( ( sGL>gammaConst  ) .* (0.055 + sGL) ./ 1.055 )  .^2.4;
sBL = ( sBL<=gammaConst ) .* sBL  ./ 12.92 +  ...( ( sBL>gammaConst  ) .* (0.055 + sBL) ./ 1.055 )  .^2.4;RGB = [sRL; sGL; sBL];% linear map
MAT = [0.436052025 0.385081593 0.1430874140.222491598 0.716886060 0.0606214860.013929122 0.097097002 0.714185470];  % D50XYZ = MAT * RGB;
XYZ = XYZ';% normalize for white point
wp = [0.964296 1.0 0.825106];         % D50XYZ = bsxfun(@rdivide, XYZ, wp);% cube root normalized xyz
fxyz_n = XYZ .^ (1/3);
% if normalized x, y, or z less than or equal to 216 / 24389 apply function 2  
L = XYZ <= 216 / 24389;
% function 2
k = 841 / 108;
fxyz_n(L) = k * XYZ(L) + 16/116;
clear XYZ L;LAB = zeros(s,3);
% calculate L*  
LAB(:,1) = 116 * fxyz_n(:,2) - 16;
% calculate a*  
LAB(:,2) = 500 * (fxyz_n(:,1) - fxyz_n(:,2));
% calculate b*  
LAB(:,3) = 200 * (fxyz_n(:,2) - fxyz_n(:,3));% do the scale and offset and cast to uint8
LAB = round([(255 * (LAB(:,1)/100)) LAB(:,2)+128 LAB(:,3)+128]);
LAB = max(0, min(255, LAB));
LAB = uint8(LAB);L = reshape(LAB(:,1), M, N);
a = reshape(LAB(:,2), M, N);
b = reshape(LAB(:,3), M, N);if nargout < 2L = cat(3, L, a, b);
end


 

function [L, a, b] = sRGB2LabD65(sR, sG, sB)
% SRGB2LAB convert sRGB to CIELAB(Matlab implemention).
% 
if nargin == 1sB = double(sR(:,:,3));sG = double(sR(:,:,2));sR = double(sR(:,:,1));
end% normalize for [0 1]
if max(max(sR)) > 1.0 || max(max(sG)) > 1.0 || max(max(sB)) > 1.0sR = double(sR) / 255;sG = double(sG) / 255;sB = double(sB) / 255;
end[M, N] = size(sR);
s = M * N;
sRL = reshape(sR, 1, s);
sGL = reshape(sG, 1, s);
sBL = reshape(sB, 1, s);% gamma correction (gamma 2.2)
gammaConst = 0.04045; 
sRL = ( sRL<=gammaConst ) .* sRL  ./ 12.92 +  ...( ( sRL>gammaConst  ) .* (0.055 + sRL) ./ 1.055 )  .^2.4;
sGL = ( sGL<=gammaConst ) .* sGL  ./ 12.92 +  ...( ( sGL>gammaConst  ) .* (0.055 + sGL) ./ 1.055 )  .^2.4;
sBL = ( sBL<=gammaConst ) .* sBL  ./ 12.92 +  ...( ( sBL>gammaConst  ) .* (0.055 + sBL) ./ 1.055 )  .^2.4;RGB = [sRL; sGL; sBL];MAT = [0.412453 0.357580 0.180423;0.212671 0.715160 0.072169;0.019334 0.119193 0.950227];   % D65XYZ = MAT * RGB;
XYZ = XYZ';% normalize for white point
wp = [0.950456 1.0 1.088754];         % D65XYZ = bsxfun(@rdivide, XYZ, wp);% cube root normalized xyz
fxyz_n = XYZ .^ (1/3);
% if normalized x, y, or z less than or equal to 216 / 24389 apply function 2  
L = XYZ <= 216 / 24389;
% function 2
k = 841 / 108;
fxyz_n(L) = k * XYZ(L) + 16/116;
clear XYZ L;LAB = zeros(s,3);
% calculate L*  
LAB(:,1) = 116 * fxyz_n(:,2) - 16;
% calculate a*  
LAB(:,2) = 500 * (fxyz_n(:,1) - fxyz_n(:,2));
% calculate b*  
LAB(:,3) = 200 * (fxyz_n(:,2) - fxyz_n(:,3));% do the scale and offset and cast to uint8
LAB = round([(255 * (LAB(:,1)/100)) LAB(:,2)+128 LAB(:,3)+128]);
LAB = max(0, min(255, LAB));
LAB = uint8(LAB);L = reshape(LAB(:,1), M, N);
a = reshape(LAB(:,2), M, N);
b = reshape(LAB(:,3), M, N);% keyboard
if nargout < 2L = cat(3, L, a, b);
end


测试程序:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc; clear all;
close all;% initial image
N = 100;
I = uint8( zeros(N, N, 3) );
level = 0 : N-1;
for ii = 1: length( level )I(ii, :, 1) =  circshift(level, [0 ii]);I(ii, :, 2) =  circshift(level, [0 -ii]);I(ii, :, 3) =  circshift(level, [0 ii+2]);
end% rgb2lab (matlab built-in function)
sRGB2LabForm = makecform('srgb2lab');
labImageBuiltIn = applycform(I, sRGB2LabForm);
figure('Name', 'Matlab built-in function');  imshow(labImageBuiltIn);% rgb to lab function 
labImageForMatlab = sRGB2LabD50(I);
figure('Name', 'One step function'); imshow(labImageBuiltIn);% difference of two version
diffValue = double(labImageBuiltIn) - double(labImageForMatlab);
h = figure('Name', 'Difference of two version', 'NumberTitle', 'off'); 
subplot(2, 2, 1);  mesh(diffValue(:, :, 1));  title('Difference L'); view([0 0]);
subplot(2, 2, 2);  mesh(diffValue(:, :, 2));  title('Difference A'); view([0 0]);
subplot(2, 2, [3 4]);  mesh(diffValue(:, :, 3));  title('Difference B'); view([0 0]);


 

实验结果:

 

 

                                    (a) matlab自带函数的sRGB转Lab                                                                        (c) sRGB转Lab D50实现

                                                                                                             

                                   (c) sRGB转Lab D65实现                                                                             (d) 对比结果 D50实现

 

(5) 对比结果 D65实现

 

从实验结果可以发现,D50的实现与Matlab自带的RGB转Lab差别都在1像素之内(这可以理解为中间计算误差),而D65的实现与Matlab自带的误差很明显。

参考资料:

Principles of Digital Image Processing: Fundamental Techniques.  Wilhelm Burger, Mark J. Burge


http://chatgpt.dhexx.cn/article/4P3pRlFX.shtml

相关文章

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;对人脸皮肤分割结果进…

彩色图像--色彩空间 CIELAB、CIELUV

学习DIP第65天 转载请标明本文出处&#xff1a;http://blog.csdn.net/tonyshengtan &#xff0c;出于尊重文章作者的劳动&#xff0c;转载请标明出处&#xff01;文章代码已托管&#xff0c;欢迎共同开发&#xff1a;https://github.com/Tony-Tan/DIPpro 更多图像处理机器学习内…

【视觉基础篇】10 # 图形系统如何表示颜色?

说明 【跟月影学可视化】学习笔记。 RGB 和 RGBA 颜色 RGB 和 RGBA 的颜色表示法 #RRGGBB 是 RGB 颜色的十六进制表示法&#xff0c;其中 RR、GG、BB 分别是两位十六进制数字&#xff0c;表示红、绿、蓝三色通道的色阶。 色阶可以表示某个通道的强弱。 每个通道一共有 25…

CIELab图像的通道分解与合成

import cv2 import numpy as np lotus cv2.imread(lotus.jpg) showImgByPlot(lotus,10,6) lotus_lab cv2.cvtColor(lotus, cv2.COLOR_BGR2LAB) l, a, b cv2.split(lotus_lab) #! featureMat cv2.merge([l, a, b]) #! merge失败 featureMat np.dstack((l, a, b)).astype(np…

CIELab和LCH的色彩空间图

资料来源&#xff1a;http://www.18show.cn/share_news/599547.html CIE Lab&#xff1a; LAB色空间是基于一种颜色不能同时既是蓝又是黄这个理论而建立。所以CIE Lab&#xff0c;单一数值可用于描述红/绿色及黄/蓝色特徽。当一种颜色用CIE L*a*b*时&#xff0c;L* 表示明度值…

CIELAB色差计算

CIE色差计算就是在之前Lab颜色空间进行的。色差一般指的是由于位置不同或者放大率不同所造成的颜色差异。而在图像处理领域&#xff0c;尤其是针对色彩的处理中&#xff0c;很重要的一点就是消除色差。那么接下来我们就讨论CIE色差公式的改进过程&#xff0c;每次改进的意义&am…