参考: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]); } } }
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