float cvCalcEMD( const float* signature1, int size1, const float* signature2, int size2, int dims, int dist_type, CvDistanceFunction dist_func, float* lower_bound, void* user_param) { CvMat sign1 = cvMat( size1, dims + 1, CV_32FC1, (void*)signature1 ); CvMat sign2 = cvMat( size2, dims + 1, CV_32FC1, (void*)signature2 ); return cvCalcEMD2( &sign1, &sign2, dist_type, dist_func, 0, 0, lower_bound, user_param ); }
float Histogram::calcEMD2(const Histogram* histogram1, const Histogram* histogram2, int distanceType) { Signature* signature1 = histogram1->signature(); Signature* signature2 = histogram2->signature(); float emd2 = cvCalcEMD2(signature1, signature2, distanceType); cvRelease(&signature1); cvRelease(&signature2); return emd2; }
float emd_float(float *sig1, int len1, float *sig2, int len2, float *costmat) { CvMat *s1=cvCreateMatHeader(len1,1,CV_32F), *s2=cvCreateMatHeader(len2,1,CV_32F), *c =cvCreateMatHeader(len1,len2,CV_32F); s1->data.fl=sig1; s2->data.fl=sig2; c->data.fl=costmat; float lb=1; float ret=cvCalcEMD2(s1,s2,CV_DIST_USER,NULL,c,NULL,NULL,NULL); cvReleaseMat(&s1); cvReleaseMat(&s2); cvReleaseMat(&c); return ret; }
float cv::EMD( InputArray _signature1, InputArray _signature2, int distType, InputArray _cost, float* lowerBound, OutputArray _flow ) { Mat signature1 = _signature1.getMat(), signature2 = _signature2.getMat(); Mat cost = _cost.getMat(), flow; CvMat _csignature1 = signature1; CvMat _csignature2 = signature2; CvMat _ccost = cost, _cflow; if( _flow.needed() ) { _flow.create(signature1.rows, signature2.rows, CV_32F); flow = _flow.getMat(); _cflow = flow; } return cvCalcEMD2( &_csignature1, &_csignature2, distType, 0, cost.empty() ? 0 : &_ccost, _flow.needed() ? &_cflow : 0, lowerBound, 0 ); }
CvMat* sig2 = cvCreateMat(n, 3, CV_32FC1); foreach_idx(i, h1) { int row = i/histogram_cycle; int col = i%histogram_cycle; cvSet2D(sig1, i, 0, cvScalar(h1[i])); cvSet2D(sig1, i, 1, cvScalar(row)); cvSet2D(sig1, i, 2, cvScalar(col)); cvSet2D(sig2, i, 0, cvScalar(h2[i])); cvSet2D(sig2, i, 1, cvScalar(row)); cvSet2D(sig2, i, 2, cvScalar(col)); } double dist = cvCalcEMD2(sig1, sig2, CV_DIST_L2, 0, 0, 0, 0, 0); cvReleaseMat(&sig1); cvReleaseMat(&sig2); return dist; } double emd_distance(const std::vector<double>& h1, const std::vector<double>& h2, int histogram_cycle) { int n = h1.size(); ntk_assert((n%histogram_cycle)==0, "Not a multiple of cycle !!"); int n_cycle = n/histogram_cycle; double global_dist = 0; for (int c = 0; c < n_cycle; ++c)
// 利用EMD来度量两分布之间的相似性 // Do EMD and REPORT int emd_compare(CvMat* sig1,CvMat* sig2){ float emd = cvCalcEMD2(sig1, sig2, CV_DIST_L2); printf("%f;", emd); return 0; }