/*********************************************************** 
*  --- OpenSURF ---                                        *
*  This library is distributed under the GNU GPL. Please   *
*  contact chris.evans@irisys.co.uk for more information.  *
*                                                          *
*  C. Evans, Research Into Robust Visual Features,         *
*  MSc University of Bristol, 2008.                        *
*                                                          *
************************************************************/

// This file has slightly changed for compatibility with the OpenGSURF library
// OpenGSURF
// Author: Pablo F. Alcantarilla
// Date: 11/11/2011
// Email: pablofdezalc@gmail.com

//**************************************************************************************
//**************************************************************************************

#ifndef SURFLIB_H
#define SURFLIB_H

//**************************************************************************************
//**************************************************************************************

#include "cv.h"
#include "highgui.h"
#include "integral.h"
#include "fasthessian.h"
#include "surf.h"
#include "ipoint.h"
#include "utils.h"
#include <sys/time.h>

//**************************************************************************************
//**************************************************************************************

//! Library function builds vector of described interest points
inline void surfDetDes(IplImage *img,  /* image to find Ipoints in */
                       std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */
                       unsigned char mode = 0,   /* Descriptor Mode*/
                       bool upright = false, /* run in rotation invariant mode? */
                       bool extended = false, /*128 descriptor?*/
                       int octaves = OCTAVES, /* number of octaves to calculate */
                       int intervals = INTERVALS, /* number of intervals per octave */
                       int init_sample = INIT_SAMPLE, /* initial sampling step */
                       float thres = THRES /* blob response threshold */)
{
  int dsize = 0;

  // OpenSURF and M-SURF descriptors (64,128)
  // G-SURF and SURF No Gaussian Weighting descriptors (64,128)
  if( mode == 0 || mode == 1 || mode == 4 || mode == 9 || mode == 12 )
  {
	  if( extended == false )
	  {
		  dsize = 64;
	  }
	  else
	  {
		  dsize = 128;
	  }
  }
  // G-SURF and SURF No Gaussian Weighting descriptors (16,32)
  else if( mode == 2 || mode == 7)
  {
	  if( extended == false )
	  {
		  dsize = 16;
	  }
	  else
	  {
		  dsize = 32;
	  }
  }
  // G-SURF and SURF No Gaussian Weighting descriptors (36,72)
  else if( mode == 3 || mode == 12 || mode == 8 )
  {
	  if( extended == false )
	  {
		  dsize = 36;
	  }
	  else
	  {
		  dsize = 72;
	  }
  }
  // G-SURF and SURF No Gaussian Weighting descriptors (100,200)
  else if( mode == 5 || mode == 10 )
  {
	  if( extended == false )
	  {
		  dsize = 100;
	  }
	  else
	  {
		  dsize = 200;
	  }
  }
    // G-SURF and SURF No Gaussian Weighting descriptors (144,288)
  else if( mode == 6 || mode == 11 )
  {
	  if( extended == false )
	  {
		  dsize = 144;
	  }
	  else
	  {
		  dsize = 288;
	  }
  }
  
  // Create integral-image representation of the image
  IplImage *int_img = Integral(img);
  
  // Create Fast Hessian Object
  FastHessian fh(int_img, ipts, octaves, intervals, init_sample, thres, dsize);
   
  // Extract interest points and store in vector ipts
  fh.getIpoints();
   
  // Create Surf Descriptor Object
  Surf des(int_img, ipts);

  // Extract the descriptors for the ipts
  des.getDescriptors(mode,upright,extended);

  // Deallocate the integral image
  cvReleaseImage(&int_img);
}

//**************************************************************************************
//**************************************************************************************

//! Library function builds vector of interest points
inline void surfDet(IplImage *img,  /* image to find Ipoints in */
                    std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */
                    int octaves = OCTAVES, /* number of octaves to calculate */
                    int intervals = INTERVALS, /* number of intervals per octave */
                    int init_sample = INIT_SAMPLE, /* initial sampling step */
                    float thres = THRES /* blob response threshold */)
{
  // Create integral image representation of the image
  IplImage *int_img = Integral(img);

  // Create Fast Hessian Object
  FastHessian fh(int_img, ipts, octaves, intervals, init_sample, thres);

  // Extract interest points and store in vector ipts
  fh.getIpoints();

  // Deallocate the integral image
  cvReleaseImage(&int_img);
}

//**************************************************************************************
//**************************************************************************************

//! Library function describes interest points in vector
inline void surfDes(IplImage *img,  /* image to find Ipoints in */
                    std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */
                    unsigned char mode, /* descriptors mode*/
                    bool upright = false, /* run in rotation invariant mode? */
                    bool extended = false /*128 descriptor?*/)
{ 
  // Create integral image representation of the image
  IplImage *int_img = Integral(img);

  // Create Surf Descriptor Object
  Surf des(int_img, ipts);

  // Extract the descriptors for the ipts
  des.getDescriptors(mode,upright,extended);
  
  // Deallocate the integral image
  cvReleaseImage(&int_img);
}

//**************************************************************************************
//**************************************************************************************

#endif
