RGB与Lab颜色空间转换的程序实现及效果(VC++6.0) |
您所在的位置:网站首页 › lab色彩空间图 › RGB与Lab颜色空间转换的程序实现及效果(VC++6.0) |
RGB与Lab颜色空间转换的程序实现及效果 孙志海
在做双边滤波的时候,用到Lab颜色空间,所以对RGB与Lab颜色空间的转换进行了程序实现。 网上有不少RGB与Lab颜色空间转换的公式或代码,如果不做测试的话,大家肯定会觉得差不多,实不然。 发现网上现存的多数公式或代码信息不全,或者没有测试效果,实在难于让人信服。 这里给出RGB->Lab及Lab->RGB空间的测试效果及程序,与大家一起交流。
RGB->Lab时未添加以下代码所出现的效果(见右图) if (l< BLACK) { a *= exp((l - BLACK) / (BLACK/ 4)); b *= exp((l - BLACK) / (BLACK/ 4)); l = 20; } if (b > YELLOW)b = YELLOW; ------------------------------------------------------------------------------------------- 带注释的源程序【以下程序未做任何优化,有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) [email protected] //--------------------------------------------------------------------------------- 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) [email protected] //--------------------------------------------------------------------------------- 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(dr255.0) { *(rgb+2) = 255; }else { |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |