www.pudn.com > MyImageDB(imageobject).rar > MyColorSpace.cpp


// MyColorSpace.cpp: implementation of the MyColorSpace class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "myimagedb.h" 
#include "MyColorSpace.h" 
#include  
#include "mymath.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
// Coefficient matrix for xyz and rgb spaces 
static const int    XYZ[3][3] = { { 4125, 3576, 1804 }, 
{ 2125, 7154,  721 }, 
{  193, 1192, 9502 } }; 
static const double  RGB[3][3] = {  
{ (float)3.2405, (float)-1.5371, (float)-0.4985 }, 
{(float)-0.9693,  (float)1.8760,  (float)0.0416 }, 
{ (float)0.0556, (float)-0.2040,  (float)1.0573 } }; 
 
// Constants for LUV transformation  
static const float     Xn = (float)0.9505; 
static const float     Yn = (float)1.0; 
static const float     Zn = (float)1.0888; 
static const float     Un_prime = (float)0.1978; 
static const float     Vn_prime = (float)0.4683; 
static const float     Lt = (float)0.008856; 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
MyColorSpace::MyColorSpace() 
{ 
 
} 
 
MyColorSpace::~MyColorSpace() 
{ 
 
} 
 
 
BOOL MyColorSpace::Rgb2Hsi(FLOAT r, FLOAT g, FLOAT b, FLOAT& h, FLOAT& s, FLOAT& i) 
//冈萨雷斯《数字图像处理》第二版,p235-p237; 
{ 
	//有问题; 
/* 
	h = r; 
	s = g; 
	i = b; 
*/ 
	FLOAT temp1 = (FLOAT) ( 0.5 * ( (r-g) + (r-b) ) ); 
	FLOAT temp2 = (FLOAT) sqrt( (r-g)*(r-g) + (r-g)*(g-b) ); 
	if (temp1>temp2) 
	{ 
		temp1=temp2=1;//本来不应该,但确实会有这种情况,晕! 
	} 
 
	FLOAT sita = (FLOAT) acos( temp1/temp2 ); 
	if (b<=g) 
	{ 
		h = sita; 
	}else 
	{ 
		h = 360 - sita; 
	} 
	 
	if (h>=360) 
	{ 
		h = h - 360; 
	} 
 
	s = (FLOAT) ( 1 - 3.0 * myMath.ReturnMinInThree(r, g, b) / (r + g + b) ); 
 
	i = (FLOAT) ( (r + g + b) / 3.0 ); 
 
	return TRUE; 
} 
 
BOOL MyColorSpace::Hsi2Rgb(FLOAT h, FLOAT s, FLOAT i, FLOAT& r, FLOAT& g, FLOAT& b) 
//冈萨雷斯《数字图像处理》第二版,p237; 
{ 
/* 
	r = h; 
	g = s; 
	b = i; 
*/ 
	if (h<0||h>=360) 
	{ 
		return FALSE; 
	} 
 
	if (h<120) 
	{ 
		b = i * ( 1 - s); 
		r = (FLOAT) ( i * ( 1 + s*cos(h) / cos(60.0-h) ) ); 
		g = 1 - ( r+b ); 
		return TRUE; 
	} 
 
	if (h<240) 
	{ 
		h = h - 120; 
		r = i * ( 1 - s); 
		g = (FLOAT) ( i * ( 1 + s*cos(h) / cos(60.0-h) ) ); 
		b = 1 - ( r+g ); 
		return TRUE; 
	} 
 
	if (h<360) 
	{ 
		h = h - 240; 
		g = i * ( 1 - s); 
		b = (FLOAT) ( i * ( 1 + s*cos(h) / cos(60.0-h) ) ); 
		r = 1 - ( g+b ); 
		return TRUE; 
	} 
 
	return FALSE; 
} 
 
BOOL MyColorSpace::Rgb2Ycbcr(FLOAT r, FLOAT g, FLOAT b, FLOAT& y, FLOAT& cb, FLOAT& cr) 
//据《Color and Texture Descriptors》by B.S.Manjunath,eg. 
{	 
	y = (FLOAT) ( 0.2989*r + 0.5866*g + 0.1145*b ); 
	cb = (FLOAT) ( -0.1687*r - 0.3312*g + 0.5000*b ); 
	cr = (FLOAT) ( 0.5000*r - 0.4183*g - 0.0816*b ); 
	return TRUE; 
} 
 
