#include "MUtils.h"
#include "MCharImage.h"
#include "MDetecteur.h"
#include "MListeCouples.h"
#include "MEstimeTranslation.h"

void CalculeTranslation(MCharImage& Image1,MCharImage& Image2);
int main(int argc, char** argv)
{
  MCheckCpu(); // obligatoire pour l'acceleration !
  MSetWithMmxSseUse(0);
  
  MCharImage Image1,Image2;
  if (argc!=3)
  {
    cout << "Usage : "<<argv[0]<<" image1.ppm image2.ppm" << endl;
    abort();
  }
    
  Image1.Load(argv[1]);
  Image2.Load(argv[2]);
 
  CalculeTranslation(Image1,Image2);

  return 0;
};

void CalculeTranslation(MCharImage& Image1,MCharImage& Image2)
{
  //On recupere la taille des images
  int x=Image1.x();
  int y=Image1.y();

  //On cree un detecteur de points d'interet pour chaque image et on detecte les points d'interet
  //ne pas utiliser le meme detecteur pour les 2 images, car le detecteur conserve des
  //informations dont on aura besoin au moment de l'appariement
  MDetecteurHarris Detecteur1(x,y),Detecteur2(x,y);
  //MListePI = liste de points d'interets
  MListePI ListePI1(5000),ListePI2(5000);

  Detecteur1.Detecte(Image1,ListePI1,600);
  Detecteur2.Detecte(Image2,ListePI2,600);

  //On apparie les points detectes sur chaque image
  MListeCouples ListeCouples;
  //Parametres choisis :
  // 50,50 -> deplacement maximum autorise en x et en y d'une image a l'autre (a adapter en fonction de l'algo)
  // 0.8 -> valeur minimum du score de correlation pour retenir un appariement (pas besoin d'y toucher)
 
  ListeCouples.Apparie(ListePI1,Detecteur1,ListePI2,Detecteur2,600,300,0.8);
  
  //A ce stade, il ne reste plus qu'a exploiter la liste de couples de points pour en deduire le deplacement d'une image a l'autre
  MEstimeTranslation EstimeTranslation;
  double tx,ty;
  int nb=EstimeTranslation.Estime(ListeCouples,tx,ty);

  cout << "Decalage calcule : ( " << tx << " , " << ty << " )" << "  nbPoints utilises " << nb << endl;

  MCharImage result;
  result.SetSize(Image1.x()*2,Image1.y()*2);
  cout << "res created\n";
  result.Put(Image1,Image1.x()/2,Image1.y()/2);
  cout << "res put 1\n";
  result.Put(Image2,Image1.x()/2-((int)tx)*2,Image1.y()/2-((int)ty)*2);
  cout << "res composed\n";
  result.Save("result.pgm");
}

