图片相似度比较方法及源码.docx
《图片相似度比较方法及源码.docx》由会员分享,可在线阅读,更多相关《图片相似度比较方法及源码.docx(10页珍藏版)》请在冰豆网上搜索。
图片相似度比较方法及源码
图片相似度比较方法及源码
一、大致实现步骤如下:
1,将图像转换成相同大小,以有利于计算出相像的特征
2,计算转化后的灰度,二值
3,利用相似度公式,得到图像相似度的定量度量
4,统计相似度结果数据
相似度公式:
二、部分代码
#defineMAX(a,b)(((a)>(b))?
(a):
(b))
计算相减后的绝对值//
floatGetAbs(floatf,floats){
floatabs=fabs((float)f-(float)s);
floatresult=MAX(f,s);
if(result==0)
result=1;
returnabs/result;
}
//相似度
floatGetResult(floatfirstNum[],floatscondNum[],intnSize)
{
if(nSize==0)
{
return0;
}
else
{
floatresult=0;
intj=nSize;
for(inti=0;i{
result+=1-GetAbs(firstNum[i],scondNum[i]);
}
returnresult/j;
}
}
//函数功能:
自动普通二值化
//参数说明:
iSrc,表示原图像
//iDst,表示目标图像
//nLevel,表示阈值[OUT]
//iIterationTimes,表示迭代次数
voidAutoThreshold(CxImage*iSrc,int&nLevel,CxImage*iDst,intiIterationTimes)
{
void*pDib=NULL;
pDib=iSrc->GetDIB();
if(!
pDib)
return;
if(iSrc->GetBpp()==1)
return;
longiWidth=0,iHeight=0,x=0,y=0,i=0,t=0;
unsignedchariThreshold,iNewThreshold,iMaxGrayValue=255,iMinGrayValue=
0,iMean1GrayValue,iMean2GrayValue;
doublew0,w1,iMeanGrayValue;
doubleG=0,tempG=0;
longlP1,lS1,lP2,lS2;
iWidth=iSrc->GetWidth();
iHeight=iSrc->GetHeight();
//保存原始图像
CxImagetmpSrc(iWidth,iHeight,iSrc->GetBpp());
tmpSrc.Copy(*iSrc);
///////////////////////////////////////////////
iSrc->GrayScale();
//灰度分布统计
long*pGray=newlong[256];
memset(pGray,0,sizeof(long)*256);
for(y=0;y{
for(x=0;x{
i=iSrc->GetPixelIndex(x,y);
pGray[i]++;
//修改最大灰度值和最小灰度值
if(iMinGrayValue>i)
{
iMinGrayValue=i;
}
if(iMaxGrayValue
{
iMaxGrayValue=i;
}
}
}
//遍历t,选取最佳阈值
for(t=iMinGrayValue;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=(unsignedchar)(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=(unsignedchar)(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;
}
////////////////////////////////////////////////
CxImagetmp(iWidth,iHeight,1);
if(!
tmp.IsValid())
{
return;
}
for(y=0;y{
for(x=0;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);
}
//图像的相似比率
floatImageSameRatio(CxImage*iSrc,CxImage*iDst)
{
floatfRadio=1.0f,fRadio1=1.0f,fRadio2=1.0f;
longiWidth=0,iHeight=0,x=0,y=0,i=0,t=0,j=0;
longiWidth2=0,iHeight2=0;;
iWidth=iSrc->GetWidth();
iHeight=iSrc->GetHeight();
//统一成一样的大小
iWidth2=iDst->GetWidth();
iHeight2=iDst->GetHeight();
if(iWidth==iWidth2&&iHeight==iHeight2)
{
}
else
{
intnImageType=iSrc->GetType();
CxImage*newIma=newCxImage(nImageType);
iDst->Resample(iWidth,iHeight,1,newIma);
iDst->Copy(*newIma);
}
//////////////////////////////////////////////
//二值化处理
intnLevel=128;
CxImage*pBinImage1=NULL,*pBinImage2=NULL;
pBinImage1=newCxImage(iWidth,iHeight,1);
pBinImage2=newCxImage(iWidth,iHeight,1);
AutoThreshold(iSrc,nLevel,pBinImage1,200);
AutoThreshold(iDst,nLevel,pBinImage2,200);
//提取iSizeX*iSizeY点比率特征
intiSizeX=3,iSizeY=3;
intmm=0,nn=0,num=0;
mm=(iWidth+iSizeX-1)/iSizeX;
nn=(iHeight+iSizeY-1)/iSizeY;
float*pDotRadio1=newfloat[mm*nn+1];
memset(pDotRadio1,0,sizeof(float)*(mm*nn+1));
float*pDotRadio2=newfloat[mm*nn+1];
memset(pDotRadio2,0,sizeof(float)*(mm*nn+1));
for(j=0;j{
for(i=0;i{
fRadio=0.0f;
num=0;
for(y=j*iSizeY;y{
for(x=i*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{
for(i=0;i{
fRadio=0.0f;
num=0;
for(y=j*iSizeY;y{
for(x=i*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)
{
deletepBinImage1;
}
if(pBinImage2)
{
deletepBinImage2;
}
returnfRadio;
}
注:
使用了Cximage开源图像处理库。