⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cretrievemethod.cpp

📁 关于基于内容的图像特征的检索VC的实现,包括直方图,累计直方图等
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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;i<iCurrentCharacter;i++)
					  distance1=distance1+pow(KeybmpCharactervq.m_dFileStandCharacter[i]-(pCharacterVq+min)->m_dFileStandCharacter[i],2.0);
					  distance2=distance2+pow(KeybmpCharactervq.m_dFileStandCharacter[i]-(pCharacterVq+max)->m_dFileStandCharacter[i],2.0);
				if(distance1<distance2)
				  iFindNumber=min;
				else 
					  iFindNumber=max;
				break;
		  }
	  }

///找到最接近的那个,我们开始对它的附近检索
///具体的算法参考《矢量量化编码算法及应用研究》,陆哲明,2001,1
/////这里给出程序
	double dDistanceCurrent=0,dDistanceMin=0;//当前的距离
	int index=iFindNumber;              ///检索结果的索引
	for(i=0;i<iCurrentCharacter;i++)
		  dDistanceCurrent=dDistanceCurrent+pow(KeybmpCharactervq.m_dFileStandCharacter[i]-(pCharacterVq+iFindNumber)->m_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;i<iRetrieveBmpNumber;i++)
{
////如果向上检索还需进行
 if(flagup==TRUE&&flagdown==TRUE)  
	  break;
 if(flagup==FALSE)
	  {
		if((iFindNumber-i)<0||(pCharacterVq+iFindNumber-i)->m_dAverage<mmin)       ///如果向上不能再检索
		{
			  flagup=TRUE;         
		}
		else
		{
      ///计算距离
			  distancevarible=0;
			  for(j=0;j<iCurrentCharacter;j++)
					distancevarible=distancevarible+pow(KeybmpCharactervq.m_dFileStandCharacter[j]-(pCharacterVq+iFindNumber-i)->m_dFileStandCharacter[j],2.0);
			  if (distancevarible<dDistanceCurrent)
			  {
				  index=iFindNumber-i;
				  dDistanceCurrent=distancevarible;
			  }
			 
		}
			   
	  }
 if(flagdown==FALSE)
	  {
			if((iFindNumber+i)>=iRetrieveBmpNumber||(pCharacterVq+iFindNumber+i)->m_dAverage>mmax)       ///如果向上不能再检索
		{
			  flagdown=TRUE;         
		}
		else
		{
      ///计算距离
			  distancevarible=0;
			  distancevarible=0;
			  for(j=0;j<iCurrentCharacter;j++)
					distancevarible=distancevarible+pow(KeybmpCharactervq.m_dFileStandCharacter[j]-(pCharacterVq+iFindNumber+i)->m_dFileStandCharacter[j],2.0);
			  if (distancevarible<dDistanceCurrent)
			  {
				  index=iFindNumber+i;
				  dDistanceCurrent=distancevarible;
			  }
			 
		}
	  }
	  if(dDistanceCurrent==dDistanceMin)
			continue;
	   dDistanceMin=dDistanceCurrent;
	  if(flagup==FALSE)
	  	mmin=KeybmpCharactervq.m_dAverage-sqrt(dDistanceMin/iCurrentCharacter);  ///快速检索的上下限
	  if (flagdown==FALSE) 
	    mmax=KeybmpCharactervq.m_dAverage+sqrt(dDistanceMin/iCurrentCharacter);

}
///事后处理
	time2=clock();
	timecost=(double)(time2-time1)/CLOCKS_PER_SEC;
	RetrieveTime->Empty();
	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;number<iRetrieveBmpNumber;number++)
		pDistance[number]=pow((KeybmpCharactervq.m_dFileStandCharacter[vector]-(pCharacterVq+number)->m_dFileStandCharacter[vector]),2); ///第k种检索方式  
	
///到现在为止,pDistance[]保存了各个图象和关键图的颜色距离,绝对值
///排序,按着从小到大排序
//基本方法,找到最小的欧式距离后,将它所对应的图象路径给显示数组,然后将赋值256
//由于归一化后的图象的欧式距离不可能为256,故在找下一个图象时不会重复
			int sign=0;            ///做最相似图象的标号
			for(int displaynumber=0;displaynumber<maxOutNumber;displaynumber++)//16个显示图象
			{
				if(displaynumber>iRetrieveBmpNumber-1)        //如果图像数目不够,退出
					{
					
						displaynumber=iRetrieveBmpNumber;
						break;
					}	
					for(int check=0;check<iRetrieveBmpNumber;check++)
					{
						if(pDistance[sign]>pDistance[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;displaynumber<maxOutNumber;displaynumber++)//16个显示图象
		  {
			if(displaynumber>iRetrieveBmpNumber-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;i<iCurrentCharacter;i++)
					  distance1=distance1+pow(KeybmpCharactervq.m_dFileStandCharacter[i]-(pCharacterVq+min)->m_dFileStandCharacter[i],2.0);
					  distance2=distance2+pow(KeybmpCharactervq.m_dFileStandCharacter[i]-(pCharacterVq+max)->m_dFileStandCharacter[i],2.0);
				if(distance1<distance2)
				  iFindNumber=min;
				else 
					  iFindNumber=max;
				break;
		  }
	  }

///找到最接近的那个,我们开始对它的附近检索
///具体的算法参考《矢量量化编码算法及应用研究》,陆哲明,2001,1
//////这里与最邻近的图像检索有所不同,在最邻近的检索算法中,我们是以矢量均值最接近的d
///来制检索上下限,而在检索前16幅图像时,我们是以dmin附近的k幅图像中的距离最大的来控制
////上下限,而且在检索过程中,不断更新前K图像
/////找到控制上下限的参数dDistanceCurrent
	double dDistanceCurrent=0;//当前的距离
	double distancevarible=0;  ///变量
	double kdistancevarible[16];       ///我们保存16个距离,从小到大的排序
	int index[16];            ///16个索引,我们让他们关键图的距离从小到大排序
	int indexvarible;                  ///变量
	for(i=0;i<iCurrentCharacter;i++)
		  dDistanceCurrent=dDistanceCurrent+pow(KeybmpCharactervq.m_dFileStandCharacter[i]-(pCharacterVq+iFindNumber)->m_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;j<iCurrentCharacter;j++)
					kdistancevarible[i-finddmaxup]=kdistancevarible[i-finddmaxup]+pow(KeybmpCharactervq.m_dFileStandCharacter[j]-(pCharacterVq+i)->m_dFileStandCharacter[j],2.0);
	  }
	  ///排序,从小到大
	  for(i=finddmaxup;i<finddmaxdown;i++)
	  {
			for(j=i+1;j<=finddmaxdown;j++)
			if(kdistancevarible[i-finddmaxup]>kdistancevarible[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);  ///快速检索的上下限

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -