色彩特性实验

第一章 要求

数字成像的作业,当时做的时候查了很多资料,现在把过程记录一下。
用matlab模拟Imatest的“colorcheck”模块编写一个色差处理程序。要求实现最基本功能:读入相机拍摄的色卡图像,用鼠标拖选单个色块区域,手动输入色块编号,程序可以自动计算色差ΔEab和ΔCab。24个色块的标准值选用爱色丽色卡的sRGB标称值,经XYZ空间转换到CIE Lab均匀颜色空间,在D65照明体下比较和显示色差。

第二章 色彩空间

2.1 色彩空间

所谓色彩空间,即一定的色彩范围,这是一种色彩模型。sRGB、AdobeRGB、ProPhotoRGB、CMYK等都是不同的色彩空间。它们都以可见光谱为基础,但分别包含不同的色彩范围。
色彩空间

2.2 sRGB色彩空间

sRGB色彩空间是惠普与微软于1996年一起开发的用于显示器、打印机以及因特网的一种标准RGB色彩空间。这种标准得到了W3C、Exif、英特尔、Pantone、Corel以及其它许多业界厂商的支持,在GIMP这样的开放源代码软件也支持这种标准,另外一些专有的或者像SVG这样的开放图形文件格式中也有应用。
sRGB定义了红色、绿色与蓝色三原色的颜色,即在其它两种颜色值都为零时该颜色的最大值。在CIE xy颜色坐标系中红色位于[0.6400, 0.3300]、绿色位于[0.3000, 0.6000]、蓝色位于[0.1500, 0.0600]、白色是位于[0.3127,0.3290]的D65。对于任何的RGB色彩空间来说,非负的R、G、B都不可能表示超出原色定义的三角形即色域范围,它刚好在人眼的色彩感知范围之内。

2.3 CIE Lab色彩空间

CIE(Commission International del’Eclairage)国际标准照明委员会于1931年建立了一系列表示可见光谱的颜色空间标准。它有三个基本量,用X、Y、Z表示,通过X、Y、Z能够表示任何一种颜色,X、Y、Z的值能够利用R、G、B线性表示出来,相对于RGB颜色空间,XYZ颜色空间几乎能包含人类能够感觉到的所有颜色,但XYZ颜色空间仍然是一种不均匀的颜色空间。因此在CIE-XYZ颜色空间的基础上又有了CIE-Lab,CIE-Luv等颜色空间。
国际照明委员会制定了Lab颜色空间,人类所能感觉到的任何颜色都可以在Lab颜色空间中表示出来,其颜色空间比RGB颜色空间还大,可以直接使用欧几里德距离来衡量两种颜色的差异性。这种模式是以数字化的方式来描述人的视觉感觉,它与显示器的色移、输出设备以及其他设备无关。Lab系统是一个优秀的亮度和彩色分离器,它在图像压缩方面很有用。其中L代表亮度,a的正方向代表红色,负方向代表绿色,b的正方向代表黄色,负方向代表蓝色。Lab颜色空间由XYZ转换而得
任意颜色在LAB空间都会有一个准确的数值表示而且和设备无关,任何单一色调背景下,用通道抠有明显颜色区别的部分,用LAB模式很快能完成;LAB模式下对明度(L)通道做任何操作(如锐化、模糊等)不会影响到色相;适合RGB通道抠的图大部分LAB模式能完成,反之不成立。

2.4 sRGB与CIE Lab的转换

2.4.1 sRGB到CIE XYZ的变换

首先对sRGB像素进行归一化处理(式2-1),在将归一化后的sRGB像素进行线性化。
在这里插入图片描述
将线性化的sRGB像素值转化为归一化的XYZ(D65)空间,根据IEC61922-2-1定义得:
在这里插入图片描述

2.4.2 CIE XYZ到CIE Lab的转换

在这里插入图片描述
其中
在这里插入图片描述

第三章 实验代码

3.1 流程图

在这里插入图片描述

3.2 爱色丽色卡

爱色丽色卡的sRGB、CIE Lab数值如图所示。
在这里插入图片描述

程序代码

首先建立色卡类,用来存放色卡的sRGB、CIE Lab数值及其其他属性。

