www.pudn.com > CRetrieveMethod.rar > CRetrieveMethod.cpp


// CRetrieveMethod.cpp: implementation of the CCRetrieveMethod class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "VqRetrieve.h" 
#include "CRetrieveMethod.h" 
#include "math.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CRetrieveMethod::CRetrieveMethod() 
{ 
 
} 
 
CRetrieveMethod::~CRetrieveMethod() 
{ 
 
} 
//升序 
void CRetrieveMethod::ListByAverage(CHARACTERVQ *pCharacterVq, long int iRetrieveBmpNumber) 
{ 
 
	long int i,j; 
	long int index;  //索引 
	CHARACTERVQ varible; 
	for(i=0;im_dAverage>(pCharacterVq+j)->m_dAverage)  
			{ 
				index=j; 
			}  //end of for j,get the index 
 
			if (index==i)  //本身最小 
			{ 
				continue;//next i 
			} 
			varible=*(pCharacterVq+i); 
			*(pCharacterVq+i)=*(pCharacterVq+index); 
			*(pCharacterVq+index)=varible; 
	} 
} 
 
//计算高:dataheigth,datawidth首地址为*pdata的特征矢量存在结构体中:charactervq 
//characterfirst:为特征矢量结构体的存入的第一个的编号,characternumber:该算法提取参数的个数 
///本算法中,characternumber必须等于7 
bool CRetrieveMethod::CharacterVqDistillMethod_1_7(unsigned char *pdata, int datawidth, int dataheigth, CHARACTERVQ *charactervq, int characterfirst, int characternumber) 
{ 
	if (characternumber!=7)  
	{ 
		MessageBox(NULL,"CharacterDistill Number error","error!",MB_OK); 
		return false; 
	} 
////add your word here 
/////注意:计算一个特征量,iCharacterNumbercheck++; 
////////////////////////////////////////////////////////////////////////// 
	////////参数1:最佳域值 
	//////算法:给定初始值,将像素分为两部分,计算个自的中心,中心的均值作为新的域值,与 
	//////////前一次的最佳域值比较,若相同则结束 
	/////////并用最大值限制迭代次数 
	////说明:参数1,2是颜色中的不变量,是在最佳域值方法中提取出来的 
		int i,j; 
		double regiondata1=128,regiondata2=128;         ///最佳域值初值 
		int Max=1000;                                     ///迭代最多的次数 
		int regionnumberleft=0,regionnumberright=0;           ////两个区域的计数值 
		long double regiontotallleft=0,regiontotalright=0;         ////两个区域的总和 
		long int count;     //计数器 
	 
		for(count=0;countm_dFileOriginalCharacter[characterfirst+0]=regiondata2/255.0; ///归一化 
	 
///参数2 
	charactervq->m_dFileOriginalCharacter[characterfirst+1]=(double)regionnumberleft/(regionnumberleft+regionnumberright); 
////end of 颜色 
	///颜色参数的个数 
 
//////说明:参数3,4,5是纹理中的不变量,他们是在共生矩阵中提取的 
////参数3: 
///统计共生矩阵 
	double (*texturematrix)[256]=new double[256][256];  ///共生矩阵x 
	double (*texturematriy)[256]=new double[256][256];  ///共生矩阵x 
	for(i=0; i<256; i++) 
			for(j=0; j<256; j++) 
			{ 
				texturematrix[i][j]=0; 
				texturematriy[i][j]=0; 
 
			} 
	for(i=1; im_dFileOriginalCharacter[characterfirst+2]=(Con1+Con2)/2/255.0/255.0;             //提取反差变量 
	charactervq->m_dFileOriginalCharacter[characterfirst+3]=(Asm1+Asm2)/2;              ///提取能量变量 
	charactervq->m_dFileOriginalCharacter[characterfirst+4]=-(Ent1+Ent2)/2;              ///提取熵变量 
	delete[] texturematrix; 
	delete[] texturematriy; 
 
 
//////参数3,4,5提取结束	 
////end of 纹理 
///纹理参数的个数 
 
	 
////参数6,7提取:形状不变量 
///////二阶矩和一阶矩 
/////特点:矩是对图像的一种的一种统计形式,他的计算要用到图像或区域中的所有相关的像素点, 
////	对一个数字图像函数F(X),如果他分段连续且只在XY平面上的有限个点不为零,则可以证明他的 
////////各阶矩存在。 
	  	//范例图像的各阶矩的声明 
	double M_00=0.0,M_01=0.0,M_10=0.0,M_11=0.0,M_20=0.0,M_02=0.0;//P+Q阶矩 
    double U_00=0.0,U_11=0.0,U_20=0.0,U_02=0.0;//P+Q阶中心矩 
	double m_00,n_00;//重心坐标 
	double u_00,u_11,u_20,u_02;//归一化的P+Q阶中心矩 
 	///计算范例图的各阶矩 
	for(int l=0; lm_dFileOriginalCharacter[characterfirst+5]=(pow((u_20-u_02),2.0)+4*u_11*u_11);  ////保存  
		///一阶不变矩保存 
		charactervq->m_dFileOriginalCharacter[characterfirst+6]=(u_20+u_02); 
	return true; 
} 
	//矢量检索,方法1 
///直接的检索矢量,对图像的矢量进行检索 
///pCharacterVq图像库矢量结构体指针,iCurrentCharacter:检索矢量的数量, 
//iRetrieveBmpNumber图像库图像数目, KeybmpCharactervq :关键图像的结构 
//pOutCharactervq:输出结构体的头指针,maxOutNumber输出图像的最多数目,*pOutBmpNumber:输出图像的数目的地址 
//pDistance检索图像和关键图像的距离输出的头指针,RetrieveTime检索时间 
bool CRetrieveMethod::RetrieveKeyVqMethod_1Nomal(CHARACTERVQ *pCharacterVq, int iCurrentCharacter, long iRetrieveBmpNumber, CHARACTERVQ KeybmpCharactervq, CHARACTERVQ *pOutCharactervq, unsigned char maxOutNumber, unsigned char *pOutBmpNumber, double *pOutDistance, CString *RetrieveTime) 
{ 
	int vector=iCurrentCharacter;  //特征量未计算完最大可以是100 
	double *pDistance=new double[iRetrieveBmpNumber];//开辟内存空间保存距离数据 
	///开辟内存,载入颜色几何均值 
	////初始化//// 
	clock_t time1,time2;       ///定义时间变量  
	double timecost; 
	time1=clock(); 
			for(long int number=0;numberm_dFileStandCharacter[vectornumber]),2); ///第k种检索方式 
 
	} 
///到现在为止,pDistance[]保存了各个图象和关键图的颜色距离,绝对值 
///排序,按着从小到大排序 
//基本方法,找到最小的欧式距离后,将它所对应的图象路径给显示数组,然后将赋值256 
//由于归一化后的图象的欧式距离不可能为256,故在找下一个图象时不会重复 
			int sign=0;            ///做最相似图象的标号 
			for(int displaynumber=0;displaynumberiRetrieveBmpNumber-1)        //如果图像数目不够,退出 
					{ 
					 
						displaynumber=iRetrieveBmpNumber; 
						break; 
					}	 
					for(int check=0;checkpDistance[check])  //要最小的 
						{ 
							sign=check; 
						} 
					} 
					CHARACTERVQ* pcharactervqvar;  //临时 
					pcharactervqvar=(CHARACTERVQ*)(pOutCharactervq+displaynumber); 
					*pcharactervqvar=*(pCharacterVq+sign);///save the PathName for display 
					*(pOutDistance+displaynumber)=pDistance[sign]; 
					pDistance[sign]=100*36;             //给最大值100 个矢量*6*6 
 
		} 
