RGB to LAB converter

参考:http://cookbooks.adobe.com/post_Useful_color_equations__RGB_to_LAB_converter-14227.html

 

#include "stdafx.h"
#include "ColorSpace.h"
#include <math.h>
void rgbxyz(float* r,float* g,float* b,float* x,float* y,float* z)
{
	float tempx=(*r>0.04045)?pow((*r+0.055)/1.055,2.4):*r/12.92;
	float tempy=(*g>0.04045)?pow((*g+0.055)/1.055,2.4):*g/12.92;
	float tempz=(*b>0.04045)?pow((*b+0.055)/1.055,2.4):*b/12.92;
	*x=(tempx*0.4124+tempy*0.3576+tempz*0.1805)*100;
	*y=(tempx*0.2126+tempy*0.7152+tempz*0.0722)*100;
	*z=(tempx*0.0193+tempy*0.1192+tempz*0.9505)*100;
}
void xyzlab(float* x,float* y,float* z,float* l,float* la,float* lb)
{
	float tempx=*x/95.047;
	float tempy=*y/100;
	float tempz=*z/108.883;
	tempx=(tempx>0.008856)? pow(tempx,(float)(1.0/3.0)):(7.787*tempx)+(16.0/116.0);
	tempy=(tempy>0.008856)? pow(tempy,(float)(1.0/3.0)):(7.787*tempy)+(16.0/116.0);
	tempz=(tempz>0.008856)? pow(tempz,(float)(1.0/3.0)):(7.787*tempz)+(16.0/116.0);
	*l=116.0*tempy-16.0;
	*la=500.0*(tempx-tempy);
	*lb=200.0*(tempy-tempz);

}
void rgblab(float* r,float* g,float* b,float* l,float* la,float* lb)
{
	float x,y,z;
	rgbxyz(r,g,b,&x,&y,&z);
	xyzlab(&x,&y,&z,l,la,lb);
	*l=*l/100.0;
	*la=0.5+0.5*(*la/127.0);
	*lb=0.5+0.5*(*lb/127.0);
}
void RGB2LAB(float* r,float* g,float* b,float* l,float* la,float* lb,int width,int height)
{
	for(int y=0;y<height;y++)
	{
		for(int x=0;x<width;x++)
		{
			rgblab(&r[y*width+x],&g[y*width+x],&b[y*width+x],&l[y*width+x],&la[y*width+x],&lb[y*width+x]);
		}
	}
}



void labxyz(float* l,float* la,float* lb,float* x,float* y,float* z)
{
	float tempy=(*l+16.0)/116.0;
	float tempx=*la/500.0+tempy;
	float tempz=tempy-*lb/200.0;
	*x=95.047*((tempx>0.206897)?tempx*tempx*tempx:(tempx-16.0/116.0)/7.787);
	*y=100.000*((tempy>0.206897)?tempy*tempy*tempy:(tempy-16.0/116.0)/7.787);
	*z=108.883*((tempz>0.206897)?tempz*tempz*tempz:(tempz-16.0/116.0)/7.787);
}
void xyzrgb(float* x,float* y,float* z,float* r,float* g,float* b)
{
	float tempx=(*x*3.2406-*y*1.5372-*z*0.4986)/100.0;
	float tempy=(-*x*0.9689+*y*1.8758+*z*0.0415)/100.0;
	float tempz=(*x*0.0557-*y*0.2040+*z*1.0570)/100.0;
	*r=(tempx>0.0031308)?((1.055*pow(tempx,(float)(1.0/2.4)))-0.055):12.92*tempx;
	*g=(tempy>0.0031308)?((1.055*pow(tempy,(float)(1.0/2.4)))-0.055):12.92*tempy;
	*b=(tempz>0.0031308)?((1.055*pow(tempz,(float)(1.0/2.4)))-0.055):12.92*tempz;
}
void labrgb(float* l,float* la,float* lb,float* r,float* g,float* b)
{
	float x,y,z;
	float tempr=*l*100.0;
	float tempg=2.0*127.0*(*la-0.5);
	float tempb=2.0*127.0*(*lb-0.5);
	labxyz(&tempr,&tempg,&tempb,&x,&y,&z);
	xyzrgb(&x,&y,&z,r,g,b);
}
void LAB2RGB(float* l,float* la,float* lb,float* r,float* g,float* b,int width,int height)
{
	for(int y=0;y<height;y++)
	{
		for(int x=0;x<width;x++)
		{
			labrgb(&l[y*width+x],&la[y*width+x],&lb[y*width+x],&r[y*width+x],&g[y*width+x],&b[y*width+x]);
			
		}
	}

}


 

