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