classdef COLORCARD
    %COLORCARD-色卡
    %存放sRGB值 和 CIE Lab值
    properties
        %保持读入待检验色卡的数据
        card;
        %爱色丽色卡标准值
        sRGB = [ 115,82,68; 194,150,130; 98,122,157; 87,108,67; 133,128,177; 103,189,170; 
                 214,126,44; 80,91,166; 193,90,99; 94,60,108; 157,188,64; 224,163,46;
                 56,61,150; 70,148,73; 175,54,60; 231,199,31; 187,86,149; 8,133,161;
                 243,243,242; 200,200,200; 160,160,160; 122,122,121; 85,85,85; 52,52,52 ];
        CIE_Lab = [ 37.986,13.555,14.059; 65.711,18.13,17.81; 49.927,-4.88,-21.925; 43.139,-13.095,21.905;
                    55.112,8.844,-25.399; 70.719,-33.397,-0.199; 62.661,36.067,57.096; 40.02,10.41,-45.964; 
                    51.124,48.239,16.248; 30.325,22.976,-21.587; 72.532,-23.709,57.255; 71.941,19.363,67.857; 
                    28.778,14.179,-50.297; 55.261,-38.342,31.37; 42.101,53.378,28.19; 81.733,4.039,79.819; 
                    51.935,49.986,-14.574; 51.038,-28.631,-28.638;96.539,-0.425,1.186; 81.257,-0.638,-0.335; 
                    66.766,-0.734,-0.504; 50.867,-0.153,-0.27; 35.656,-0.421,-1.231;20.461,-0.079,-0.973 ];
        value = cell(1,24);%存放每个色块的编号、选框左上和右下点的坐标、数据
        Cab = zeros(1,24);%Cab = (a^2+b^2)^(1/2)
    end
end

绘制爱色丽色卡

standard_color = COLORCARD;%创建爱色丽色卡对象
I = standard_color.sRGB ./ 255;%sRGB归一化
%绘制爱色丽色卡
figure('NumberTitle','off','name','屏幕图样:Colorchecker(sRGB)')
daspect([1,1,1]);%设置图像比例
set(gca,'xlim',[0,740]);%设置x坐标轴范围
set(gca,'ylim',[0,500]);%设置y坐标轴范围
axis off %关闭坐标轴
rectangle('position',[0,0,740,500],'FaceColor',[0,0,0]);%绘制740*500的黑色背景
%在黑色背景上绘制24个色块
w = 100;%色块的尺寸
h = 20;%色块之间的距离
m = 1;%定义色块起始编号
x = 20 : w + h :620;
y = 380: - w - h:20;
for y = 380: - w - h:20
    for x = 20 : w + h :620
        rectangle('position',[x,y,w,w],'FaceColor',I(m,:));
        m = m + 1;
    end
end
saveas(gcf, 'standard_color', 'jpg');%保存爱色丽色卡

运行程序得到标准色卡图样。
在这里插入图片描述
计算标准色卡的Ca * b *:

L_standrand = standard_color.CIE_Lab(:,1);
a_standrand = standard_color.CIE_Lab(:,2);
b_standrand = standard_color.CIE_Lab(:,3);
Cab_standrand = sqrt(a_standrand.^2 + b_standrand.^2);

3.3 拍摄色卡

用老师提供的拍摄色卡,记为测试色卡进行测试。
在这里插入图片描述

程序代码

%创建测试色卡对象
test_color = COLORCARD;
%选择图片路径
[filename,filepath] = uigetfile({'*'},'选择图片');
%合成路径
Fullfile = [filepath,filename];
%读取色卡,数据存放在card属性中
test_color.card = imread(Fullfile);
if isempty(test_color.card) %读取色卡失败
    h=dialog('name','关于...','position',[200 200 200 70]);
    uicontrol('parent',h,'style','text','string','读取色卡失败,请重新读取!','position',[50 40 120 20],'fontsize',12);
    uicontrol('parent',h,'style','pushbutton','position',[80 10 50 20],'string','确定','callback','delete(gcbf)');
    movegui(h,'center');
else %读取色卡成功
    h=dialog('name','关于...','position',[200 200 200 70]);
    uicontrol('parent',h,'style','text','string','读取色卡成功!','position',[50 40 120 20],'fontsize',12);
    uicontrol('parent',h,'style','pushbutton','position',[80 10 50 20],'string','确定','callback','delete(gcbf)');
    movegui(h,'center');
    %显示图片
    figure('NumberTitle','off','name','Colorchecke-selection')
    imshow(test_color.card);
end

显示读取的色卡
在这里插入图片描述

3.4 测试色卡的两次框选

3.4.1 第一次框选

方便对测试色卡的后续处理,进行第一次整体框选。

 %显示图片
    figure('NumberTitle','off','name','Colorchecke-selection')
    imshow(test_color.card);
    %整体框选
    card = imcrop(test_color.card);
    test_color.card = [];
    test_color.card = card;
    open('ImatestColorCheck2.fig');

