转载http://blog.sina.com.cn/s/blog_7eb23c070100y6dh.html
同RGB颜色空间相比,Lab是一种不常用的色彩空间。它是在1931年国际照明委员会(CIE)制定的颜色度量国际标准的基础上建立起来的。1976年,经修改后被正式命名为CIELab。它是一种设备无关的颜色系统,也是一种基于生理特征的颜色系统。这也就意味着,它是用数字化的方法来描述人的视觉感应。Lab颜色空间中的L分量用于表示像素的亮度,取值范围是[0,100],表示从纯黑到纯白;a表示从红色到绿色的范围,取值范围是[127,-128];b表示从黄色到蓝色的范围,取值范围是[127,-128]。
色差计算公式:
△E*=[(△L*)2+(△a*)2。+(△b*)2]1/2。
△L=L样品-L标准(明度差异)
△a=a样品-a标准(红/绿差异)
△b=b样品-b标准(黄/蓝差异)
色差是用数值方式表示的两种颜色给人色彩感觉上的差别。两种采用La*b *色空间表示的颜色,色差即是两种颜色所在的坐标点在空间上的距离,由下式计算: 色差的单位用NBS表示,△E盎值为1时称为1NBS,1个NBS大约相当于视觉识别阈值的5倍。
值的大小即两种颜色在视觉感受上的相差大小,色差值和视觉感受上大约有这样的对应关系:
0.0—0.5(微小色差),感觉极微;
0.5—1.5(小色差),感觉轻微;
l.5~3(较小色差),感觉明显;
3—6(较大色差)感觉很明显;
6以上(大色差)感觉强烈。
◆色差计工作原理
自动比较样板与被检品之间的颜色差异,输出CIE_Lab–三组数据和比色后的△E、△L、△a、△b四组色差数据。
△E总色差的大小:
⊙ △L+表示偏白,△L–表示偏黑
⊙ △a+表示偏红,△a–表示偏绿
⊙ △b+表示偏黄,△b–表示偏蓝
http://storytelling-system-in-dsp.googlecode.com/svn-history/r37/trunk/HSV_Control_Image/main.c
//Reference: Mr.Mark Ruzon
// Convert between RGB and CIE-Lab color spaces
// Uses ITU-R recommendation BT.709 with D65 as reference white.
// Yossi Rubner
// Last modified 2/24/98
//=================================================================== LAB_GEL Function
void RGB2Lab(unsigned char R, unsigned char G, unsigned char B,
int *L, int *a, int *b)
{
float X, Y, Z, fX, fY, fZ;
X = 0.412453R + 0.357580G + 0.180423B;
Y = 0.212671R + 0.715160G + 0.072169B;
Z = 0.019334R + 0.119193G + 0.950227*B;
X /= (255 * 0.950456);
Y /= 255;
Z /= (255 * 1.088754);
if (Y > 0.008856)
{
fY = pow(Y, 1.0/3.0);
L = (int)(116.0fY - 16.0 + 0.5);
}
else
{
fY = 7.787*Y + 16.0/116.0;
L = (int)(903.3Y + 0.5);
}
if (X > 0.008856)
fX = pow(X, 1.0/3.0);
else
fX = 7.787*X + 16.0/116.0;
if (Z > 0.008856)
fZ = pow(Z, 1.0/3.0);
else
fZ = 7.787*Z + 16.0/116.0;
a = (int)(500.0(fX - fY) + 0.5);
b = (int)(200.0(fY - fZ) + 0.5);
//printf(“RGB=(%d,%d,%d) ==> Lab(%d,%d,%d)\n”,R,G,B,*L,*a,*b);
}
void Lab2RGB(int L, int a, int b,
unsigned char *R, unsigned char *G, unsigned char *B)
{
float X, Y, Z, fX, fY, fZ;
int RR, GG, BB;
fY = pow((L + 16.0) / 116.0, 3.0);
if (fY < 0.008856)
fY = L / 903.3;
Y = fY;
if (fY > 0.008856)
fY = pow(fY, 1.0/3.0);
else
fY = 7.787 * fY + 16.0/116.0;
fX = a / 500.0 + fY;
if (fX > 0.206893)
X = pow(fX, 3.0);
else
X = (fX - 16.0/116.0) / 7.787;
fZ = fY - b /200.0;
if (fZ > 0.206893)
Z = pow(fZ, 3.0);
else
Z = (fZ - 16.0/116.0) / 7.787;
X *= (0.950456 * 255);
Y *= 255;
Z *= (1.088754 * 255);
RR = (int)(3.240479X - 1.537150Y - 0.498535Z + 0.5);
GG = (int)(-0.969256X + 1.875992Y + 0.041556Z + 0.5);
BB = (int)(0.055648X - 0.204043Y + 1.057311*Z + 0.5);
*R = (unsigned char)(RR < 0 ? 0 : RR > 255 ? 255 : RR);
*G = (unsigned char)(GG < 0 ? 0 : GG > 255 ? 255 : GG);
*B = (unsigned char)(BB < 0 ? 0 : BB > 255 ? 255 : BB);
//printf(“Lab=(%f,%f,%f) ==> RGB(%f,%f,%f)\n”,L,a,b,*R,*G,*B);
}
//
Cindy备注:此代码由于Lab采用int型,RGB2Lab和Lab2RGB的结果略有偏差,建议Lab采用float型。