wKiom1PsHjGQkiSHAANSduDCqzA741.jpg

程序:

HSize=30,SSize=32:比例为2.89

wKioL1PsH1ajkWCPAAD2CngYBuM212.jpg

wKioL1PsH-HicEM1AAD6K6o39cU437.jpg

wKiom1PsHkqR9zWCAAEIAGhAo08051.jpg


HSize=20,SSize=20:比例为2.88

wKioL1PsH27SFCYjAAD9sD9DcdQ933.jpg

wKioL1PsH3my3MBqAADQnpPz308121.jpg


HSize=50,SSize=50:比例为2.87

wKiom1PsHnGA8u8SAAEHOrNbjkA891.jpg

wKiom1PsHn2Asfe5AADUjTz1qq4981.jpg


代码:

#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <iostream>
CvHistogram* histogram(IplImage* src,int HSize,int SSize) //返回归一化的histogram
{
IplImage* SrcH=cvCreateImage(cvGetSize(src),8,1);
IplImage* SrcS=cvCreateImage(cvGetSize(src),8,1);
//分割HSV
cvSplit(src,SrcH,SrcS,NULL,NULL);
//创建histogram
CvHistogram* hist;
int dims=2;
int size[]={HSize,SSize};
float RangeH[]={0,180};
float RangeS[]={0,360};
float* ranges[]={RangeH,RangeS};
hist=cvCreateHist(dims,size,CV_HIST_ARRAY,ranges);
//计算histogram
IplImage* image[]={SrcH,SrcS};
cvCalcHist(image,hist);
//归一化histogram
cvNormalizeHist(hist,1.0);  //所有值加起来为1
return hist;
}
CvMat* CreateSignature(CvHistogram* hist,int HSize,int SSize)  //由histogram得到signature
{
int rows=HSize*SSize;
CvMat* mat=cvCreateMat(rows,3,CV_32FC1); //第一列为结果,第二列为histogram中该结果的行号,第三列为列号
for(int rows=0;rows<HSize;rows++)
{
for(int cols=0;cols<SSize;cols++)
{
float data=cvQueryHistValue_2D(hist,rows,cols);
cvSet2D(mat,rows*SSize+cols,0,cvScalar(data));
cvSet2D(mat,rows*SSize+cols,1,cvScalar(rows));
cvSet2D(mat,rows*SSize+cols,2,cvScalar(cols));
}
}
return mat;
}
int CalcEMD2(int argc,char** argv)  //EMD:earth mover's distance 陆基移动距离
{
IplImage* src1=cvLoadImage("e:\\picture\\4.jpg");
IplImage* src2=cvLoadImage("e:\\picture\\11.jpg");
int HSize=30;
int SSize=32;
CvHistogram* hist1=histogram(src1,HSize,SSize);
CvHistogram* hist2=histogram(src2,HSize,SSize);
CvMat* mat1=CreateSignature(hist1,HSize,SSize);
CvMat* mat2=CreateSignature(hist2,HSize,SSize);
//计算陆基移动距离
float EMD2Result=cvCalcEMD2(mat1,mat2,CV_DIST_L2);
std::cout<<"0 is best"<<std::endl;
std::cout<<"EMD2Result:"<<EMD2Result<<std::endl;
cvNamedWindow("src1");
cvNamedWindow("src2");
cvShowImage("src1",src1);
cvShowImage("src2",src2);
cvWaitKey(0);
cvDestroyWindow("src1");
cvDestroyWindow("src2");
cvReleaseImage(&src1);
cvReleaseImage(&src2);
return 0;
}