www.pudn.com > firev0.01.rar > globallocalfeaturedistance.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
*/
#ifndef __globallocalfeaturedistance_hpp
#define __globallocalfeaturedistance_hpp
/** Global Local Feature distance ... This is a Distance Function
implementation of the usual Local Feature Classification method
How is this done:
three Steps: init, actuall distance function, deinit (forget)
1 Init:
Create KD Tree
-load data from harddrive
-copy into appropriate data structure
Query the KD-Tree by all of the local features for the query image:
- count votes for each image from the database
- dist[n]=totalvotes-vote[n]
2 distance function: return dist[n]. n is here found by the filename
3 deinit:
forget some stuff, but not all, because we don't need to recreate kd-tree for every query
*/
#include
#include
#include "kann.hpp"
#include "localfeature.hpp"
class GlobalLocalFeatureDistance : public BaseDist {
public:
GlobalLocalFeatureDistance(int k=20, double eps=1.0) {
k_=20;
eps_=eps;
treeBuilt_=false;
}
virtual ~GlobalLocalFeatureDistance() {
}
virtual void distInit(const BaseFeature *queryFeat, const vector< vector *> > &database, const int distNo) {
DBG(DBG_MESSAGE) << "initing" << endl;
LocalFeatures *a=const_cast(dynamic_cast(queryFeat));
LocalFeatures *b;
queryname_=a->filename();
DBG(DBG_MESSAGE) << "initing for file "<< queryname_ << endl;
if(!treeBuilt_) {
// kann=kANN();
::std::vector< ::std::vector > traindb;
::std::vector imageNo;
DBG(DBG_MESSAGE) << "copying data step 1... and maybe loading the data" << endl;
for(unsigned int i=0;i(database[i][distNo]);
b->load();
filenames_.push_back(b->filename());
for(unsigned int f=0;fdata().size();++f) {
traindb.push_back(b->feature(f));
imageNo.push_back(i);
}
}
DBG(DBG_MESSAGE) << "copying data step 2" << endl;
kann.putTraindata(traindb, imageNo);
DBG(DBG_MESSAGE) << "building tree" << endl;
kann.buildTree();
treeBuilt_=true;
}
votes_=::std::vector(database.size());
dists_=::std::vector(database.size());
vector qr;
int total_votes=0;
DBG(DBG_VERBOSE) << "querying" << endl;
for(unsigned int f=0;fdata().size();++f) {
qr=kann.query(a->feature(f), k_, eps_);
for(unsigned int i=0;i *a, const BaseFeature *b) const {
const LocalFeatures *lfa=dynamic_cast(a);
const LocalFeatures *lfb=dynamic_cast(b);
double result=9999999999.0;
if(lfb->filename() != queryname_) {
ERR << "Cannot give this. Queryname: '"<< queryname_ << "' != actual query: '" << lfb->filename() <<"'." << endl;
} else {
for(unsigned int i=0;ifilename()) {
result=dists_[i];
}
}
}
return result;
}
virtual double dist(const BaseFeature*, const vector&) const {
ERR << "Not defined!" << endl;
return -1.0;
}
virtual std::string name() {
return "globallocalfeaturedistance";
}
virtual void distForget() {
votes_.clear();
dists_.clear();
// filenames_.clear();
queryname_="";
}
private:
::std::string queryname_;
::std::vector< ::std::string > filenames_;
::std::vector votes_;
::std::vector dists_;
int k_;
double eps_;
bool treeBuilt_;
kANN kann;
};
#endif