在这里插入图片描述

3.4.2 第二次框选

按照要求,手动框选24个色块并进行编号,计算色块的sRGB、CIE Lab值。对单个色块框选后进行sRGB、CIE Lab的计算,直到完成全部色块的处理。

for i = 1:24
    %手动框选24个色块并编号,得到每个色块的平均sRGB作为该色块的sRGB
    [sRGB,value] = color_number(test_color.card);
    test_color.sRGB(i,:) = sRGB; %把每个sRGB值存放在测试色卡test_color.sRGB属性中
    test_color.value{i} = value; %把每个value的值存放在测试色卡test_color.value属性中
    test_color.CIE_Lab(i,:) = sRGB2CIE_Lab(sRGB); %sRGB转换为CIE_Lab,
                                                 %把每个CIE_Lab的值存放在测试色卡test_color.CIE_Lab属性中
    
    %判断24个色块是否框选完成,完成后进行提示
    if i == 24
        h=dialog('position',[200 200 200 70]);
        movegui(h,'center');
        uicontrol('parent',h,'style','text','string','已完成24个色块的框选!','position',[50 40 120 20],'fontsize',12);
        uicontrol('parent',h,'style','pushbutton','string','确定','callback','delete(gcbf)','position',[80 10 50 20]);
    end
end

在该程序中有两个函数:
(1)单个色块的处理函数:function [sRGB,value] = color_number(card)
函数输出参数为单个色块的平均sRGB值,输入参数为第一次整体截取的测试测卡图像。
具体函数程序如下

function [sRGB,value] = color_number(card)

waitforbuttonpress; % 等待鼠标按下
point1 = get(gca,'CurrentPoint'); % 鼠标按下
rbbox;
point2 = get(gca,'CurrentPoint'); % 鼠标松开
point1 = floor(point1(1,1:2)); %提取出两个点
point2 = floor(point2(1,1:2));
offset = abs(point1-point2);%offset(1)为x方向的距离,offset(2)为y方向的距离
%判断单个色块的框选是否成功,若没有成功则提示重新框选
while offset(1,1) == 0 || offset(1,2) == 0 
    uiresume;
    h=dialog('position',[200 200 200 100]);
    movegui(h,'center');
    uicontrol('parent',h,'style','text','string','未完成拖选,请重新选择!','position',[30 40 150 30],'fontsize',9);
    uicontrol('parent',h,'style','pushbutton','string','确定','callback','delete(gcf)','position',[80 10 50 20]);
    set(h, 'WindowStyle', 'modal');%设为模态对话框
    uiwait;
    a = 0;
    waitforbuttonpress; % 等待鼠标按下
    point1 = get(gca,'CurrentPoint'); % 鼠标按下
    rbbox;
    point2 = get(gca,'CurrentPoint'); % 鼠标松开
    point1 = floor(point1(1,1:2)); % 提取出两个点
    point2 = floor(point2(1,1:2));
    offset = abs(point1-point2);
end
hold on %防止plot时闪烁
rectangle('position',[point1(1),point1(2),offset(1),offset(2)],'EdgeColor','r');%绘制选框
number = inputdlg('请输入色块编号');%框选完成后出现提示框:输入编号
%value为元胞数组,value(1,1)保存编号,value(2,1)保存鼠标拖选矩形框的左上和右下点的坐标,value(3,1)保存该色块数据
value(1,1) = number;%保存编号
value(2,1) = {[point1(1) point1(2) point2(1) point2(2)]};%保存鼠标拖选矩形框的左上和右下点的坐标
j = 1;
color_val = zeros((offset(1)+ 1)*(offset(2)+1),3);%根据选中色块像素数量创建矩阵,存放色块的数据
for n = point1(1):point2(1)
    for m = point1(2):point2(2)
        color_val(j,1) = card(m,n,1);%所有的sR
        color_val(j,2) = card(m,n,2);%所有的sG
        color_val(j,3) = card(m,n,3);%所有的sB
        j = j + 1;
    end
end
value(3,1) = {color_val}; %保存单个色块数据
R = mean(color_val(:,1));%该色块的平均sR
G = mean(color_val(:,2));%该色块的平均sG
B = mean(color_val(:,3));%该色块的平均sB
sRGB = [R,G,B];
end

(2)sRGB转换为CIE Lab函数:function CIE_Lab = sRGB2CIE_Lab(sRGB)
函数输出参数为色块的平均sRGB值对应的CIE Lab,输入参数为单个色块的平均sRGB值。该函数是先将色块的sRGB值转换为CIE XYZ值,再将CIE XYZ值转换为CIE Lab值。

