注释的源程序【以下程序未做任何优化,有Bug欢迎指正。】:
-------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------
* 函数名称:
* RGB2Lab()
*
* 功能:
* 该函数将24位RGB颜色空间图像转为Lab颜色空间图像
*
* 参数:
* src
* 指向待处理的RGB图像数据(24位)
* dst
* 指向存结果的Lab图像数据(L\a\b-double型)
* (L: 0~100; a: -128~127; b: -128~127)
* iWidth
* 图像宽度
* iHeight
* 图像高度
*
* 返回值类型: bool
*
* 参考推荐:
* http://c.chinaitlab.com/cc/ccjq/200806/752572.html
* http://wenku.baidu.com/view/055b8defaeaad1f346933f8f.html
*
* 编辑日期: 2011-05-17 Copyright (C) eeszh@163.com
//---------------------------------------------------------------------------------
bool RGB2Lab(unsigned char *src, double *dst, int iWidth, int iHeight)
{
// 输入参数有效性判断
if(src==NULL||dst==NULL)return false;
// 每行图像数据的字节数
int iLBytes = (iWidth*24+31)/32*4;
unsigned char *rgb;
double *lab;
unsigned char R,G,B;
double l,a,b;
double x,y,z;
double fx,fy,fz;
double BLACK = 20.0;
double YELLOW = 70.0;
for (int i = 0; i < iHeight; i++ )
{
for (int j = 0; j < iWidth; j++ )
{
rgb = src + iLBytes*i + 3*j;
lab = dst + iLBytes*i + 3*j;
// R\G\B像素值
B = *rgb; G = *(rgb+1); R = *(rgb+2);
// 转至X-Y-Z
//[ X ] [ 0.412453 0.357580 0.180423 ] [ R ]
//[ Y ] = [ 0.212671 0.715160 0.072169 ] * [ G ]
//[ Z ] [ 0.019334 0.119193 0.950227 ] [ B ]
x = 0.412453*R + 0.357580*G + 0.180423*B;
y = 0.212671*R + 0.715160*G + 0.072169*B;
z = 0.019334*R + 0.119193*G + 0.950227*B;
// 除255即归一化
x = x/(255.0*0.950456);
y = y/255.0;
z = z/(255.0*1.088754);
if(y>0.008856)
{
fy = pow(y,1.0/3.0);
l = 116.0*fy-16.0;
}else
{
fy = 7.787*y + 16.0/116.0;
l = 903.3*y;
}
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 = 500.0*(fx-fy);
b = 200.0*(fy-fz);
// 这里不加时出现颜色饱和的情况(见上图)
// 参考出处http://c.chinaitlab.com/cc/ccjq/200806/752572.html
if (l< BLACK)
{
a *= exp((l - BLACK) / (BLACK/ 4));
b *= exp((l - BLACK) / (BLACK/ 4));
l = 20;
}
if (b > YELLOW)b = YELLOW;
// 归一化值Lab
*lab = l / 255.0; // L
*(lab+1) = (a + 128.0) / 255.0; // a
*(lab+2) = (b + 128.0) / 255.0; // b
}
}
return true;
}
本文链接:http://blog.sina.com.cn/eeszh
//---------------------------------------------------------------------------------
* 函数名称:
* Lab2RGB()
*
* 功能:
* 该函数将Lab颜色空间图像转为24位RGB颜色空间图像
*
* 参数:
* src
* 指向待处理的Lab图像数据(double型)
* dst
* 指向存结果的RGB图像数据
* iWidth
* 图像宽度
* iHeight
* 图像高度
*
* 返回值类型: bool
*
* 参考推荐:
* http://c.chinaitlab.com/cc/ccjq/200806/752572.html
* http://wenku.baidu.com/view/055b8defaeaad1f346933f8f.html
*
* 编辑日期: 2011-05-17 Copyright (C) eeszh@163.com
//---------------------------------------------------------------------------------
bool Lab2RGB(double *src, unsigned char *dst, int iWidth, int iHeight)
{
// 输入参数有效性判断
if(src==NULL||dst==NULL)return false;
// 每行图像数据的字节数
int iLBytes = (iWidth*24+31)/32*4;
unsigned char *rgb;
double *lab;
double l,a,b;
double fx,fy,fz;
double x,y,z;
double dr,dg,db;
for (int i = 0; i < iHeight; i++ )
{
for (int j = 0; j < iWidth; j++ )
{
lab = src + iLBytes*i + 3*j;
rgb = dst + iLBytes*i + 3*j;
l = *lab* 255.0; // L
a = *(lab+1) * 255.0 - 128.0; // a
b = *(lab+2)* 255.0 - 128.0; // b
fy = (l+16.0)/116.0;
fy = fy*fy*fy;
if(fy > 0.008856)
{
y=fy;
}else
{
fy = l/903.3;
}
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);
}else
{
z = (fz-16.0/116.0)/7.787;
}
x = x*0.950456*255.0;
y = y*255.0;
z = z*1.088754*255.0;
// [ R ] [ 3.240479 -1.537150 -0.498535 ] [ X ]
// [ G ] = [ -0.969256 1.875992 0.041556 ] * [ Y ]
// [ B ] [ 0.055648 -0.204043 1.057311 ] [ Z ]
dr = 3.240479*x - 1.537150*y - 0.498535*z;
dg = -0.969256*x + 1.875992*y + 0.041556*z;
db = 0.055648*x - 0.204043*y + 1.057311*z;
// 防止溢出
if(dr<0.0)
{
*(rgb+2) = 0;
}else if(dr>255.0)
{
*(rgb+2) = 255;
}else
{
*(rgb+2) = (unsigned char)dr;
}