在opencv里调用如下:
void CLABDlg::ShowImage(IplImage* Image,char* title)
{
	cvNamedWindow(title);
	cvShowImage(title,Image);
}
void CLABDlg::IplImageToFloat(IplImage* pSrc,float* r,float* g,float* b)
{
	for(int y=0;y<nHeight;y++)
	{
		for(int x=0;x<nWidth;x++)
		{
			b[y*nWidth+x]=((float*)(pSrc->imageData+y*pSrc->widthStep))[x*pSrc->nChannels];
			g[y*nWidth+x]=((float*)(pSrc->imageData+y*pSrc->widthStep))[x*pSrc->nChannels+1];
			r[y*nWidth+x]=((float*)(pSrc->imageData+y*pSrc->widthStep))[x*pSrc->nChannels+2];
		}
	}
}
void CLABDlg::FloateToIplImag(float* r,float* g,float* b,IplImage* pDst)
{
	for(int y=0;y<nHeight;y++)
	{
		for(int x=0;x<nWidth;x++)
		{
			((float*)(pDst->imageData+y*pDst->widthStep))[x*pDst->nChannels]=b[y*nWidth+x];
			((float*)(pDst->imageData+y*pDst->widthStep))[x*pDst->nChannels+1]=g[y*nWidth+x];
			((float*)(pDst->imageData+y*pDst->widthStep))[x*pDst->nChannels+2]=r[y*nWidth+x];
		}
	}
}
void CLABDlg::OnBnClickedRgblab()
{
	/*********************Load Images*********************/
	IplImage * OriginImage;
	OriginImage=cvLoadImage(strPath1,CV_LOAD_IMAGE_ANYCOLOR);
	nWidth=OriginImage->width;
	nHeight=OriginImage->height;
	nChannel=OriginImage->nChannels;
	/*********************Normalize Images*********************/
	IplImage* pSrc;
	pSrc=cvCreateImage(cvSize(nWidth,nHeight),IPL_DEPTH_32F,nChannel);
	cvConvertScale(OriginImage,pSrc,1.0/255,0.0);

	float* r=(float*)malloc(sizeof(float)*nWidth*nHeight);
	float* g=(float*)malloc(sizeof(float)*nWidth*nHeight);
	float* b=(float*)malloc(sizeof(float)*nWidth*nHeight);
	float* l=(float*)malloc(sizeof(float)*nWidth*nHeight);
	float* la=(float*)malloc(sizeof(float)*nWidth*nHeight);
	float* lb=(float*)malloc(sizeof(float)*nWidth*nHeight);

	float* newr=(float*)malloc(sizeof(float)*nWidth*nHeight);
	float* newg=(float*)malloc(sizeof(float)*nWidth*nHeight);
	float* newb=(float*)malloc(sizeof(float)*nWidth*nHeight);
	IplImageToFloat(pSrc,r,g,b);
	RGB2LAB(r,g,b,l,la,lb,nWidth,nHeight);
	LAB2RGB(l,la,lb,newr,newg,newb,nWidth,nHeight);
	
	double err=0;
	for(int y=0;y<nHeight;y++)
	{
		for(int x=0;x<nWidth;x++)
		{
			err+=pow(r[y*nWidth+x]-newr[y*nWidth+x],(float)2.0);
			err+=pow(g[y*nWidth+x]-newg[y*nWidth+x],(float)2.0);
			err+=pow(b[y*nWidth+x]-newb[y*nWidth+x],(float)2.0);
		}
	}
	
	FloateToIplImag(newr,newg,newb,pSrc);
	ShowImage(OriginImage,"origin image");
	ShowImage(pSrc,"result image");
}

转换之前的原图

RGB->LAB->RGB

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值