///事后处理 
	delete[] pDistance;               //释放保存欧式距离内存 
	time2=clock(); 
	timecost=(double)(time2-time1)/CLOCKS_PER_SEC; 
	RetrieveTime->Empty(); 
	RetrieveTime->Format("%s%f",*RetrieveTime,timecost);  
///为显示文件名作准备, 
	*pOutBmpNumber=maxOutNumber; 
	for(displaynumber=0;displaynumberiRetrieveBmpNumber-1)        //如果图像数目不够,退出 
			{ 
				  *pOutBmpNumber=(unsigned char)iRetrieveBmpNumber; 
				 break; 
			  } 
		  } 
////////////////////////////////////////////////////////////////////////// 
 	return true; 
	 
} 
 
//矢量检索,方法2:快速检索最相似的一幅图像 
///pCharacterVq图像库矢量结构体指针,iCurrentCharacter:检索矢量的数量, 
//iRetrieveBmpNumber图像库图像数目, KeybmpCharactervq :关键图像的结构 
//pOutCharactervq:输出结构体的头指针,maxOutNumber=1输出图像的最多数目,*pOutBmpNumber:输出图像的数目的地址 
//pDistance检索图像和关键图像的距离输出的头指针,RetrieveTime检索时间 
bool CRetrieveMethod::RetrieveKeyVqMethod_2AccelerateBestOne(CHARACTERVQ *pCharacterVq,int iCurrentCharacter, long int iRetrieveBmpNumber,CHARACTERVQ KeybmpCharactervq, CHARACTERVQ *pOutCharactervq, unsigned char maxOutNumber,unsigned char *pOutBmpNumber, double *pOutDistance, CString *RetrieveTime) 
{ 
	///下面我们采用快速检索 
////我们的矢量是按照均值排序的,而且,均值在矢量的最后一维分量上,从小到大的排序 
////1.找和关键图的矢量最接近的矢量均值 
////采用二分法 
CHARACTERVQ testvq; 
testvq.m_dFileStandCharacter; 
	clock_t time1,time2;       ///定义时间变量  
	double timecost; 
	time1=clock(); 
	int min=0,max=iRetrieveBmpNumber;////二分法中的前后两个数 
	int iFindNumber; 
	int i,j; 
	while(1) 
	  { 
   //如果关键图的均值比中间的小 
		  if (KeybmpCharactervq.m_dAverage<(pCharacterVq+(min+max)/2)->m_dAverage) 
		  { 
				max=(min+max)/2; 
		  } 
		  else 
				min=(min+max)/2; 
   //上下限相等后相差一个单位,结束我们取均值较小的那个 
		  if (min==max||(min==(max-1))) 
		  { 
				double distance1=0; 
				double distance2=0; 
				for(i=0;im_dFileStandCharacter[i],2.0); 
					  distance2=distance2+pow(KeybmpCharactervq.m_dFileStandCharacter[i]-(pCharacterVq+max)->m_dFileStandCharacter[i],2.0); 
				if(distance1m_dFileStandCharacter[i],2.0); 
	dDistanceMin=dDistanceCurrent;   ///初始值 
	double mmin=KeybmpCharactervq.m_dAverage-sqrt(dDistanceCurrent/iCurrentCharacter);  ///快速检索的上下限 
	double mmax=KeybmpCharactervq.m_dAverage+sqrt(dDistanceCurrent/iCurrentCharacter);            ///快速检索的上下限 
	////检索开始 
	 BOOL flagup=FALSE,flagdown=FALSE;         ///上下检索标志是否继续标志 
	 double distancevarible=0;      ///变量 
	 if (dDistanceCurrent==0) 
	 { 
		   flagup=true; 
		   flagdown=true; 
	 } 
for(i=0;im_dAveragem_dFileStandCharacter[j],2.0); 
			  if (distancevarible=iRetrieveBmpNumber||(pCharacterVq+iFindNumber+i)->m_dAverage>mmax)       ///如果向上不能再检索 
		{ 
			  flagdown=TRUE;          
		} 
		else 
		{ 
      ///计算距离 
			  distancevarible=0; 
			  distancevarible=0; 
			  for(j=0;jm_dFileStandCharacter[j],2.0); 
			  if (distancevaribleEmpty(); 
	RetrieveTime->Format("%s%f",*RetrieveTime,timecost);  
///为显示文件名作准备, 
	*pOutBmpNumber=1; 
*(pOutDistance+0)=dDistanceCurrent; 
*(pOutCharactervq+0)=*(pCharacterVq+index); 
////////////////////////////////////////////////////////////////////////// 
 	return true; 
	 
} 
//矢量检索,方法3:对矢量的某一维分量进行检索:vector维分量 
///直接的检索矢量,对图像的矢量进行检索 
///pCharacterVq图像库矢量结构体指针,iCurrentCharacter:检索矢量的数量, 
//iRetrieveBmpNumber图像库图像数目, KeybmpCharactervq :关键图像的结构 
//pOutCharactervq:输出结构体的头指针,maxOutNumber输出图像的最多数目,*pOutBmpNumber:输出图像的数目的地址 
//pDistance检索图像和关键图像的距离输出的头指针,RetrieveTime检索时间 
///int vector:分量值0~iCurrentCharacter-1 
//0~100 
bool CRetrieveMethod::RetrieveKeyVqMethod_3Single(CHARACTERVQ *pCharacterVq,int iCurrentCharacter, long int iRetrieveBmpNumber,CHARACTERVQ KeybmpCharactervq, CHARACTERVQ *pOutCharactervq, unsigned char maxOutNumber,unsigned char *pOutBmpNumber, double *pOutDistance, CString *RetrieveTime,int vector) 
{ 
	if (vector>iCurrentCharacter-1) 
	{ 
		MessageBox(NULL,"this vector is not exist!","error",MB_OK); 
		return false; 
	} 
	double *pDistance=new double[iRetrieveBmpNumber];//开辟内存空间保存距离数据 
	///开辟内存,载入颜色几何均值 
	////初始化//// 
	clock_t time1,time2;       ///定义时间变量  
	double timecost; 
	time1=clock(); 
	for(long int number=0;numberm_dFileStandCharacter[vector]),2); ///第k种检索方式   
	 
///到现在为止,pDistance[]保存了各个图象和关键图的颜色距离,绝对值 
///排序,按着从小到大排序 
//基本方法,找到最小的欧式距离后,将它所对应的图象路径给显示数组,然后将赋值256 
//由于归一化后的图象的欧式距离不可能为256,故在找下一个图象时不会重复 
			int sign=0;            ///做最相似图象的标号 
			for(int displaynumber=0;displaynumberiRetrieveBmpNumber-1)        //如果图像数目不够,退出 
					{ 
					 
						displaynumber=iRetrieveBmpNumber; 
						break; 
					}	 
					for(int check=0;checkpDistance[check])  //要最小的 
						{ 
							sign=check; 
						} 
					} 
					CHARACTERVQ* pcharactervqvar;  //临时 
					pcharactervqvar=(CHARACTERVQ*)(pOutCharactervq+displaynumber); 
					*pcharactervqvar=*(pCharacterVq+sign);///save the PathName for display 
					*(pOutDistance+displaynumber)=pDistance[sign]; 
					pDistance[sign]=100*9;             //给最大值100 个食量*9 
 
		} 
///事后处理 
	delete[] pDistance;               //释放保存欧式距离内存 
	time2=clock(); 
	timecost=(double)(time2-time1)/CLOCKS_PER_SEC; 
	RetrieveTime->Empty(); 
	RetrieveTime->Format("%s%f",*RetrieveTime,timecost);  
///为显示文件名作准备, 
	*pOutBmpNumber=maxOutNumber; 
	for(displaynumber=0;displaynumberiRetrieveBmpNumber-1)        //如果图像数目不够,退出 
			{ 
				  *pOutBmpNumber=(unsigned char)iRetrieveBmpNumber; 
				 break; 
			  } 
		  } 
////////////////////////////////////////////////////////////////////////// 
 
	return true; 
} 
 
