www.pudn.com > firev0.01.rar > emdistance.hpp
/* This file is part of the FIRE -- Flexible Image Retrieval System FIRE is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. FIRE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FIRE; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /** * @file emdistance.hpp * @author Thomas Deselaers * @date Mon Jun 23 19:02:56 2003 * * @brief Earth movers distance as subclass of basedist. * * This is an encapsulation of the earth movers distance implemented * by yassi rubner. */ #ifndef __emdistance_hpp #define __emdistance_hpp #include#include "basedist.hpp" #include "mdhistogram.hpp" #include "histogram.hpp" #include "colorpixel.hpp" typedef vector * feature_t; #ifdef __HAVE_EMD__ #include "emd.h" #endif inline float emdbasedist(feature_t *F1, feature_t *F2) { double dX=0.0; double tmp; for(unsigned int i=0;i<(*F1)->size();++i) { tmp=(*F1)->operator[](i)-(*F2)->operator[](i); dX+=tmp*tmp; } return (float)sqrt(dX); } class EMDistance : public BaseDist { public: EMDistance() {}; virtual double dist(const BaseFeature *a, const BaseFeature *b) const { #ifdef __HAVE_EMD__ signature_t *s1=(signature_t*) malloc(1*sizeof(signature_t)); signature_t *s2=(signature_t*) malloc(1*sizeof(signature_t)); s1->n=a->size(); s2->n=b->size(); s1->Features=(feature_t*)malloc(s1->n*sizeof(feature_t)); s2->Features=(feature_t*)malloc(s2->n*sizeof(feature_t)); s1->Weights=(float *) malloc(s1->n*sizeof(float)); s2->Weights=(float *) malloc(s2->n*sizeof(float)); if(dynamic_cast >* >(a)) { const ::img::MDHistogram< ::img::ColorPixel > *mdha=dynamic_cast >* >(a); const ::img::MDHistogram< ::img::ColorPixel > *mdhb=dynamic_cast >* >(b); if(!mdha) ERR << "[EMDistance::dist()] !mdha" << endl; if(!mdhb) ERR << "[EMDistance::dist()] !mdhb" << endl; for(unsigned int i=0;i nOfBins();++i) { int dim=mdha->dim(); feature_t v=new vector (dim); s1->Features[i]=v; for(unsigned int k=0;k dim();++k) { s1->Features[i]->operator[](k)=mdha->value(i)[k]; } s1->Weights[i]=mdha->operator[](i); } for(unsigned int i=0;i nOfBins();++i) { int dim=mdhb->dim(); feature_t v=new vector (dim); s2->Features[i]=v; for(unsigned int k=0;k dim();++k) { s2->Features[i]->operator[](k)=mdhb->value(i)[k]; } s2->Weights[i]=mdhb->operator[](i); } } else if(dynamic_cast< const ::img::Histogram * >(a)) { const ::img::Histogram *ha=dynamic_cast * >(a); const ::img::Histogram *hb=dynamic_cast * >(b); if(!ha) ERR << "[EMDistance::dist()] !ha" << endl; if(!hb) ERR << "[EMDistance::dist()] !hb" << endl; for(unsigned int i=0;i nOfBins();++i) { int dim=1; feature_t v=new vector (dim); s1->Features[i]=v; s1->Features[i]->operator[](0)=ha->value(i); s1->Weights[i]=ha->operator[](i); } for(unsigned int i=0;i nOfBins();++i) { int dim=1; feature_t v=new vector (dim); s2->Features[i]=v; s2->Features[i]->operator[](0)=hb->value(i); s2->Weights[i]=hb->operator[](i); } } else { ERR << "[EMDistance::dist()] Not MDHistogram, not Histogram, don't know what to do." << endl; } double result=emd(s1,s2,emdbasedist,0,0); //freeing memory for(int i=0;i n;++i) { delete (s1->Features[i]); } free(s1->Features); free(s1->Weights); for(int i=0;i n;++i) { delete (s2->Features[i]); } free(s2->Features); free(s2->Weights); //returning return result; #else ERR << "Need EMD implementation to use this" << endl; exit(20); #endif } virtual double dist(const BaseFeature *, const vector &) const { return 0; } virtual std::string name() { return "emd"; } private: }; #endif