RGB与Lab颜色空间互相转换

RGB与Lab颜色空间互相转换

 

1.Lab颜色空间

 

       同RGB颜色空间相比(见博客光与色的故事--颜色空间浅析》),Lab是一种不常用的色彩空间。它是在1931年国际照明委员会(CIE)制定的颜色度量国际标准的基础上建立起来的。1976年,经修改后被正式命名为CIELab。它是一种设备无关的颜色系统,也是一种基于生理特征的颜色系统。这也就意味着,它是用数字化的方法来描述人的视觉感应。Lab颜色空间中的L分量用于表示像素的亮度,取值范围是[0,100],表示从纯黑到纯白;a表示从红色到绿色的范围,取值范围是[127,-128];b表示从黄色到蓝色的范围,取值范围是[127,-128]。下图所示为Lab颜色空间的图示;

 

 

      需要提醒的是,Lab颜色空间比计算机显示器、打印机甚至比人类视觉的色域都要大,表示为 Lab 的位图比 RGB 或 CMYK 位图获得同样的精度要求更多的每像素数据。虽然我们在生活中使用RGB颜色空间更多一些,但也并非Lab颜色空间真的一无所有。例如,在 Adobe Photoshop图像处理软件中,TIFF格式文件中,PDF文档中,都可以见到Lab颜色空间的身影。而在计算机视觉中,尤其是颜色识别相关的算法设计中,rgb,hsv,lab颜色空间混用更是常用的方法。

两者的区别:

      RGB的是由红色通道(R)、绿色通道(G)、蓝色通道(B)组成的,最亮的红色+最亮的绿色+最亮的蓝色=白色;最暗的红色+最暗的绿色+最暗的蓝色=黑色;而在最亮和最暗之间,相同明暗度的红色+相同明暗度的绿色+相同明暗度的蓝色=灰色。在RGB的任意一个通道内,白和黑表示这个颜色的明暗度。所以,有白色或者灰白色的地方,R、G、B三个通道都不可能是黑色的,因为必须要有R、G、B三个通道来构成这些颜色。
      而LAB不一样,LAB中的明度通道(L)专门负责整张图的明暗度,简单的说就是整幅图的黑白版。a通道和b通道只负责颜色的多少。a通道表示从洋红色(通道里的白色)至深绿色(通道里的黑色)的范围;b表示从焦黄色(通道里的白色)至袅蓝色(通道里的黑色)的范围;a、b通道里的50%中性灰色表示没有颜色,所以越接近灰色说明颜色越少,而且a通道和b通道的颜色没有亮度。这就说明了为什么在a、b通道中红色T恤的轮廓是那么的清晰!因为红色是洋红色+焦黄色组成的。
    总的来说:
      1、适合RGB通道抠的图大部分LAB模式能完成,反之不成立。
      2、任何单一色调背景下,用通道抠有明显颜色区别的部分,用LAB模式很快能完成
      3、LAB模式下对明度(L)通道做任何操作(如锐化、模糊等)不会影响到色相。

2.RGB转Lab颜色空间

      RGB颜色空间不能直接转换为Lab颜色空间,需要借助XYZ颜色空间,把RGB颜色空间转换到XYZ颜色空间,之后再把XYZ颜色空间转换到Lab颜色空间。

     RGB与XYZ颜色空间有如下关系:

      仔细观察式(1),其中 X = 0.412453 * R +  0.412453 *G+ 0.412453B ;  各系数相加之和为0.950456,非常接近于1,我们知道R/G/B的取值范围为[ 0,255 ],如果系数和等于1,则X的取值范围也必然在[ 0,255 ]之间,因此我们可以考虑等比修改各系数,使其之和等于1,这样就做到了XYZ和RGB在同等范围的映射。这也就是为什么代码里X,Y,Z会分别除以0.950456、1.0、1.088754。

RGB2Lab关键代码实现:

 