//矢量检索,方法4:快速检索最相似的前16幅图像 
///pCharacterVq图像库矢量结构体指针,iCurrentCharacter:检索矢量的数量, 
//iRetrieveBmpNumber图像库图像数目, KeybmpCharactervq :关键图像的结构 
//pOutCharactervq:输出结构体的头指针,maxOutNumber=16输出图像的最多数目,*pOutBmpNumber:输出图像的数目的地址 
//pDistance检索图像和关键图像的距离输出的头指针,RetrieveTime检索时间 
bool CRetrieveMethod::RetrieveKeyVqMethod_4AccelerateBest16(CHARACTERVQ *pCharacterVq,int iCurrentCharacter, long int iRetrieveBmpNumber,CHARACTERVQ KeybmpCharactervq, CHARACTERVQ *pOutCharactervq, unsigned char maxOutNumber,unsigned char *pOutBmpNumber, double *pOutDistance, CString *RetrieveTime) 
{ 
	clock_t time1,time2;       ///定义时间变量  
	double timecost; 
	time1=clock(); 
	int min=0,max=iRetrieveBmpNumber;////二分法中的前后两个数 
	int iFindNumber; 
	int i,j; 
	while(1) 
	  { 
   //如果关键图的均值比中间的小 
		  if (KeybmpCharactervq.m_dAverage<(pCharacterVq+(min+max)/2)->m_dAverage) 
		  { 
				max=(min+max)/2; 
		  } 
		  else 
				min=(min+max)/2; 
   //上下限相等后相差一个单位,结束我们取均值较小的那个 
		  if (min==max||(min==(max-1))) 
		  { 
				double distance1=0; 
				double distance2=0; 
				for(i=0;im_dFileStandCharacter[i],2.0); 
					  distance2=distance2+pow(KeybmpCharactervq.m_dFileStandCharacter[i]-(pCharacterVq+max)->m_dFileStandCharacter[i],2.0); 
				if(distance1m_dFileStandCharacter[i],2.0);	 
	int finddmaxup,finddmaxdown;        ////找最大的距离参数的上下限 
	BOOL flagup=FALSE,flagdown=FALSE;         ///上下检索标志是否继续标志 
	finddmaxup=iFindNumber-16/2;              ////上限 
	if(finddmaxup<=0)            //如果越界,我们不用在向上检索 
	{  
		finddmaxup=0; 
	  	flagup=TRUE; 
	} 
	finddmaxdown=finddmaxup+15;              ////下限 
	if(finddmaxdown>=iRetrieveBmpNumber)            //如果越界,我们不用像下检索 
	{  
		finddmaxdown=iRetrieveBmpNumber-1; 
		flagdown=TRUE; 
	} 
///初始化 
	for(i=0;i<16;i++) 
		  kdistancevarible[i]=0; 
///如果到图像数目小于16 
	if (iRetrieveBmpNumber<=16) 
	{ 
	  	  flagup=TRUE;    /////此时,finddminup=0;finddmaxdown=m_iOverSign 
		  flagdown=TRUE; 
	} 
///到顶上,图像数目大于16,且到顶部 
	else if(finddmaxup==0) 
	{ 
	  finddmaxdown=15;	  
	  flagup=TRUE; 
  
	} 
///到底端,图像数目大于16,且到底端 
	else if(finddmaxdown==iRetrieveBmpNumber-1) 
	 { 
		  finddmaxup=iRetrieveBmpNumber-16; 
		  flagdown=TRUE; 
		  ///获得距离 
	} 
///统一处理,计算它们的距离 
  { 
	for(i=finddmaxup;i<=finddmaxdown;i++) 
	  { 
		  index[i-finddmaxup]=i; ///给初始值 
		   for(j=0;jm_dFileStandCharacter[j],2.0); 
	  } 
	  ///排序,从小到大 
	  for(i=finddmaxup;ikdistancevarible[j-finddmaxup])///比后面的大 
			{ 
				  ////交换距离 
				  distancevarible=kdistancevarible[i-finddmaxup]; 
				  kdistancevarible[i-finddmaxup]=kdistancevarible[j-finddmaxup]; 
				  kdistancevarible[j-finddmaxup]=distancevarible; 
				  ////交换索引号 
				  indexvarible=index[i-finddmaxup]; 
				  index[i-finddmaxup]=index[j-finddmaxup]; 
				  index[j-finddmaxup]=indexvarible; 
 
			} 
	  } 
	} 
////检索	  
///我们以新的dDistanceCurrent作为上下限的控制来检索 
///当然如果图像数目不够,我们应该控制 
///具体的算法参考《矢量量化编码算法及应用研究》,陆哲明,2001,1 
/////这里给出程序 
///////我们检索的是前16幅图像 
	dDistanceCurrent=kdistancevarible[15];        ///取最大的 
	double mmin=KeybmpCharactervq.m_dAverage-sqrt(dDistanceCurrent/iCurrentCharacter);  ///快速检索的上下限 
	double mmax=KeybmpCharactervq.m_dAverage+sqrt(dDistanceCurrent/iCurrentCharacter);            ///快速检索的上下限 
////向上下搜索 
for(i=1;im_dAveragem_dFileStandCharacter[j],2.0); 
			  if (distancevarible=0;t--)  
					{ 
 
						  if(distancevarible=iRetrieveBmpNumber||(pCharacterVq+finddmaxdown+i)->m_dAverage>mmax)       ///如果向上不能再检索 
		{ 
			  flagdown=TRUE;          
		} 
		else 
		{ 
      ///计算距离 
			  distancevarible=0; 
			  for(j=0;jm_dFileStandCharacter[j],2.0); 
			  if (distancevarible=0;t--) 
					{ 
 
						  if(distancevaribleEmpty(); 
	  RetrieveTime->Format("%s%f",*RetrieveTime,timecost);	 
  
///为显示文件名作准备,显示文件名为:m_sDisplayFileName 
///为显示文件名作准备, 
	*pOutBmpNumber=maxOutNumber;  //默认16 
	for(int displaynumber=0;displaynumberiRetrieveBmpNumber-1)        //如果图像数目不够,退出 
			{ 
				 *pOutBmpNumber=(unsigned char)iRetrieveBmpNumber; 
				 break; 
			 } 
			pOutDistance[displaynumber]=kdistancevarible[displaynumber]; 
			pOutCharactervq[displaynumber]=pCharacterVq[index[displaynumber]]; 
		  } 
////////////////////////////////////////////////////////////////////////// 
 
////////////////////////////////////////////////////////////////////////// 
	return true; 
} 
///用参数归一化一矢量结构体 
	//KeybmpCharactervq :关键图像的结构,characternumber矢量的数目 
	//pstandequvarible,方差的头指针,pstandaverage均值的头指针 
bool CRetrieveMethod::StandKeyBmp(CHARACTERVQ *KeybmpCharactervq,int characternumber,double *pstandequvarible,double *pstandaverage) 
{ 
		 
      const double mindata=1e-15; 
	  int i; 
	  for(i=0;im_dFileStandCharacter[i]=(KeybmpCharactervq->m_dFileOriginalCharacter[i]-*(pstandaverage+i))/(*(pstandequvarible+i));	 
			if(fabs(KeybmpCharactervq->m_dFileStandCharacter[i])<=3.0) 
						continue; 
				  else if (KeybmpCharactervq->m_dFileStandCharacter[i]<-3) 
				  { 
						KeybmpCharactervq->m_dFileStandCharacter[i]=-3; 
				  } 
				  else  
				  { 
						KeybmpCharactervq->m_dFileStandCharacter[i]=3; 
				  } 
	  } 
///给出均值 
	double Datatotal=0; 
	 for(i=0;im_dFileStandCharacter[i]; 
		   KeybmpCharactervq->m_dAverage=Datatotal/characternumber; 
	return true; 
} 
 
////标准化参数 
/////charactervq:待归一化的结构;numberbmp=图像的数目;characternumber:矢量的维数 
///pstandequvarible:输出标准差的首地址,pstandaverage:输出均值的首地址 
bool CRetrieveMethod::StandCharacter(CHARACTERVQ *charactervq,long int numberbmp,int characternumber,double *pstandequvarible,double *pstandaverage) 
{ 
	  long double Datatotal=0;  /////同一类的参数的和 
	  long int number;     ///循环计数,矢量维数 
	  double Average,squareDifference;  ////均值和方差 
	  for(number=0;numberm_dFileOriginalCharacter[number]; 
			} 
			Average=Datatotal/numberbmp;     ///均值 
			Datatotal=0;   ///初始化 
			for(i=0;im_dFileOriginalCharacter[number]-Average,2.0); 
			} 
			squareDifference=sqrt(Datatotal/numberbmp); 
			*(pstandequvarible+number)=squareDifference;///////均方差输出 
			*(pstandaverage+number)=Average;///均值输出 
			for(i=0;im_dFileStandCharacter[number]=((charactervq+i)->m_dFileOriginalCharacter[number]-Average)/(*(pstandequvarible+number)); 
				  if(fabs((charactervq+i)->m_dFileStandCharacter[number])<=3.0)  //限制范围 
						continue; 
				  else if ((charactervq+i)->m_dFileStandCharacter[number]<-3) 
				  { 
						(charactervq+i)->m_dFileStandCharacter[number]=-3; 
				  } 
				  else  
				  { 
						(charactervq+i)->m_dFileStandCharacter[number]=3; 
				  } 
			} 
	  } 
///计算均值 
	   for(number=0;numberm_dFileStandCharacter[i]; 
		   (charactervq+number)->m_dAverage=Datatotal/characternumber; 
 
	   } 
//// 
return true; 
	 
} 
///方法2:计算基于颜色的三个的三个中心矩 
//计算高:dataheigth,datawidth首地址为*pdata的特征矢量存在结构体中:charactervq 
//characterfirst:为特征矢量结构体的存入的第一个的编号,characternumber:该算法提取参数的个数 
///本算法中,characternumber必须等于3 
bool CRetrieveMethod::CharacterVqDistillMethod_2_3(unsigned char *pdata, int datawidth, int dataheigth, CHARACTERVQ *charactervq, int characterfirst, int characternumber) 
{ 
	if (characternumber!=3)  
	{ 
		MessageBox(NULL,"CharacterDistill Number error","error!",MB_OK); 
		return false; 
	} 
////add your word here 
////////////////////////////////////////////////////////////////////////// 
	////////参数1:///像素均值 
	int width,height;           //高宽 
	long int length=dataheigth*datawidth; 
	int i;			///变量 
	double M1=0,M2=0,M3=0;         ///三阶矩 
	double *pihistogram=new double[256]; 
	// 
	for(i=0;i<256;i++) 
	{ 
		pihistogram[i]=0; 
	} 
	for(height=0;heightm_dFileOriginalCharacter[characterfirst+0]=M1; 
	charactervq->m_dFileOriginalCharacter[characterfirst+1]=M2; 
	charactervq->m_dFileOriginalCharacter[characterfirst+2]=M3; 
////////////////////////////////////////////////////////////////////////// 
///end of 计算 
///delete the memory 
	delete[]pihistogram; 
	return true; 
} 
///提取参数,三阶矩 
bool CRetrieveMethod::CharacterVqDistillMethod_3_1(unsigned char *pdata, int datawidth, int dataheigth, CHARACTERVQ *charactervq, int characterfirst, int characternumber) 
{ 
	if (characternumber!=1)  
	{ 
		MessageBox(NULL,"CharacterDistill Number error","error!",MB_OK); 
		return false; 
	} 
////add your word here 
////////////////////////////////////////////////////////////////////////// 
	double M_00=0.0,M_01=0.0,M_10=0.0,M_12=0.0,M_30=0.0,M_03=0.0;//P+Q阶矩 
    double U_00=0.0,U_21=0,U_12=0.0,U_30=0.0,U_03=0.0;//P+Q阶中心矩 
	double m_00,n_00;//重心坐标 
	double u_00,u_12,u_21,u_30,u_03;//归一化的P+Q阶中心矩 
	///计算范例图的各阶矩 
 unsigned 	 char * pBits = pdata; 
	for(int l=0; lm_dFileOriginalCharacter[characterfirst+0]=pow((u_30-3*u_12),2.0)+pow((3*u_21-u_03),2.0); 
	//end 
	return true; 
}