www.pudn.com > firev0.01.rar > idmdistancesobel.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
*/
/** Copyright notice
 * © Thomas Deselaers 
 * All right reserved
 *
 * This software may not be published and not used for any comercial
 * applications without explicit written agreement from the author
 * 
 */
#ifndef __idmdistancesobel_hpp
#define __idmdistancesobel_hpp
#include "basehisto.hpp"
#include "basefeature.hpp"
#include "diag.hpp"
#include 
#include 

class IDMDistanceSobel : public BaseDist {
public:
  IDMDistanceSobel(int warprange1=3, int warprange2=1, double threshold=-2.0) {
    warprange1_=warprange1;
    warprange2_=warprange2;
    threshold_=threshold;
    
    sobelH=vector< vector >(3,vector(3,0.0));
    sobelV=vector< vector >(3,vector(3,0.0));
    
    sobelH[0][0]=-1;     sobelV[0][0]=-1; 
    sobelH[0][1]=-2;     sobelV[1][0]=-2; 
    sobelH[0][2]=-1;     sobelV[2][0]=-1; 
    sobelH[1][0]=0;      sobelV[0][1]=0;  
    sobelH[1][1]=0;      sobelV[1][1]=0;  
    sobelH[1][2]=0;      sobelV[2][1]=0;  
    sobelH[2][0]=1;      sobelV[0][2]=1;  
    sobelH[2][1]=2;      sobelV[1][2]=2;  
    sobelH[2][2]=1;      sobelV[2][2]=1;  

    DBG(DBG_MESSAGE) << "wr1=" << warprange1_ << " wr2=" << warprange2_ << " threshold=" << threshold_ << endl;
  }
  
  virtual ~IDMDistanceSobel() {
  }

  virtual double dist(const BaseFeature *b, const BaseFeature *a) const {
    const ImageFeature *gfa=dynamic_cast(a);
    const ImageFeature *gfb=dynamic_cast(b);
    
    if(!gfa || !gfb) {
      
      const RGBImageFeature* cfa=dynamic_cast(a);
      const RGBImageFeature* cfb=dynamic_cast(b);
      
      if (!cfa || !cfb) {
        ERR << "Only Image Features can be used!" << ::std::endl;
        return 0.0;
      } else {
        RGBImage ima=cfa->img();
        RGBImage imb=cfb->img();
        
        return idm_color(ima, imb);
      }
    } else {
      BaseImage ima=gfa->img();
      BaseImage imb=gfb->img();
      
      return idm_grey(ima, imb);
    }
  };

 
  virtual double dist(const BaseFeature*, const vector&) const {
    ERR << "Not defined" << endl;
    return 0.0;
  };
  
  virtual std::string name() {
    return "idmdistsobel";
  }
  
private:
  
  double idm_color(const RGBImage & ima, const RGBImage &imb) const {
    BaseImage tmp_a, tmp_b;
    double dist=0.0;
    for(int i=0;i<3;++i) {
      tmp_a=ima.layer(i);
      tmp_b=imb.layer(i);
      
      dist+=idm_grey(tmp_a,tmp_b);
    }
    return dist;
  }
  
  
  double idm_grey(const BaseImage &inA, const BaseImage &inB) const {
    double dist=0.0;
    double tmp;
    double bestDist;

    BaseImage A=inA;
    BaseImage B=inB;
    
    for(unsigned int y=0;y sobelAv=A;    sobelAv.convolution(sobelV);
    BaseImage sobelAh=A;    sobelAh.convolution(sobelH);
    BaseImage sobelBv=B;    sobelBv.convolution(sobelV);
    BaseImage sobelBh=B;    sobelBh.convolution(sobelH);
    for(unsigned int y=0;y::max();
          for(int xx=x-warprange1_;xx<=x+warprange1_;++xx) {
            for(int yy=y-warprange1_;yy<=y+warprange1_;++yy) {
              
              if(xx >= 0 && yy >= 0 && xx < int(B.xDim()) && yy < int(B.yDim())
                 && ((tmp=pixelDist (sobelAv,sobelAh, sobelBv,sobelBh,y,x,yy,xx))::max();
          int B_x=int( double((B.xDim()-1)*x)/double(A.xDim()-1)+0.5);
          int B_y=int( double((B.yDim()-1)*y)/double(A.yDim()-1)+0.5);
          for(int xx=B_x-warprange1_;xx<=B_x+warprange1_;++xx) {
            for(int yy=B_y-warprange1_;yy<=B_y+warprange1_;++yy) {
              if(xx >= 0 && yy >= 0 && xx < int(B.xDim()) && yy < int(B.yDim())
                 && ((tmp=pixelDist (sobelAv,sobelAh, sobelBv, sobelBh,y,x,yy,xx)) &a1,const BaseImage &a2,const BaseImage &b1, const BaseImage &b2, const int ya, const int xa, const int yb, const int xb) const {
    double dist=0.0, dist1=0.0, dist2=0.0;
    double aktDist;
    int ay, ax, by, bx;
    int cnt=0;
    
    for(int i=-warprange2_;i<=warprange2_;++i) {
      for(int j=-warprange2_;j<=warprange2_;++j) {
        ay=ya+i;
        ax=xa+j;
        
        by=yb+i;
        bx=xb+j;
        
        if(ay>=0 && ay=0 && ax =0 && by=0 && bx =0 && ay=0 && ax =0 && by=0 && bx -1) {
      return MIN(threshold_,dist);
    } else {
      return dist;
    }
  }
  
  int warprange1_, warprange2_;
  double threshold_;
  ::std::vector< ::std::vector > sobelH, sobelV;
  
};
#endif