//RGB2Lab Lab2RGB
const float param_13 = 1.0f / 3.0f;
const float param_16116 = 16.0f / 116.0f;
const float Xn = 0.950456f;
const float Yn = 1.0f;
const float Zn = 1.088754f;

 float gamma(float x)
  {
	  return x>0.04045?powf((x+0.055f)/1.055f,2.4f):(x/12.92);
  }; 

 void RGB2XYZ(T_U8 R, T_U8 G, T_U8 B, float *X, float *Y, float *Z)  
    {  
	float RR = gamma(R/255.0);
	float GG = gamma(G/255.0);
	float BB = gamma(B/255.0);

        *X = 0.4124564f * RR + 0.3575761f * GG + 0.1804375f * BB;  
        *Y = 0.2126729f * RR + 0.7151522f * GG + 0.0721750f * BB;  
        *Z = 0.0193339f * RR + 0.1191920f * GG + 0.9503041f * BB;  
    }  
  


  void XYZ2Lab(float X, float Y, float Z, float *L, float *a, float *b)  
    {  
        float fX, fY, fZ;  
      
        X /= (Xn);  
        Y /= (Yn);  
        Z /= (Zn);  
      
        if (Y > 0.008856f)  
	    fY = pow(Y, param_13);  	
        else  
	    fY = 7.787f * Y + param_16116;  
   
        if (X > 0.008856f)  
            fX = pow(X, param_13);  
        else  
            fX = 7.787f * X + param_16116;  
      
        if (Z > 0.008856)  
            fZ = pow(Z, param_13);  
        else  
            fZ = 7.787f * Z + param_16116;  

        *L = 116.0f * fY - 16.0f;
	*L = *L > 0.0f ? *L : 0.0f;   
        *a = 500.0f * (fX - fY);  
        *b = 200.0f * (fY - fZ);  
    }  

int RGB2Lab(IMAGE_TYPE *bmp_img,float *lab_img)
{
	DWORD width,height,index;
	WORD  biBitCount;
	T_U8 *dst,*bmp,R,G,B;
	float X,Y,Z,L,a,b;
	
	T_U32 line_byte;
	T_U16 i,j;
	
	BITMAPFILEHEADER bf;
	BITMAPINFOHEADER bi;
	
	memset(&bf, 0, sizeof(bf));
	memset(&bi, 0, sizeof(bi));
	
	bmp = bmp_img;
	memcpy(&bf,bmp,14);
	memcpy(&bi,&bmp[14],40);
	
	height = bi.biHeight;
	width  = bi.biWidth;
	biBitCount = bi.biBitCount;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
	line_byte = WIDTHBYTES(width*bi.biBitCount);

	dst = bmp_img+BMPHEADSIZE;
	
	for (i = 0; i <height;i++)
	{
		for (j = 0;j < width;j++)
		{
			index = i*line_byte+3*j;
			B = dst[index];
			G = dst[index+1];
			R = dst[index+2];

			RGB2XYZ(R,G,B,&X,&Y,&Z);
			XYZ2Lab(X,Y,Z,&L,&a,&b);

			lab_img[index] = L;
			lab_img[index+1] = a;
			lab_img[index+2] = b;
		}
	}
    
	return 0;

}

 

3.Lab转RGB颜色空间   

 

Lab2RGB关键代码实现:

 

extern const float param_13;
extern const float param_16116;
extern const float Xn;
extern const float Yn;
extern const float Zn;

 float gamma_XYZ2RGB(float x)
  {
	  return x>0.0031308?(1.055f*powf(x,(1/2.4f))-0.055):(x*12.92);
  };

void XYZ2RGB(float X, float Y, float Z, unsigned char*R, unsigned char*G, unsigned char*B)  
    {       
	float RR , GG, BB ;
        RR =  3.2404542f * X - 1.5371385f * Y - 0.4985314f * Z;  
        GG = -0.9692660f * X + 1.8760108f * Y + 0.0415560f * Z;  
        BB =  0.0556434f * X - 0.2040259f * Y + 1.0572252f * Z;  

	RR = gamma_XYZ2RGB(RR);
	GG = gamma_XYZ2RGB(GG);
	BB = gamma_XYZ2RGB(BB);

        RR = CLIP255(RR*255.0+0.5);
        GG = CLIP255(GG*255.0+0.5);
        BB = CLIP255(BB*255.0+0.5);

        *R = (unsigned char)RR;  
        *G = (unsigned char)GG;  
        *B = (unsigned char)BB;  
    }  
      
  void Lab2XYZ(float L, float a, float b, float *X, float *Y, float *Z)  
    {  
	float fX, fY, fZ;  
      
        fY = (L + 16.0f) / 116.0; 
	fX = a / 500.0f + fY;
	fZ = fY - b / 200.0f; 

	if(powf(fY,3.0)>0.008856)
	    *Y =powf(fY,3.0);
	else
	    *Y = (fY-param_16116)/7.787f;
		
        if (powf(fX,3) > 0.008856)  
            *X = fX * fX * fX;  
        else  
            *X = (fX - param_16116) / 7.787f;  
      
        if (powf(fZ,3.0) > 0.008856)  
            *Z = fZ * fZ * fZ;  
        else  
            *Z = (fZ - param_16116) / 7.787f;  
      
        (*X) *= (Xn);  
        (*Y) *= (Yn);  
        (*Z) *= (Zn); 
    }  


