和基于HSV的陆基移动距离相对比,这个为三维直方图
程序:
结论:
和基于HSV的路基距离相比,效果没有HSV好
代码:
#include "cv.h" #include "cxcore.h" #include "highgui.h" #include <iostream> CvHistogram* histogram(IplImage* src,int BSize,int GSize,int RSize) //返回归一化的histogram { IplImage* SrcB=cvCreateImage(cvGetSize(src),8,1); IplImage* SrcG=cvCreateImage(cvGetSize(src),8,1); IplImage* SrcR=cvCreateImage(cvGetSize(src),8,1); //分割HSV cvSplit(src,SrcB,SrcG,SrcR,NULL); //创建histogram CvHistogram* hist; int dims=3; int size[]={BSize,GSize,RSize}; float RangeB[]={0,255}; float RangeG[]={0,255}; float RangeR[]={0,255}; float* ranges[]={RangeB,RangeG,RangeR}; hist=cvCreateHist(dims,size,CV_HIST_ARRAY,ranges); //计算histogram IplImage* image[]={SrcB,SrcG,SrcR}; cvCalcHist(image,hist); //归一化histogram cvNormalizeHist(hist,1.0); return hist; } CvMat* CreateSignature(CvHistogram* hist,int BSize,int GSize,int RSize) //由histogram得到signature { int rows=BSize*GSize*RSize; CvMat* mat=cvCreateMat(rows,4,CV_32FC1); //第一列为结果,第二列为histogram中该结果的行号,第三列为列号 for(int z=0;z<BSize;z++) { for(int y=0;y<GSize;y++) { for(int x=0;x<RSize;x++) { float data=cvQueryHistValue_3D(hist,z,y,x); //std::cout<<data<<std::endl; cvSet2D(mat,z*(GSize*RSize)+y*RSize+x,0,cvScalar(data)); cvSet2D(mat,z*(GSize*RSize)+y*RSize+x,1,cvScalar(z)); cvSet2D(mat,z*(GSize*RSize)+y*RSize+x,2,cvScalar(y)); cvSet2D(mat,z*(GSize*RSize)+y*RSize+x,3,cvScalar(x)); } } } return mat; } int CalcEMD2BaseOnBGR(int argc,char** argv) { IplImage* src1=cvLoadImage("e:\\picture\\4.jpg"); IplImage* src2=cvLoadImage("e:\\picture\\11.jpg"); int BSize=20; //理论上,cvCalcEMD2能计算的最大直方图签名的行数为15440,及20*20*20<15440,所以不能用30,30,30 int GSize=20; int RSize=20; CvHistogram* hist1=histogram(src1,BSize,GSize,RSize); CvHistogram* hist2=histogram(src2,BSize,GSize,RSize); CvMat* mat1=CreateSignature(hist1,BSize,GSize,RSize); CvMat* mat2=CreateSignature(hist2,BSize,GSize,RSize); //float max=0; // float min=0; //cvGetMinMaxHistValue(hist2,&min,&max); //std::cout<<"hist1"<<min<<" "<<max<<std::endl; //double Max=0; //double Min=0; //cvMinMaxLoc(mat2,&Min,&Max); //std::cout<<"mat1"<<Min<<" "<<Max<<std::endl; //计算陆基移动距离 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; }