图像相似度

 图像相似度

       图像相似度是指图像的相似程序。本文给出了实现步骤与代码。

      

一、大致实现步骤如下:

  1, 将图像转换成相同大小,以有利于计算出相像的特征

  2, 计算转化后的灰度,二值

  3, 利用相似度公式,得到图像相似度的定量度量

  4, 统计相似度结果数据

      相似度公式:

    

 

二、部分代码

    #define MAX(a, b) (((a) > (b)) ? (a) : (b))
//计算相减后的绝对值
float GetAbs(float f, float s)
{
 float abs = fabs((float)f - (float)s);
 float result = MAX(f, s);
 if (result == 0)
  result = 1;
 return abs / result;
}

//相似度
float GetResult(float firstNum[], float scondNum[],int nSize)
{
 if (nSize==0)
 {
  return 0;
 }
 else
 {  
  float result = 0;  
  int j = nSize;  
  for (int i = 0; i < j; i++)   
  {  
   result += 1 - GetAbs(firstNum[i], scondNum[i]);    
  }  
  return result/j;  
 }
}

//函数功能:自动普通二值化
//参数说明:iSrc,表示原图像
//iDst,表示目标图像
//nLevel,表示阈值 [OUT]
//iIterationTimes,表示迭代次数
void AutoThreshold(CxImage *iSrc, int &nLevel,CxImage *iDst,int iIterationTimes)
{
 void* pDib = NULL;
 pDib = iSrc->GetDIB();
 if (!pDib)
  return ;
 if (iSrc->GetBpp()==1)
  return ;
 
 long iWidth = 0,iHeight =0,x = 0,y = 0,i = 0,t = 0;
 unsigned   char   iThreshold,   iNewThreshold,   iMaxGrayValue = 255,   iMinGrayValue = 0,   iMean1GrayValue,   iMean2GrayValue;  
 double   w0,w1,iMeanGrayValue;  
 double   G=0,   tempG=0;   
    long   lP1,   lS1,   lP2,   lS2;    
 iWidth = iSrc->GetWidth();
 iHeight = iSrc->GetHeight();
 //保存原始图像
 CxImage tmpSrc(iWidth,iHeight,iSrc->GetBpp());
 tmpSrc.Copy(*iSrc);
 ///////////////////////////////////////////////
 iSrc->GrayScale();
 //灰度分布统计
    long *pGray = new long[256];
 memset(pGray,0,sizeof(long)*256);
 for (y=0;y<iHeight;y++)
 {
  for (x=0;x<iWidth;x++)
  {
   i = iSrc->GetPixelIndex(x,y);
   pGray[i]++;
   //修改最大灰度值和最小灰度值  
   if(iMinGrayValue > i)  
   {  
    iMinGrayValue  =  i;  
   }  
   if(iMaxGrayValue <  i)  
   {  
    iMaxGrayValue  =  i;  
   } 
  }
 }

 //   遍历t,   选取最佳阈值  
 for(t   =   iMinGrayValue;   t   <   iMaxGrayValue   ;   t++)  
 {  
  iNewThreshold   =   t;  
  lP1   =   0;  
  lS1   =   0;  
  lP2   =   0;  
  lS2   =   0;  
  
  //     求前景,背景两个区域的平均灰度值,   点数所占比例  
  for(i   =   iMinGrayValue;   i   <=   iNewThreshold;   i++)  
  {  
   lP1   +=   pGray[i]   *   i;  
   lS1   +=   pGray[i];  
  }
  if(lS1==0)
   continue;
  iMean1GrayValue   =   (unsigned   char)   (lP1/lS1);  
  w0   =   (double)   (lS1)   /   (iWidth   *   iHeight);  
  for(i   =   iNewThreshold   +   1;   i   <=   iMaxGrayValue;   i++)  
  {  
   lP2   +=   pGray[i]   *   i;  
   lS2   +=   pGray[i];  
  } 
  if(lS2==0)
   continue;
  iMean2GrayValue   =   (unsigned   char)   (lP2/lS2);  
  w1   =   1   -   w0;  
  iMeanGrayValue=w0*iMean1GrayValue +w1*iMean2GrayValue ;
  
  G   =  w0 *(iMean1GrayValue-iMeanGrayValue)*(iMean1GrayValue-iMeanGrayValue)+w1*
   (iMean2GrayValue-iMeanGrayValue)*(iMean2GrayValue-iMeanGrayValue);  
  if(G   >   tempG)    
  {  
   tempG   =   G;  
   iThreshold   =   iNewThreshold;  
  }  
 }  

    nLevel = iThreshold;
 if(pGray)
 {
  delete []pGray;
  pGray = NULL;
 }
 ////////////////////////////////////////////////
 CxImage tmp(iWidth,iHeight,1);
 if (!tmp.IsValid())
 {
  return ;
 }
 
 for (y=0;y<iHeight;y++)
 {
  for (x=0;x<iWidth;x++)
  {
   i = iSrc->GetPixelIndex(x,y);
   if (i>nLevel)
    tmp.SetPixelIndex(x,y,0);
   else
    tmp.SetPixelIndex(x,y,1);
  }
 }
 tmp.SetPaletteColor(0,255,255,255);
 tmp.SetPaletteColor(1,0,0,0);
 iDst->Transfer(tmp);
 //
 iSrc->Copy(tmpSrc);
}

 