BOOL MyColorSpace::Rgb2Hsv(FLOAT r, FLOAT g, FLOAT b, FLOAT& h, FLOAT& s, FLOAT& v) 
//据《Color and Texture Descriptors》by B.S.Manjunath,eg. 
{	 
	//无定义(非彩色)时,h返回0; 
	FLOAT tempmax = (FLOAT) myMath.ReturnMaxInThree(r, g, b); 
	FLOAT tempmin = (FLOAT) myMath.ReturnMinInThree(r, g, b); 
 
	v = tempmax; 
 
	if (tempmax == 0) 
	{ 
		s = 0; 
	}else 
	{ 
		s = (tempmax - tempmin) / tempmax; 
	} 
 
	if (tempmax == tempmin) 
	{ 
		h = 0;//undefined(achromatic color); 
	}else 
	{ 
		if (tempmax==r && g>b) 
		{ 
			h = 60*(g-b) / (tempmax - tempmin); 
		}else if (tempmax==r &&gg)  
	{ 
		h = (FLOAT) ( 2*PI - h ); 
	} 
 
	s = (FLOAT) ( ( __max( r, __max(g,b) ) - __min( r, __min(g,b) ) ) / 255 ); 
	v = (FLOAT) ( (r+g+b) / (3.0*255) ); 
 
	return TRUE; 
} 
 
 
BOOL MyColorSpace::XyztoRgb(FLOAT* xyzDatas, int width, int height, BYTE* rgbDatas) 
{ 
	if (NULL == rgbDatas) 
	{ 
		CString tempstr; 
		tempstr.Format("传入内存未分配,在MyColorSpace::RGBtoHSV"); 
		AfxMessageBox(tempstr,NULL,MB_OK); 
		return FALSE;		 
	} 
 
	int i,j; 
	FLOAT r,g,b; 
	FLOAT x, y, z; 
	unsigned long pos; 
 
	for(i=0;i255) b=255; 
		else if(b<0) b=0; 
		 
		if(g>255) g=255; 
		else if(g<0) g=0; 
		 
		if(r>255) r=255; 
		else if(r<0) r=0; 
	} 
 
	return TRUE; 
} 
*/ 
 
BOOL MyColorSpace::Rgb2Xyz(FLOAT r, FLOAT g, FLOAT b, FLOAT& x, FLOAT& y, FLOAT& z) 
//RGB to CIE XYZitu(D65), 根据David Bourgin, Color space FAQ 
{ 
	x = (FLOAT) ( 0.431*r + 0.342*g + 0.178*b ); 
	y = (FLOAT) ( 0.222*r + 0.707*g + 0.071*b ); 
	z = (FLOAT) ( 0.020*r + 0.130*g + 0.939*b ); 
	return TRUE; 
} 
 
BOOL MyColorSpace::Xyz2Rgb(FLOAT x, FLOAT y, FLOAT z, FLOAT& r, FLOAT& g, FLOAT& b) 
//CIE XYZitu(D65) to RGB,根据David Bourgin, Color space FAQ 
{ 
	r =  (FLOAT) ( 3.063*x - 1.393*y - 0.476*z ); 
	g = (FLOAT) ( -0.969*x + 1.876*y + 0.042*z ); 
	b =  (FLOAT) ( 0.068*x - 0.229*y + 1.069*z ); 
	return TRUE; 
} 
 
BOOL MyColorSpace::Xyz2Luv(FLOAT x, FLOAT y, FLOAT z, FLOAT& l, FLOAT& u, FLOAT& v) 
//CIE XYZitu(D65) to CIE Luv,根据David Bourgin, Color space FAQ 
//The white point is D65 and have coordinates fixed as (xn;yn)=(0.312713;0.329016).  
//上面这句不懂意思。Xn、Yn和Zn的值来自D. Comaniciu, P. Meer,Robust Analysis of Feature Spaces: Color Image Segmentation 的相应代码 
{ 
	DOUBLE tempb = pow((y/Yn), (1.0/3.0)); 
	if (y/Yn>0.008856) 
	{ 
		l = (FLOAT) ( 116 * pow((y/Yn), (1.0/3.0)) ); 
	}else 
	{ 
		l = (FLOAT) ( 903.3 * y/Yn ); 
	} 
 
	float up = 4 * x / (x+15*y+3*z); 
	float vp = 9 * y / (x+15*y+3*z); 
    float upn = 4 * Xn / (Xn+15*Yn+3*Zn); 
	float vpn = 9 * Yn / (Xn+15*Yn+3*Zn); 
	 
	u = 13 * (l) * (up - upn); 
    v = 13 * (l) * (vp - vpn); 
 
	return TRUE; 
} 
 
BOOL MyColorSpace::Ycbcr2Rgb(FLOAT y, FLOAT cb, FLOAT cr, FLOAT& r, FLOAT& g, FLOAT& b) 
//Rec 601-1 YCbCr to RGB, 根据David Bourgin, Color space FAQ 
{ 
	r = (FLOAT) ( y + 0.0000*cb + 1.4022*cr ); 
	g = (FLOAT) ( y - 0.3456*cb - 0.7145*cr ); 
	b = (FLOAT) ( y + 1.7710*cb + 0.0000*cr ); 
 
	return TRUE; 
} 
 
FLOAT MyColorSpace::Labf(FLOAT input, FLOAT Y_Yn) 
//用于计算Lab色彩; 
{ 
	if (Y_Yn>0.008856) 
	{ 
		return (FLOAT)pow(input, (1.0/3.0));		 
	}else 
	{ 
		return (FLOAT) ( 7.787*input + 16./116. ); 
	}	 
} 
 
BOOL MyColorSpace::Xyz2Lab(FLOAT x, FLOAT y, FLOAT z, FLOAT& l, FLOAT& a, FLOAT& b) 
//CIE XYZitu(D65) to CIE Lab, 根据David Bourgin, Color space FAQ 
{ 
	FLOAT y_yn = y / Yn; 
	if (y_yn>0.008856) 
	{ 
		l = (FLOAT) ( 116. * pow(y_yn, 1./3.) ); 
	}else 
	{ 
		l = (FLOAT) ( 903.3 * y_yn ); 
	} 
    a = 500 * ( Labf(x/Xn, y_yn) - Labf(y/Yn, y_yn) ); 
    b = 200 * ( Labf(y/Yn, y_yn) - Labf(z/Zn, y_yn) ); 
 
	return TRUE;	 
} 
 
BOOL MyColorSpace::Lab2Lch(FLOAT li, FLOAT a, FLOAT b, FLOAT& lo, FLOAT& c, FLOAT& h) 
//CIE Lab to CIE LCH, 根据David Bourgin, Color space FAQ 
{ 
    lo = li; 
    c = (FLOAT) ( pow( (a*a+b*b), 0.5) ); 
 
	INT k= -1; 
	if (a>=0 && b>=0) 
	{ 
		k = 0; 
	}else if (a>=0 && b<0) 
	{ 
		k = 1; 
	}else if (a<0 && b<0) 
	{ 
		k = 2; 
	}else if (a<0 && b>=0) 
	{ 
		k = 3; 
	} 
 
	if (a==0) 
	{ 
		h = 0; 
	}else 
	{ 
		h = (FLOAT) ( (atan(b/a) + k*PI/2.) / (2.*PI) ); 
		if (h<0) 
		{ 
			h += (FLOAT) ( PI/2. ); 
		} 
	} 
 
	return TRUE; 
} 
 
#define MAXV 256 
BOOL MyColorSpace::RgbtoLuvPcm(BYTE* inDatas, int width, int height, MyLUV* luvbuff) 
//基于表转换,将位图图像数据转换为LUV数据, 修改自D. Comaniciu, P. Meer, 
//Robust Analysis of Feature Spaces: Color Image Segmentation 的相应代码 
{ 
	int x, y, z, my_temp; 
	 
	float l_star, u_star, v_star; 
	float u_prime, v_prime; 
	//register int temp_col, temp_index, temp_ind; 
	register int j;//,k; 
	 
	int a00=XYZ[0][0], a01=XYZ[0][1], a02=XYZ[0][2]; 
	int a10=XYZ[1][0], a11=XYZ[1][1], a12=XYZ[1][2]; 
	int a20=XYZ[2][0], a21=XYZ[2][1], a22=XYZ[2][2]; 
	 
	int *A00 = new int[MAXV]; int *A01 = new int[MAXV]; int *A02 = new int[MAXV]; 
	int *A10 = new int[MAXV]; int *A11 = new int[MAXV]; int *A12 = new int[MAXV]; 
	int *A20 = new int[MAXV]; int *A21 = new int[MAXV]; int *A22 = new int[MAXV]; 
	 
	for(j=0; j  Lt)  l_star = my_pow[(int)(tval*255+0.5)]; 
        else  l_star = (FLOAT) ( 903.3 * tval ); 
		 
        my_temp = x + 15 * y + 3 * z; 
		if(my_temp) 
		{ 
			u_prime = (float)(x << 2) / (float)(my_temp); 
			v_prime = (float)(9 * y) / (float)(my_temp); 
		} 
		else 
		{ 
			u_prime = 4.0; 
			v_prime = (FLOAT) ( 9.0/15.0 ); 
		} 
		 
		tval = 13*l_star; 
        u_star = tval * (u_prime - Un_prime); // Un_prime = 0.1978 
        v_star = tval * (v_prime - Vn_prime); // Vn_prime = 0.4683 
		 
		luvbuff[j].l = l_star; 
		luvbuff[j].u = u_star; 
		luvbuff[j].v = v_star; 
    } 
 
	delete [] my_pow; 
	delete [] A22; delete [] A21; delete [] A20; 
	delete [] A12; delete [] A11; delete [] A10; 
	delete [] A02; delete [] A01; delete [] A00; 
 
	return TRUE; 
} 
 
BOOL MyColorSpace::RgbtoLuv(BYTE* inDatas, int width, int height, MyLUV* luvbuff) 
//将位图图像数据转换为LUV数据; 
{ 
	if (NULL == luvbuff) 
	{ 
		CString tempstr; 
		tempstr.Format("传入内存未分配,在MyColorSpace::RgbtoLuv"); 
		AfxMessageBox(tempstr,NULL,MB_OK); 
		return FALSE;		 
	} 
 
	int i,j; 
	FLOAT r,g,b; 
	unsigned long pos; 
 
	for(i=0;i255) r=255; 
		else if(r<0) r=0; 
		 
		if(g>255) g=255; 
		else if(g<0) g=0; 
		 
		if(b>255) b=255; 
		else if(b<0) b=0; 
	} 
	 
	return TRUE; 
}