和基于HSV的陆基移动距离相对比,这个为三维直方图

程序:

wKiom1PsHTDzNBGWAAD5S93HnKc168.jpg

wKioL1PsHl2zMXFdAAD-4zaH0xw167.jpg

wKioL1PsHm2wNc02AAEVYPg_nnQ641.jpg

结论:

和基于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* p_w_picpath[]={SrcB,SrcG,SrcR};
cvCalcHist(p_w_picpath,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;
}