程序:
HSize=30,SSize=32:比例为2.89
HSize=20,SSize=20:比例为2.88
HSize=50,SSize=50:比例为2.87
代码:
#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; }