RGB与Lab颜色空间转换的程序实现及效果(VC++6.0)

注释的源程序【以下程序未做任何优化,有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;
   }
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值