//图像的相似比率

float ImageSameRatio(CxImage *iSrc,CxImage *iDst)
{
    float fRadio = 1.0f,fRadio1 = 1.0f,fRadio2 = 1.0f;
 long iWidth = 0,iHeight =0,x = 0,y = 0,i = 0,t = 0,j = 0;
 long iWidth2 = 0,iHeight2 = 0;;
 iWidth = iSrc->GetWidth();
 iHeight = iSrc->GetHeight();
 //统一成一样的大小
    iWidth2 = iDst->GetWidth();
 iHeight2 = iDst->GetHeight();
 if(iWidth==iWidth2 && iHeight==iHeight2)
 {

 }
 else
 {
  int nImageType = iSrc->GetType();
   CxImage * newIma = new CxImage(nImageType);
  iDst->Resample(iWidth,iHeight,1,newIma);
  iDst->Copy(*newIma);
 }
 //////////////////////////////////////////////
 //二值化处理
 int nLevel = 128;
 CxImage *pBinImage1 = NULL,*pBinImage2 = NULL;
 pBinImage1 = new CxImage(iWidth,iHeight,1);
 pBinImage2 = new CxImage(iWidth,iHeight,1);
 AutoThreshold(iSrc,nLevel,pBinImage1,200);
 AutoThreshold(iDst,nLevel,pBinImage2,200);
    //提取iSizeX*iSizeY点比率特征
    int iSizeX = 3,iSizeY = 3;
 int mm=0,nn=0,num = 0;
 mm = (iWidth+iSizeX-1)/iSizeX;
 nn = (iHeight+iSizeY-1)/iSizeY;
 float *pDotRadio1 = new float[mm*nn+1];
    memset(pDotRadio1,0,sizeof(float)*(mm*nn+1));
 float *pDotRadio2 = new float[mm*nn+1];
    memset(pDotRadio2,0,sizeof(float)*(mm*nn+1));
    for(j=0;j<nn;j++)
 {
  for(i=0;i<mm;i++)
  {
   fRadio = 0.0f;
   num = 0;
   for(y=j*iSizeY;y<j*iSizeY+iSizeY;y++)
   {
    for(x=i*iSizeX;x<i*iSizeX+iSizeX;x++)
    {
     if(x>=iWidth || y>=iHeight)
      continue;
     fRadio += pBinImage1->GetPixelIndex(x,y);
     num = num + 1;
    }
   }
   if(num!=0)
   {
    pDotRadio1[j*mm+i] = fRadio/num;
   }
  }
 }

    for(j=0;j<nn;j++)
 {
  for(i=0;i<mm;i++)
  {
   fRadio = 0.0f;
   num = 0;
   for(y=j*iSizeY;y<j*iSizeY+iSizeY;y++)
   {
    for(x=i*iSizeX;x<i*iSizeX+iSizeX;x++)
    {
     if(x>=iWidth || y>=iHeight)
      continue;
     fRadio += pBinImage2->GetPixelIndex(x,y);
     num = num + 1;
    }
   }
   if(num!=0)
   {
    pDotRadio2[j*mm+i] = fRadio/num;
   }
  }
 }

    fRadio = GetResult(pDotRadio1,pDotRadio2,nn*mm);
 if(pDotRadio1)
 {
  delete []pDotRadio1;
  pDotRadio1 = NULL;
 }
    if(pDotRadio2)
 {
  delete []pDotRadio2;
  pDotRadio2 = NULL;
 }


//   pBinImage1->Save("c://1.tif",CXIMAGE_FORMAT_TIF);
// pBinImage2->Save("c://2.tif",CXIMAGE_FORMAT_TIF);
 if(pBinImage1)
 {
  delete pBinImage1;
 }
 if(pBinImage2)
 {
  delete pBinImage2;
 }
 return fRadio;
}

注:使用了Cximage开源图像处理库。

你可能感兴趣的:(c,null,delete,float,图像处理)