function CIE_Lab = sRGB2CIE_Lab(sRGB)
%归一化sRGB被线性化
%归一化sRGB(除以255)
sRGB_normal = sRGB./255;
%线性化
%归一化后的sR值
if sRGB_normal(1) <= 0.0405
    sR(1) = sRGB_normal(1) / 12.95;
else
    sR(1) = ((0.055+sRGB_normal(1)) / 1.055)^2.4;
end
%归一化后的sG值
if sRGB_normal(2) <= 0.0405
    sG(1) = sRGB_normal(2) / 12.95;
else
    sG(1) = ((0.055+sRGB_normal(2)) / 1.055)^2.4;
end
%归一化后的sB值
if sRGB_normal(3) <= 0.0405
    sB(1) = sRGB_normal(3) / 12.95;
else
    sB(1) = ((0.055+sRGB_normal(3)) / 1.055)^2.4;
end
sRGB = [sR,sG,sB];
sRGB = sRGB';
%将线性化的sRGB值转换到归一化的XYZ(D65)空间
A = [0.4124,0.3576,0.1805;%变换矩阵
    0.2126,0.7152,0.0722;
    0.0193,0.1192,0.9505];
XYZ = A * sRGB;

%从sRGB到CIE_Lab的变换(以CIE XYZ为中介)
%Xn,Yn,Zn为D65照明体下参考白点坐标
Xn = 0.9505;
Yn = 1.0000;
Zn = 1.0890;
X = XYZ(1);
Y = XYZ(2);
Z = XYZ(3);
if X/Xn > 0.008856 
    fX = (X / Xn)^(1/3);
else
    fX = 7.787*(X/Xn) + 16/116;
end
if Y/Yn > 0.008856 
    fY = (Y / Yn)^(1/3);
    L = 116 * fY - 16;%计算L*
else
    fY = 7.787*(Y/Yn) + 16/116;
    L = 903.3 * (Y/Yn);%计算L*
end
if Z/Zn > 0.008856 
    fZ = (Z / Zn)^(1/3);
else
    fZ = 7.787*(Z/Zn) + 16/116;
end
a = 500 * (fX - fY);%计算a*
b = 200 * (fY - fZ);%计算b*
CIE_Lab = [L,a,b];
end

3.5 计算Ca * b *

L_test = test_color.CIE_Lab(:,1);
a_test = test_color.CIE_Lab(:,2);
b_test = test_color.CIE_Lab(:,3);
Cab_test = sqrt(a_test.^2 + b_test.^2);

3.6 计算色差

CIE (国际照明委员会)Lab颜色空间简单介绍:L:(亮度)轴 表示黑白,0为黑 100为白。a:(红绿)轴 正值为红,负值为绿,0为中性。b:(黄蓝)轴正值为黄,负值为蓝,0为中性。
△L为正,说明测试样比标准样浅(偏白)△L为负,说明测试样比标准样深(偏黑)。△a为正,说明测试样比标准样红(偏红)△a为负,说明测试样比标准样绿(偏绿)。△b为正,说明测试样比标准样黄(偏黄)△b为负,说明测试样比标准样蓝(偏蓝)。△Eab为总色差,值越大说明色差越大。
色差公式:
△E=[(△L)2 (△a)2 (△b)2]^(1/2)。
具体程序代码如下:

%计算Eab Cab
L_test = test_color.CIE_Lab(:,1);
a_test = test_color.CIE_Lab(:,2);
b_test = test_color.CIE_Lab(:,3);
Cab_test = sqrt(a_test.^2 + b_test.^2);

standard_color = COLORCARD;
L_standrand = standard_color.CIE_Lab(:,1);
a_standrand = standard_color.CIE_Lab(:,2);
b_standrand = standard_color.CIE_Lab(:,3);
Cab_standrand = sqrt(a_standrand.^2 + b_standrand.^2);

cL = L_test - L_standrand;
ca = a_test - a_standrand;
cb = b_test - b_standrand;
d_Eab = sqrt(cL.^2 + ca.^2 + cb.^2);
d_Cab = Cab_test - Cab_standrand ;

3.7 显示色差

a_standard = standard_color.CIE_Lab(:,2);
b_standard = standard_color.CIE_Lab(:,3);
a_test = test_color.CIE_Lab(:,2);
b_test = test_color.CIE_Lab(:,3);
d_Eab_mean = mean(d_Eab);
d_Eab_max = max(d_Eab);
d_Cab_mean = mean(abs(d_Cab));
d_Cab_max = max(abs(d_Cab));
figure
xlabel = 'a*';
ylabel = 'b*';
for i = 1:24
    plot([a_standard(i),a_test(i)],[b_standard(i),b_test(i)]);
    hold on;
    text(a_standard(i),b_standard(i),'o','color','g');
    hold on;
    text(a_test(i),b_test(i),'o','color','r');
    hold on;
end

hold off;
daspect([1,1,1]);

第四章 图形用户界面及实验结果

4.1 图形用户界面

模拟Imatest的colorcheck模块,进行色差处理实验。
新建两个fig页面:ImatestColorCheck.fig、ImatestColorCheck2.fig
ImatestColorCheck.fig
屏幕图样的回调函数为加载爱色丽色卡,ColorCheck则是进行色差处理:加载测试图片、第一次框选、打开ImatestColorCheck2.fig。
ImatestColorCheck2.fig
Axes2显示第一次框选后的图并进行第二次框选:对24个色块进行拖选、输入编号并进行sRGB、CIE Lab、Cab、△Cab、△Eab的计算。“是的,继续”的回调函数是显示色差并计算△Cab和△Eab的平均值和最大值。

4.2 图形用户界面操作流程及实验结果

开始界面如下所示:
在这里插入图片描述
点击屏幕图样得到爱色丽色卡。
在这里插入图片描述
点击Color Check进行色差处理,首先导入测试图片,出现选择图片浏览框。
在这里插入图片描述
读取成功后出现读取成功提示框并显示图像,反之提示失败。
对读入的图像进行整体框选,双击得到框选后的图片:
在这里插入图片描述
在这里插入图片描述
进行第二次框选,进入该页面后直接用鼠标手动拖选色块,并输入编号。
在这里插入图片描述
对24个色块拖选并输入编码,计算每个色块的sRGB和CIE Lab的值及完成对Cab、Eab的自动计算。
完成后如下图所示。

在这里插入图片描述
计算得到色差为:

序号△Eab△Cab
15.551434348643244.73406748967801
26.94565796095100-3.93451489823245
35.69803843845297-0.704309327814165
412.055141556565610.4625414092679
57.908637194904114.40144235915420
610.4578006379024-9.26571932844358
711.5721667592339-4.35644839495931
812.55720877348047.45005075054171
95.433072015600134.31230540273475
105.554905129192900.395183864825807
117.93701635743434-6.32267735709571
1213.5539202225103-3.47158710088395
1315.46310159468489.78415349125530
143.09505584044692-2.56271077996743
1510.46818953107048.18254913143394
1616.4556837862032-13.1433642150267
173.370890970779802.44642530172536
1816.2333430815614-9.54014768002860
197.598420528158091.75832540409464
202.532118322262161.12136825330515
213.460785878822711.14717730278684
222.758716242616330.787104610254210
235.34602729596054-0.154927353098391
248.08200634373610-0.100256065415188

点击确定,关闭提示框,点击“是的,继续”显示色差图。绿色圆圈代表理想值,红色圆圈代表测试值。
在这里插入图片描述
这里可以在sRGB的背景图上显示色差,我没有弄……
△Cab_mean =4.605806553000977
△Cab_max = 13.143364215026693
△Eab_mean = 8.337055783798895
△Eab_max = 16.455683786203150
△Cab<0时,测试色比标准色色彩饱和度低;△Cab>0时,测试色比标准色色彩饱和度高。总体来看测试色饱和度较低。△Eab是Lab空间下的标准偏差。

参考文献

[1]杨超,刘本永. 基于Lab颜色空间纹理特征的图像前后景分离[J]. 激光与光电子学进展, 2019, 56(12): 59-64.
[2]徐志成. 一个色彩空间转换系统的设计与实现[D]. 东南大学, 2017.
[3]赵军辉,吴玉峰,胡坤融,等. 基于Lab色彩空间和色调映射的彩色图像增强算法[J]. 计算机科学, 2018, 45(2): 297-300.
[4]李伟斌,马洪林,易贤,等. 基于色彩空间变换的彩色图像分割方法[J]. 计算机工程与应用, 2019, 55(9): 162-167.
[5]王可,陆长德,乐万德,等. 基于Lab均匀色彩空间的色彩调和系统[J]. 西北工业大学学报, 2004, 卷缺失(6): 695-699.
[6]郑元林,杨淑蕙,周世生,等. CIE 1976 LAB色差公式的均匀性研究[J]. 包装工程, 2005, 卷缺失(2): 48-49, 65.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值