int Lab2RGB(IMAGE_TYPE *bmp_img,float *lab_img)
{
	DWORD width,height,index;
	WORD  biBitCount;
	T_U8 *bmp,R,G,B,*Lab2BMP;
	float X,Y,Z,L,a,b;
	
	T_U32 line_byte;
	T_U16 i,j;
	
	BITMAPFILEHEADER bf;
	BITMAPINFOHEADER bi;

	FILE *Lab2BMP_fp = fopen("Lab2BMP.bmp","wb");
	
	if(NULL == Lab2BMP_fp)
	{
		printf("Can't open Lab2BMP.bmp\n");
		return -1;
	}
	
	memset(&bf, 0, sizeof(bf));
	memset(&bi, 0, sizeof(bi));

	bmp = bmp_img;
	memcpy(&bf,bmp,14);
	memcpy(&bi,&bmp[14],40);

	height = bi.biHeight;
	width  = bi.biWidth;
	biBitCount = bi.biBitCount;//每一个像素由24 bits表示,即RGB分量每一个分量用8 bits表示
	line_byte = WIDTHBYTES(width*bi.biBitCount);
	
	fwrite(&bf,sizeof(BITMAPFILEHEADER),1,Lab2BMP_fp);
	fwrite(&bi,sizeof(BITMAPINFOHEADER),1,Lab2BMP_fp);


	Lab2BMP = (T_U8*)malloc(height*line_byte);
	if (Lab2BMP == NULL)
	{
		printf("Can't malloc LabBMP image.\n");
		return 0;
	}
	memset(Lab2BMP,0,height*line_byte);

	
	for (i = 0; i <height;i++)
	{
		for (j = 0;j < width;j++)
		{
			index = i*line_byte+3*j;
			L = lab_img[index];
			a = lab_img[index+1];
			b = lab_img[index+2];

			Lab2XYZ(L,a,b,&X,&Y,&Z);
			XYZ2RGB(X,Y,Z,&R,&G,&B);
		

			Lab2BMP[index] = B;
			Lab2BMP[index+1] = G;
			Lab2BMP[index+2] = R;
		}
	}

	fwrite(Lab2BMP, line_byte*height, 1, Lab2BMP_fp);
	fclose(Lab2BMP_fp);  
    free(Lab2BMP);
    
	return 0;

}

4.结果实例

 

左侧图像是原始图像,右侧图像经过RGB->XYZ->LAB->XYZ->RGB的转换结果图。

 以D65光源下24色卡为例,对比其计算出来的RGB Lab值大小。

24色在D65光源下sRGB值

 

标准SRGB转Lab值
上述Lab转RGB值

按照上述公式,计算出来的Lab值与EasyRGB和Photoshop计算出来的值比较,与EasyRGB差值比较小。之所以有所差异,是lab计算中选取的参考白点Xn、Yn、Zn以及设备RGB转XYZ的矩阵略有差异。与Photoshop比较,主要差异在于a分量,其他两个分量已经比较接近了。

常见的参考白点在XYZ颜色空间的坐标为:
Observer2° (CIE 1931)10° (CIE 1964)Note
IlluminantX2Y2Z2X10Y10Z10 
A109.850100.00035.585111.144100.00035.200Incandescent/tungsten
B99.0927100.00085.31399.178;100.00084.3493Old direct sunlight at noon
C98.074100.000118.23297.285100.000116.145Old daylight
D5096.422100.00082.52196.720100.00081.427ICC profile PCS
D5595.682100.00092.14995.799100.00090.926Mid-morning daylight
D6595.047100.000108.88394.811100.000107.304Daylight, sRGB, Adobe-RGB
D7594.972100.000122.63894.416100.000120.641North sky daylight
E100.000100.000100.000100.000100.000100.000Equal energy
F192.834100.000103.66594.791100.000103.191Daylight Fluorescent
F299.187100.00067.395103.280100.00069.026Cool fluorescent
F3103.754100.00049.861108.968100.00051.965White Fluorescent
F4109.147100.00038.813114.961100.00040.963Warm White Fluorescent
F590.872100.00098.72393.369100.00098.636Daylight Fluorescent
F697.309100.00060.191102.148100.00062.074Lite White Fluorescent
F795.044100.000108.75595.792100.000107.687Daylight fluorescent, D65 simulator
F896.413100.00082.33397.115100.00081.135Sylvania F40, D50 simulator
F9100.365100.00067.868102.116100.00067.826Cool White Fluorescent
F1096.174100.00081.71299.001100.00083.134Ultralume 50, Philips TL85
F11100.966100.00064.370103.866100.00065.627Ultralume 40, Philips TL84
F12108.046100.00039.228111.428100.00040.353Ultralume 30, Philips TL83

 D65光源下,常见的RGB转XYZ以及XYZ转RGB矩阵如下表所示:

RGB Working SpaceReference WhiteRGB to XYZ [M]XYZ to RGB [M]-1
Adobe RGB (1998)D65
 0.5767309  0.1855540  0.1881852
 0.2973769  0.6273491  0.0752741
 0.0270343  0.0706872  0.9911085
 2.0413690 -0.5649464 -0.3446944
-0.9692660  1.8760108  0.0415560
 0.0134474 -0.1183897  1.0154096
AppleRGBD65
 0.4497288  0.3162486  0.1844926
 0.2446525  0.6720283  0.0833192
 0.0251848  0.1411824  0.9224628
 2.9515373 -1.2894116 -0.4738445
-1.0851093  1.9908566  0.0372026
 0.0854934 -0.2694964  1.0912975
Best RGBD50
 0.6326696  0.2045558  0.1269946
 0.2284569  0.7373523  0.0341908
 0.0000000  0.0095142  0.8156958
 1.7552599 -0.4836786 -0.2530000
-0.5441336  1.5068789  0.0215528
 0.0063467 -0.0175761  1.2256959
Beta RGBD50
 0.6712537  0.1745834  0.1183829
 0.3032726  0.6637861  0.0329413
 0.0000000  0.0407010  0.7845090
 1.6832270 -0.4282363 -0.2360185
-0.7710229  1.7065571  0.0446900
 0.0400013 -0.0885376  1.2723640
Bruce RGBD65
 0.4674162  0.2944512  0.1886026
 0.2410115  0.6835475  0.0754410
 0.0219101  0.0736128  0.9933071
 2.7454669 -1.1358136 -0.4350269
-0.9692660  1.8760108  0.0415560
 0.0112723 -0.1139754  1.0132541
CIE RGBE
 0.4887180  0.3106803  0.2006017
 0.1762044  0.8129847  0.0108109
 0.0000000  0.0102048  0.9897952
 2.3706743 -0.9000405 -0.4706338
-0.5138850  1.4253036  0.0885814
 0.0052982 -0.0146949  1.0093968
ColorMatch RGBD50
 0.5093439  0.3209071  0.1339691
 0.2748840  0.6581315  0.0669845
 0.0242545  0.1087821  0.6921735
 2.6422874 -1.2234270 -0.3930143
-1.1119763  2.0590183  0.0159614
 0.0821699 -0.2807254  1.4559877
Don RGB 4D50
 0.6457711  0.1933511  0.1250978
 0.2783496  0.6879702  0.0336802
 0.0037113  0.0179861  0.8035125
 1.7603902 -0.4881198 -0.2536126
-0.7126288  1.6527432  0.0416715
 0.0078207 -0.0347411  1.2447743
ECI RGBD50
 0.6502043  0.1780774  0.1359384
 0.3202499  0.6020711  0.0776791
 0.0000000  0.0678390  0.7573710
 1.7827618 -0.4969847 -0.2690101
-0.9593623  1.9477962 -0.0275807
 0.0859317 -0.1744674  1.3228273
Ekta Space PS5D50
 0.5938914  0.2729801  0.0973485
 0.2606286  0.7349465  0.0044249
 0.0000000  0.0419969  0.7832131
 2.0043819 -0.7304844 -0.2450052
-0.7110285  1.6202126  0.0792227
 0.0381263 -0.0868780  1.2725438
NTSC RGBC
 0.6068909  0.1735011  0.2003480
 0.2989164  0.5865990  0.1144845
 0.0000000  0.0660957  1.1162243
 1.9099961 -0.5324542 -0.2882091
-0.9846663  1.9991710 -0.0283082
 0.0583056 -0.1183781  0.8975535
PAL/SECAM RGBD65
 0.4306190  0.3415419  0.1783091
 0.2220379  0.7066384  0.0713236
 0.0201853  0.1295504  0.9390944
 3.0628971 -1.3931791 -0.4757517
