
#ifndef __MDETECTEUR__
#define __MDETECTEUR__

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <string.h> // memcpy, memset
#include <math.h> // sqrt

#include "MUtils.h"
#include "MCharImage.h"
#include "MFloatImage.h"
#include "MShortImage.h"
#include "MSignedShortImage.h"
#include "MListePI.h"

//Detecteur de points d'interet
class MDetecteur {
protected:
  MFloatImage* ImgCritere;

public:
  MDetecteur() {ImgCritere=0;}
  MDetecteur(int x,int y) {SetSize(x,y);}
  void SetSize(int x,int y) {ImgCritere=new MFloatImage(x,y);}
  virtual ~MDetecteur() {if (ImgCritere!=0) delete ImgCritere;}
  //Creation d'une liste de points d'interet contenant au plus NbMax elements (les meilleurs)
  //a partir de l'image fournie
  //Si NbMax=-1, alors tous les points detectes sont conserves
  virtual int Detecte(MCharImage& Image,MListePI& ListePI,int NbMax=-1)=0;

  //A partir de l'image ImageCritere, extraction des meileurs points d'interet
  int CreateListPI(MCharImage& Image,MListePI& ListePI,int NbMax=-1);

	//Calcule plus precisement la position d'un max local
	void Raffine(int x0,int y0,float& x,float& y);	

};

class MDetecteurHarris:public MDetecteur
{
protected:
  MSignedShortImage* ImgA;
  MSignedShortImage* ImgB;
  MSignedShortImage* ImgC;
  MSignedShortImage* ImgTempSignedShort;
  MCharImage* ImgTempChar;
  MCharImage* GradX;
  MCharImage* GradY;

  //SetSize ne doit pas etre appelé plusieurs fois
  void SetSize(int x,int y);

public:
	MDetecteurHarris();
  MDetecteurHarris(int x,int y);
  MDetecteurHarris(MCharImage& Image);
  ~MDetecteurHarris();

  //Init de doit pas etre appele plusieurs fois
  void Init(int x,int y) {MDetecteur::SetSize(x,y);SetSize(x,y);}
  
  int Detecte(MCharImage& Image,MListePI& ListePI,int NbMax=-1);
  
};


class MDetecteurMoravec:public MDetecteur
{
protected:
  MCharImage* ImgTempChar1;
  MCharImage* ImgTempChar2;

  //SetSize ne doit pas etre appelé plusieurs fois
  void SetSize(int x,int y);

public:
	MDetecteurMoravec();
  MDetecteurMoravec(int x,int y);
  MDetecteurMoravec(MCharImage& Image);
  ~MDetecteurMoravec();

  //Init de doit pas etre appele plusieurs fois
  void Init(int x,int y) {MDetecteur::SetSize(x,y);SetSize(x,y);}


  int Detecte(MCharImage& Image,MListePI& ListePI,int NbMax=-1);

};


class MDetecteurVPInf:public MDetecteur
{
protected:
  MSignedShortImage* ImgA;
  MSignedShortImage* ImgB;
  MSignedShortImage* ImgC;
  MSignedShortImage* ImgTempSignedShort;
  MCharImage* ImgTempChar;
  MCharImage* GradX;
  MCharImage* GradY;

  //SetSize ne doit pas etre appelé plusieurs fois
  void SetSize(int x,int y);

public:
	MDetecteurVPInf();
  MDetecteurVPInf(int x,int y);
  MDetecteurVPInf(MCharImage& Image);
  ~MDetecteurVPInf();

  //Init de doit pas etre appele plusieurs fois
  void Init(int x,int y) {MDetecteur::SetSize(x,y);SetSize(x,y);}

  int Detecte(MCharImage& Image,MListePI& ListePI,int NbMax=-1);
};

#endif