-0.9692660  1.8760108  0.0415560
 0.0678775 -0.2288548  1.0693490
ProPhoto RGBD50
 0.7976749  0.1351917  0.0313534
 0.2880402  0.7118741  0.0000857
 0.0000000  0.0000000  0.8252100
 1.3459433 -0.2556075 -0.0511118
-0.5445989  1.5081673  0.0205351
 0.0000000  0.0000000  1.2118128
SMPTE-C RGBD65
 0.3935891  0.3652497  0.1916313
 0.2124132  0.7010437  0.0865432
 0.0187423  0.1119313  0.9581563
 3.5053960 -1.7394894 -0.5439640
-1.0690722  1.9778245  0.0351722
 0.0563200 -0.1970226  1.0502026
sRGBD65
 0.4124564  0.3575761  0.1804375
 0.2126729  0.7151522  0.0721750
 0.0193339  0.1191920  0.9503041
 3.2404542 -1.5371385 -0.4985314
-0.9692660  1.8760108  0.0415560
 0.0556434 -0.2040259  1.0572252
Wide Gamut RGBD50
 0.7161046  0.1009296  0.1471858
 0.2581874  0.7249378  0.0168748
 0.0000000  0.0517813  0.7734287
 1.4628067 -0.1840623 -0.2743606
-0.5217933  1.4472381  0.0677227
 0.0349342 -0.0968930  1.2884099

D50光源下常见的RGB转XYZ以及XYZ转RGB矩阵为:

RGB Working SpaceReference WhiteRGB to XYZ [M]XYZ to RGB [M]-1
Adobe RGB (1998)D50
 0.6097559  0.2052401  0.1492240
 0.3111242  0.6256560  0.0632197
 0.0194811  0.0608902  0.7448387
 1.9624274 -0.6105343 -0.3413404
-0.9787684  1.9161415  0.0334540
 0.0286869 -0.1406752  1.3487655
AppleRGBD50
 0.4755678  0.3396722  0.1489800
 0.2551812  0.6725693  0.0722496
 0.0184697  0.1133771  0.6933632
 2.8510695 -1.3605261 -0.4708281
-1.0927680  2.0348871  0.0227598
 0.1027403 -0.2964984  1.4510659
Bruce RGBD50
 0.4941816  0.3204834  0.1495550
 0.2521531  0.6844869  0.0633600
 0.0157886  0.0629304  0.7464909
 2.6502856 -1.2014485 -0.4289936
-0.9787684  1.9161415  0.0334540
 0.0264570 -0.1361227  1.3458542
CIE RGBD50
 0.4868870  0.3062984  0.1710347
 0.1746583  0.8247541  0.0005877
-0.0012563  0.0169832  0.8094831
 2.3638081 -0.8676030 -0.4988161
-0.5005940  1.3962369  0.1047562
 0.0141712 -0.0306400  1.2323842
NTSC RGBD50
 0.6343706  0.1852204  0.1446290
 0.3109496  0.5915984  0.0974520
-0.0011817  0.0555518  0.7708399
 1.8464881 -0.5521299 -0.2766458
-0.9826630  2.0044755 -0.0690396
 0.0736477 -0.1453020  1.3018376
PAL/SECAM RGBD50
 0.4552773  0.3675500  0.1413926
 0.2323025  0.7077956  0.0599019
 0.0145457  0.1049154  0.7057489
 2.9603944 -1.4678519 -0.4685105
-0.9787684  1.9161415  0.0334540
 0.0844874 -0.2545973  1.4216174
SMPTE-C RGBD50
 0.4163290  0.3931464  0.1547446
 0.2216999  0.7032549  0.0750452
 0.0136576  0.0913604  0.7201920
 3.3921940 -1.8264027 -0.5385522
-1.0770996  2.0213975  0.0207989
 0.0723073 -0.2217902  1.3960932
sRGBD50
 0.4360747  0.3850649  0.1430804
 0.2225045  0.7168786  0.0606169
 0.0139322  0.0971045  0.7141733
 3.1338561 -1.6168667 -0.4906146
-0.9787684  1.9161415  0.0334540
 0.0719453 -0.2289914  1.4052427

参考资料:

http://www.cnblogs.com/Imageshop/archive/2013/02/02/2889897.html

http://blog.youkuaiyun.com/grafx/article/details/59482320

http://www.easyrgb.com/en/math.php

http://www.brucelindbloom.com/

 

 

 

评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值