Browse Source

aïe aïe aïe

Rémi Synave 4 years ago
commit
490613f376
100 changed files with 27320 additions and 0 deletions
  1. 2 0
      README.md
  2. 2243 0
      classeImage/Image.cpp
  3. 158 0
      classeImage/Image.hpp
  4. 165 0
      classeImage/Makefile
  5. 110 0
      classeImage/Pixel.cpp
  6. 43 0
      classeImage/Pixel.hpp
  7. 3 0
      hdrvdp/AUTHORS
  8. 674 0
      hdrvdp/COPYING
  9. 86 0
      hdrvdp/ChangeLog
  10. 365 0
      hdrvdp/INSTALL
  11. BIN
      hdrvdp/ImageMagick-6.9.10-12.zip
  12. 2 0
      hdrvdp/Makefile.am
  13. 663 0
      hdrvdp/Makefile.in
  14. 1 0
      hdrvdp/NEWS
  15. 142 0
      hdrvdp/README
  16. 5 0
      hdrvdp/TODO
  17. 1107 0
      hdrvdp/aclocal.m4
  18. 5588 0
      hdrvdp/configure
  19. 81 0
      hdrvdp/configure.ac
  20. 630 0
      hdrvdp/depcomp
  21. 12 0
      hdrvdp/distort/Makefile.am
  22. 518 0
      hdrvdp/distort/Makefile.in
  23. 158 0
      hdrvdp/distort/pfsblur.cpp
  24. 17 0
      hdrvdp/distort/pfscontour
  25. 21 0
      hdrvdp/distort/pfsnoise
  26. 39 0
      hdrvdp/distort/pfsoctavelum
  27. 27 0
      hdrvdp/distort/pfssinnoise
  28. 520 0
      hdrvdp/install-sh
  29. 21 0
      hdrvdp/instructionInstallation
  30. 376 0
      hdrvdp/missing
  31. BIN
      hdrvdp/pfstools-1.9.1.tar.gz
  32. 155 0
      hdrvdp/src/CSF.cpp
  33. 50 0
      hdrvdp/src/CSF.h
  34. 21 0
      hdrvdp/src/Makefile.am
  35. 614 0
      hdrvdp/src/Makefile.in
  36. 115 0
      hdrvdp/src/array2d_algorithm.cpp
  37. 48 0
      hdrvdp/src/array2d_algorithm.h
  38. 467 0
      hdrvdp/src/cortex_transform.cpp
  39. 71 0
      hdrvdp/src/cortex_transform.h
  40. 233 0
      hdrvdp/src/csf_filter.cpp
  41. 127 0
      hdrvdp/src/csf_filter.h
  42. 1639 0
      hdrvdp/src/csf_psi_mapping.h
  43. 76 0
      hdrvdp/src/csf_psi_nonlinearity.cpp
  44. 36 0
      hdrvdp/src/csf_psi_nonlinearity.h
  45. 155 0
      hdrvdp/src/dump_image_aspect.cpp
  46. 60 0
      hdrvdp/src/dump_image_aspect.h
  47. 233 0
      hdrvdp/src/fftutils.cpp
  48. 102 0
      hdrvdp/src/fftutils.h
  49. 138 0
      hdrvdp/src/fftw_array2d.h
  50. 72 0
      hdrvdp/src/nonlinearity.cpp
  51. 79 0
      hdrvdp/src/nonlinearity.h
  52. 732 0
      hdrvdp/src/otf.cpp
  53. 132 0
      hdrvdp/src/otf.h
  54. 108 0
      hdrvdp/src/vdp.1
  55. 123 0
      hdrvdp/src/vdp.in
  56. 206 0
      hdrvdp/src/vdpcmp.1
  57. 494 0
      hdrvdp/src/vdpcmp.cpp
  58. 41 0
      hdrvdp/src/vdpvis.1
  59. 359 0
      hdrvdp/src/vdpvis.cpp
  60. 2070 0
      libSVM-3.20/FAQ.html
  61. 25 0
      libSVM-3.20/Makefile
  62. 33 0
      libSVM-3.20/Makefile.win
  63. 771 0
      libSVM-3.20/README
  64. 65 0
      libSVM-3.20/experimentationsTheseTram/NormaliseN.java
  65. 96 0
      libSVM-3.20/experimentationsTheseTram/NormaliseNE.java
  66. 57 0
      libSVM-3.20/experimentationsTheseTram/apprentissage.sh
  67. 336 0
      libSVM-3.20/experimentationsTheseTram/extractionDonnees_sous_partie.sh
  68. 336 0
      libSVM-3.20/experimentationsTheseTram/extractionDonnees_toutes_scenes.sh
  69. 371 0
      libSVM-3.20/experimentationsTheseTram/extractionDonnees_une_scene.sh
  70. 89 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise
  71. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_Appart1opt02.output
  72. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_Bureau1.output
  73. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_Cendrier.output
  74. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_Cuisine01.output
  75. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_EchecsBas.output
  76. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_PNDVuePlongeante.output
  77. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_SdbCentre.output
  78. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_SdbDroite.output
  79. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_Selles.output
  80. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_echecs_pnd_sdbCentre.output
  81. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_non_normalise_app_toutes-scenes.output
  82. 89 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise
  83. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_Appart1opt02.output
  84. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_Bureau1.output
  85. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_Cendrier.output
  86. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_Cuisine01.output
  87. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_EchecsBas.output
  88. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_PNDVuePlongeante.output
  89. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_SdbCentre.output
  90. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_SdbDroite.output
  91. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_Selles.output
  92. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_echecs_pnd_sdbCentre.output
  93. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_app_toutes-scenes.output
  94. 89 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_ensemble
  95. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_ensemble_app_Appart1opt02.output
  96. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_ensemble_app_Bureau1.output
  97. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_ensemble_app_Cendrier.output
  98. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_ensemble_app_Cuisine01.output
  99. 90 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_ensemble_app_EchecsBas.output
  100. 0 0
      libSVM-3.20/experimentationsTheseTram/fichiersSVD/Appart1opt02/zone00/Appart1opt02_100-103_normalise_ensemble_app_PNDVuePlongeante.output

+ 2 - 0
README.md

@@ -0,0 +1,2 @@
+TODO
+Ajouter le code pour la classe Image, le hdrvdp et tenter de le faire fonctionner et la biliothèque libSVM

+ 2243 - 0
classeImage/Image.cpp

@@ -0,0 +1,2243 @@
+#include "Image.hpp"
+
+
+Lisic::Image::Image(const unsigned int& tailleX, const unsigned int& tailleY, const unsigned int& profondeurCouleur)
+{
+  assert(tailleX!=0);
+  assert(tailleY!=0);
+  _profondeurCouleur=profondeurCouleur;
+  _tailleX=tailleX;
+  _tailleY=tailleY;
+
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    _pixels.push_back(Lisic::Pixel());
+
+  normaliserA255();
+}
+
+
+Lisic::Image::Image(const unsigned int& tailleX, const unsigned int& tailleY, const unsigned int& profondeurCouleur, std::vector<unsigned int> canal1, std::vector<unsigned int> canal2, std::vector<unsigned int> canal3)
+{
+  assert(tailleX!=0);
+  assert(tailleY!=0);
+  _profondeurCouleur=profondeurCouleur;
+  _tailleX=tailleX;
+  _tailleY=tailleY;
+  
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    _pixels.push_back(Lisic::Pixel(canal1[i],canal2[i],canal3[i]));
+
+  normaliserA255();
+}
+
+//imagemagick V6
+#ifdef IM6
+Lisic::Image::Image(const char *chemin)
+{
+  _profondeurCouleur = (1<<QuantumDepth) - 1;
+  Magick::Image magickimg(chemin);
+  
+  _tailleX=magickimg.columns();
+  _tailleY=magickimg.rows();
+  
+  for(unsigned int j = 0; j < magickimg.rows(); j++ )
+    {
+      const Magick::PixelPacket *magickpixels = magickimg.getConstPixels( 0, j, magickimg.columns(), 1 );
+
+      
+      for(unsigned int i = 0; i < magickimg.columns(); i++ ){
+	//std::cout << magickpixels[i].red << " " << magickpixels[i].green <<" " << magickpixels[i].blue << std::endl;
+	_pixels.push_back(Lisic::Pixel(magickpixels[i].red,magickpixels[i].green,magickpixels[i].blue));
+      }
+    }
+
+  normaliserA255();
+}
+#endif
+
+//Imagemagick V7
+#ifdef IM7
+Lisic::Image::Image(const char *chemin)
+{
+  Magick::Image magickimg(chemin);
+  _profondeurCouleur=(1<<magickimg.depth()) - 1;
+  
+  _tailleX=magickimg.columns();
+  _tailleY=magickimg.rows();
+  
+  for(unsigned int j = 0; j < magickimg.rows(); j++ )
+    for(unsigned int i = 0; i < magickimg.columns(); i++ ){ 
+      const MagickCore::Quantum *magickpixels = magickimg.getConstPixels( i, j, 1, 1 );
+      MagickCore::PixelInfo packet;
+      MagickCore::GetPixelInfoPixel(magickimg.constImage(),magickpixels,&packet);
+      //std::cout << packet.red << " " << packet.green <<" " << packet.blue << std::endl;
+      _pixels.push_back(Lisic::Pixel(packet.red, packet.green, packet.blue));
+      //std::cout << _pixels[_pixels.size()-1][0] << std::endl;
+      //std::cout << "(" << i  << "," << j << ") : (" << packet.red << "," << packet.green << "," << packet.blue << ")" << std::endl << std::endl;
+    }
+  
+  // On va tester la valeur de tous les pixels pour voir si une valeur dépasse 255
+  // donc image qui n'est pas en 8bits
+  // dans ce cas, on va diviser par 257 (257=65535/255)
+  bool diviser=false;
+  for(unsigned int i = 0; i < _pixels.size() ; i++){
+    if(_pixels[i][0]>255){
+      diviser=true;
+      i=_pixels.size();
+    }
+  }
+  if(diviser){
+    for(unsigned int i = 0; i < _pixels.size() ; i++){
+      _pixels[i][0]/=257;_pixels[i][1]/=257;_pixels[i][2]/=257;
+    }
+  }
+
+  //std::cout << "profondeur couleur : " << _profondeurCouleur << std::endl;
+
+  _profondeurCouleur=255;
+  
+  normaliserA255();
+}
+#endif
+
+Lisic::Image::Image(const Lisic::Image& im1, const unsigned int& numeroCanal1, const Lisic::Image& im2, const unsigned int& numeroCanal2, const Lisic::Image& im3, const unsigned int& numeroCanal3)
+{
+  assert(im1._tailleX==im2._tailleX && im1._tailleX==im3._tailleX &&
+	 im1._tailleY==im2._tailleY && im1._tailleY==im3._tailleY &&
+	 im2._tailleX==im3._tailleX && im2._tailleY==im3._tailleY &&
+	 im1._profondeurCouleur==im2._profondeurCouleur && im2._profondeurCouleur==im3._profondeurCouleur);
+  
+  std::vector<unsigned int> can1=im1.extraireCanal(numeroCanal1);
+  std::vector<unsigned int> can2=im2.extraireCanal(numeroCanal2);
+  std::vector<unsigned int> can3=im3.extraireCanal(numeroCanal3);
+  
+  _profondeurCouleur=im1._profondeurCouleur;
+  _tailleX=im1._tailleX;
+  _tailleY=im1._tailleY;
+  
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    _pixels.push_back(Lisic::Pixel(can1[i],can2[i],can3[i]));
+
+  normaliserA255();
+}
+
+Lisic::Image::Image(const std::vector<Lisic::Image>& vec, const unsigned int& x, const unsigned int& y)
+{
+  assert(vec.size()==x*y);
+  
+  /*Vérifier que les tailles d'images sont bien compatibles pour assemblage*/
+  for(unsigned int i=0;i<x;i++)
+    for(unsigned int j=1;j<y;j++)
+      assert(vec[i]._tailleX==vec[j*x+i]._tailleX);
+  
+  for(unsigned int j=0;j<y;j++)
+    for(unsigned int i=1;i<x;i++)
+      assert(vec[j*x]._tailleY==vec[j*x+i]._tailleY);	
+
+  /*Vérifier que les profondeurCouleur soient bien les mêmes partout*/
+  for(unsigned int i=1;i<x*y;i++)
+    assert(vec[i]._profondeurCouleur==vec[0]._profondeurCouleur);
+  
+  /*retrouver la taille finale de l'image*/
+  std::vector<unsigned int> tab_taillex,tab_tailley;
+  _tailleX=0;
+  _tailleY=0;
+  _profondeurCouleur=vec[0]._profondeurCouleur;
+
+  for(unsigned int i=0;i<x;i++)
+    {
+      tab_taillex.push_back(_tailleX);
+      _tailleX+=vec[i]._tailleX;
+    }
+  for(unsigned int j=0;j<y;j++)
+    {
+      tab_tailley.push_back(_tailleY);
+      _tailleY+=vec[j*x]._tailleY;
+    }
+
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    _pixels.push_back(Lisic::Pixel());
+
+  for(unsigned int j=0;j<y;j++)
+    for(unsigned int i=0;i<x;i++)
+      for(unsigned int jj=0;jj<vec[j*x+i]._tailleY;jj++)
+	for(unsigned int ii=0;ii<vec[j*x+i]._tailleX;ii++)
+	  setPixel(tab_taillex[i]+ii,tab_tailley[j]+jj,vec[j*x+i]._pixels[jj*vec[j*x+i]._tailleX+ii][0],vec[j*x+i]._pixels[jj*vec[j*x+i]._tailleX+ii][1],vec[j*x+i]._pixels[jj*vec[j*x+i]._tailleX+ii][2]);
+
+  normaliserA255();
+}
+
+Lisic::Image::Image(const Lisic::Image& im)
+{
+  _profondeurCouleur=im._profondeurCouleur;
+  _tailleX=im._tailleX;
+  _tailleY=im._tailleY;
+  
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    _pixels.push_back(Lisic::Pixel(im._pixels[i]));
+}
+
+void Lisic::Image::normaliserA255()
+{
+  assert(_profondeurCouleur==255 || _profondeurCouleur==65535);
+  if(_profondeurCouleur==65535){
+    for(unsigned int i=0;i<_pixels.size();i++){
+      _pixels[i].r()/=257;
+      _pixels[i].v()/=257;
+      _pixels[i].b()/=257;
+    }
+  }
+  _profondeurCouleur=255;
+}
+
+//Imagemagick V6
+#ifdef IM6
+void Lisic::Image::sauver(const char *chemin) const
+{ 
+  Magick::Image magickimg(Magick::Geometry(_tailleX,_tailleY), "white");
+  magickimg.modifyImage();
+  Magick::Pixels view(magickimg);
+  Magick::PixelPacket *magickpixels=view.get(0,0,_tailleX,_tailleY);
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      *magickpixels++=Magick::ColorRGB(((_pixels[j*_tailleX+i][0])*1.0)/(_profondeurCouleur*1.0),
+				       ((_pixels[j*_tailleX+i][1])*1.0)/(_profondeurCouleur*1.0),
+				       ((_pixels[j*_tailleX+i][2])*1.0)/(_profondeurCouleur*1.0));
+  
+  view.sync();
+  
+  magickimg.write(chemin);
+}
+#endif
+
+//Imagemagick V7
+#ifdef IM7
+void Lisic::Image::sauver(const char *chemin) const
+{ 
+  Magick::Image magickimg(Magick::Geometry(_tailleX,_tailleY), "white");
+  magickimg.modifyImage();
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++){
+      MagickCore::Quantum *magickpixels = magickimg.getPixels( i, j, 1, 1 );
+      MagickCore::SetPixelRed(magickimg.constImage(),MagickCore::Quantum(_pixels[j*_tailleX+i][0]),magickpixels);
+      MagickCore::SetPixelGreen(magickimg.constImage(),MagickCore::Quantum(_pixels[j*_tailleX+i][1]),magickpixels);
+      MagickCore::SetPixelBlue(magickimg.constImage(),MagickCore::Quantum(_pixels[j*_tailleX+i][2]),magickpixels);
+    }
+  
+  magickimg.write(chemin);
+}
+#endif
+
+void Lisic::Image::sauver(const std::string chemin) const
+{
+  sauver(chemin.c_str());
+}
+
+void Lisic::Image::sauverSVG(const char *chemin) const
+{ 
+  std::cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl << std::endl;
+  std::cout << "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"" << _tailleX <<"\" height=\"" << _tailleY << "\">" << std::endl << std::endl;
+
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      std::cout << "<rect x=\"" << i << "\" y=\"" << j << "\" width=\"1\" height=\"1\" style=\"fill:rgb(" << (int)((_pixels[j*_tailleX+i][0]*1.0)/(_profondeurCouleur)*255.0) << "," << (int)((_pixels[j*_tailleX+i][1]*1.0)/(_profondeurCouleur)*255.0) << "," << (int)((_pixels[j*_tailleX+i][2]*1.0)/(_profondeurCouleur)*255.0) << ")\" />" << std::endl;
+  
+  std::cout << "</svg>" << std::endl;
+}
+
+void Lisic::Image::sauverSVG(const std::string chemin) const
+{
+  sauverSVG(chemin.c_str());
+}
+
+Lisic::Image Lisic::Image::getSousPartie(const unsigned int& imin, const unsigned int& jmin, const unsigned int& tailleXSousPartie, const unsigned int& tailleYSousPartie) const
+{
+  assert(imin+tailleXSousPartie<=_tailleX);
+  assert(jmin+tailleYSousPartie<=_tailleY);
+
+  Lisic::Image retour=Lisic::Image(tailleXSousPartie,tailleYSousPartie,_profondeurCouleur);
+  for(unsigned int j=jmin;j<jmin+tailleYSousPartie;j++)
+    for(unsigned int i=imin;i<imin+tailleXSousPartie;i++)
+      retour.setPixel(i-imin,j-jmin,_pixels[j*_tailleX+i][0],_pixels[j*_tailleX+i][1],_pixels[j*_tailleX+i][2]);
+			       
+  return retour;
+}
+
+//retourne un nouveau pixel de même couleur que le pixel demandé
+Lisic::Pixel Lisic::Image::getPixel(const unsigned int& i, const unsigned int& j) const
+{
+  assert(i<_tailleX && j<_tailleY);
+  return Lisic::Pixel((((_pixels[j*_tailleX+i][0])*1.0)/_profondeurCouleur)*255.0,(((_pixels[j*_tailleX+i][1])*1.0)/_profondeurCouleur)*255.0,(((_pixels[j*_tailleX+i][2])*1.0)/_profondeurCouleur)*255.0);
+}
+
+void Lisic::Image::setPixel(const unsigned int& i, const unsigned int& j, const unsigned int& r, const unsigned int& v, const unsigned int& b)
+{
+  assert(i<_tailleX && j<_tailleY);
+  
+  _pixels[j*_tailleX+i][0]=r;
+  _pixels[j*_tailleX+i][1]=v;
+  _pixels[j*_tailleX+i][2]=b;
+  if(_pixels[j*_tailleX+i][0]>_profondeurCouleur)
+    _pixels[j*_tailleX+i][0]=_profondeurCouleur;
+  if(_pixels[j*_tailleX+i][1]>_profondeurCouleur)
+    _pixels[j*_tailleX+i][1]=_profondeurCouleur;
+  if(_pixels[j*_tailleX+i][2]>_profondeurCouleur)
+    _pixels[j*_tailleX+i][2]=_profondeurCouleur;
+}
+
+std::vector<unsigned int> Lisic::Image::extraireCanal(const unsigned int& numeroCanal) const
+{
+  assert(numeroCanal<=2);
+  std::vector<unsigned int> canal;
+  
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    canal.push_back(_pixels[i][numeroCanal]);
+  
+  return canal;
+}
+
+bool Lisic::Image::estNoire() const
+{
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    if(_pixels[i][0]!=0 || _pixels[i][0]!=0 || _pixels[i][0]!=0)
+      return false;
+  return true;
+}
+
+bool Lisic::Image::estBlanche() const
+{
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    if(_pixels[i][0]!=_profondeurCouleur || _pixels[i][0]!=_profondeurCouleur || _pixels[i][0]!=_profondeurCouleur)
+      return false;
+  return true;
+}
+
+bool Lisic::Image::estNiveauGris() const
+{
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    if(_pixels[i][0]!=_pixels[i][1] || _pixels[i][0]!=_pixels[i][2])
+      return false;
+  return true;
+}
+
+unsigned int Lisic::Image::nombreDePixel(const unsigned int& r, const unsigned int& v, const unsigned int& b) const
+{
+  unsigned int retour=0;
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    if(_pixels[i][0]==r && _pixels[i][1]==v && _pixels[i][2]==b)
+      retour++;
+  return retour;
+}
+
+
+void Lisic::Image::affiche() const
+{
+  std::cout << "Taille : " << _tailleX << "x" << _tailleY << " pixels" << std::endl;
+  for(unsigned int j=0;j<_tailleY;j++)
+    {
+      for (unsigned int i=0; i<_tailleX; i++)
+	std::cout << "(" << _pixels[j*_tailleX+i][0] << "," << _pixels[j*_tailleX+i][1] << "," << _pixels[j*_tailleX+i][2] << ") ";
+      std::cout << std::endl;
+    }
+}
+
+std::vector<Lisic::Image> Lisic::Image::morceler(const unsigned int& nvtailleX, const unsigned int& nvtailleY, const bool& force) const
+{
+  std::vector<Lisic::Image> retour;
+  unsigned int i,j;
+
+  if((_tailleX%nvtailleX!=0 || _tailleY%nvtailleY!=0) && !force)
+    return retour;
+  
+  for(j=0;j<_tailleY/nvtailleY;j++)
+    {
+      for(i=0;i<_tailleX/nvtailleX;i++)
+	retour.push_back(getSousPartie(i*nvtailleX,j*nvtailleY,nvtailleX,nvtailleY));
+      
+      //morceaux qui vont un peu moins bien - bande de droite
+      if(_tailleX%nvtailleX)
+	retour.push_back(getSousPartie((_tailleX/nvtailleX)*nvtailleX,j*nvtailleY,_tailleX%nvtailleX,nvtailleY));
+    }
+
+
+  if(_tailleY%nvtailleY)
+    {
+      //morceaux du bas
+      //morceaux en bas à gauche
+      for(i=0;i<_tailleX/nvtailleX;i++)
+	retour.push_back(getSousPartie(i*nvtailleX,(_tailleY/nvtailleY)*nvtailleY,nvtailleX,_tailleY%nvtailleY));
+      
+      //dernier morceau en bas à droite avec ce qu'il reste de l'image
+      if(_tailleX%nvtailleX)
+	retour.push_back(getSousPartie((_tailleX/nvtailleX)*nvtailleX,(_tailleY/nvtailleY)*nvtailleY,_tailleX%nvtailleX,_tailleY%nvtailleY));
+    }
+  
+  return retour;
+}
+
+Lisic::Image Lisic::Image::gradient(const std::vector<int>& mask) const
+{
+  assert(mask.size()==9);
+  
+  Lisic::Image grad(_tailleX-2,_tailleY-2,_profondeurCouleur);
+
+  for(unsigned int j=1;j<_tailleY-1;j++)
+    for(unsigned int i=1;i<_tailleX-1;i++)
+      {
+	unsigned int gradient1, gradient2, gradient3;
+	int res=getPixel(i-1,j-1)[0]*mask[0]+getPixel(i,j-1)[0]*mask[1]+getPixel(i+1,j-1)[0]*mask[2]+getPixel(i-1,j)[0]*mask[3]+getPixel(i,j)[0]*mask[4]+getPixel(i+1,j)[0]*mask[5]+getPixel(i-1,j+1)[0]*mask[6]+getPixel(i,j+1)[0]*mask[7]+getPixel(i+1,j+1)[0]*mask[8];
+	if(res<0)
+	  res*=-1;
+	gradient1=(unsigned int)(res);
+	  
+	res=getPixel(i-1,j-1)[1]*mask[0]+getPixel(i,j-1)[1]*mask[1]+getPixel(i+1,j-1)[1]*mask[2]+getPixel(i-1,j)[1]*mask[3]+getPixel(i,j)[1]*mask[4]+getPixel(i+1,j)[1]*mask[5]+getPixel(i-1,j+1)[1]*mask[6]+getPixel(i,j+1)[1]*mask[7]+getPixel(i+1,j+1)[1]*mask[8];
+	if(res<0)
+	  res*=-1;
+	gradient2=(unsigned int)(res);
+
+	res=getPixel(i-1,j-1)[2]*mask[0]+getPixel(i,j-1)[2]*mask[1]+getPixel(i+1,j-1)[2]*mask[2]+getPixel(i-1,j)[2]*mask[3]+getPixel(i,j)[2]*mask[4]+getPixel(i+1,j)[2]*mask[5]+getPixel(i-1,j+1)[2]*mask[6]+getPixel(i,j+1)[2]*mask[7]+getPixel(i+1,j+1)[2]*mask[8];
+	if(res<0)
+	  res*=-1;
+	gradient3=(unsigned int)(res);
+
+	grad.setPixel(i-1,j-1,gradient1,gradient1,gradient1);
+	if(gradient2>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient2,gradient2,gradient2);
+	if(gradient3>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient3,gradient3,gradient3);
+      }
+
+  return grad;
+}
+
+Lisic::Image Lisic::Image::gradientRotation(const std::vector<int>& mask) const
+{
+  assert(mask.size()==9);
+  
+  Lisic::Image grad(_tailleX-2,_tailleY-2,_profondeurCouleur);
+
+  for(unsigned int j=1;j<_tailleY-1;j++)
+    for(unsigned int i=1;i<_tailleX-1;i++)
+      {
+	unsigned int gradient1, gradient2, gradient3, gradient4, gradient5, gradient6, gradient7, gradient8, gradient9;
+	int res=getPixel(i-1,j-1)[0]*mask[0]+getPixel(i,j-1)[0]*mask[1]+getPixel(i+1,j-1)[0]*mask[2]+getPixel(i-1,j)[0]*mask[3]+getPixel(i,j)[0]*mask[4]+getPixel(i+1,j)[0]*mask[5]+getPixel(i-1,j+1)[0]*mask[6]+getPixel(i,j+1)[0]*mask[7]+getPixel(i+1,j+1)[0]*mask[8];
+	if(res<0)
+	  res*=-1;
+	gradient1=(unsigned int)(res);
+
+	res=getPixel(i-1,j-1)[1]*mask[0]+getPixel(i,j-1)[1]*mask[1]+getPixel(i+1,j-1)[1]*mask[2]+getPixel(i-1,j)[1]*mask[3]+getPixel(i,j)[1]*mask[4]+getPixel(i+1,j)[1]*mask[5]+getPixel(i-1,j+1)[1]*mask[6]+getPixel(i,j+1)[1]*mask[7]+getPixel(i+1,j+1)[1]*mask[8];
+	if(res<0)
+	  res*=-1;
+	gradient2=(unsigned int)(res);
+	
+	res=getPixel(i-1,j-1)[2]*mask[0]+getPixel(i,j-1)[2]*mask[1]+getPixel(i+1,j-1)[2]*mask[2]+getPixel(i-1,j)[2]*mask[3]+getPixel(i,j)[2]*mask[4]+getPixel(i+1,j)[2]*mask[5]+getPixel(i-1,j+1)[2]*mask[6]+getPixel(i,j+1)[2]*mask[7]+getPixel(i+1,j+1)[2]*mask[8];
+	if(res<0)
+	  res*=-1;
+	gradient3=(unsigned int)(res);
+
+	res=getPixel(i-1,j-1)[0]*mask[3]+getPixel(i,j-1)[0]*mask[0]+getPixel(i+1,j-1)[0]*mask[1]+getPixel(i-1,j)[0]*mask[6]+getPixel(i,j)[0]*mask[4]+getPixel(i+1,j)[0]*mask[2]+getPixel(i-1,j+1)[0]*mask[7]+getPixel(i,j+1)[0]*mask[8]+getPixel(i+1,j+1)[0]*mask[5];
+	if(res<0)
+	  res*=-1;
+	gradient4=(unsigned int)(res);
+
+	res=getPixel(i-1,j-1)[1]*mask[3]+getPixel(i,j-1)[1]*mask[0]+getPixel(i+1,j-1)[1]*mask[1]+getPixel(i-1,j)[1]*mask[6]+getPixel(i,j)[1]*mask[4]+getPixel(i+1,j)[1]*mask[2]+getPixel(i-1,j+1)[1]*mask[7]+getPixel(i,j+1)[1]*mask[8]+getPixel(i+1,j+1)[1]*mask[5];
+	if(res<0)
+	  res*=-1;
+	gradient5=(unsigned int)(res);
+
+	res=getPixel(i-1,j-1)[2]*mask[3]+getPixel(i,j-1)[2]*mask[0]+getPixel(i+1,j-1)[2]*mask[1]+getPixel(i-1,j)[2]*mask[6]+getPixel(i,j)[2]*mask[4]+getPixel(i+1,j)[2]*mask[2]+getPixel(i-1,j+1)[2]*mask[7]+getPixel(i,j+1)[2]*mask[8]+getPixel(i+1,j+1)[2]*mask[5];
+	if(res<0)
+	  res*=-1;
+	gradient6=(unsigned int)(res);
+
+	res=getPixel(i-1,j-1)[0]*mask[6]+getPixel(i,j-1)[0]*mask[3]+getPixel(i+1,j-1)[0]*mask[0]+getPixel(i-1,j)[0]*mask[7]+getPixel(i,j)[0]*mask[4]+getPixel(i+1,j)[0]*mask[1]+getPixel(i-1,j+1)[0]*mask[8]+getPixel(i,j+1)[0]*mask[5]+getPixel(i+1,j+1)[0]*mask[2];
+	if(res<0)
+	  res*=-1;
+	gradient7=(unsigned int)(res);
+
+	res=getPixel(i-1,j-1)[1]*mask[6]+getPixel(i,j-1)[1]*mask[3]+getPixel(i+1,j-1)[1]*mask[0]+getPixel(i-1,j)[1]*mask[7]+getPixel(i,j)[1]*mask[4]+getPixel(i+1,j)[1]*mask[1]+getPixel(i-1,j+1)[1]*mask[8]+getPixel(i,j+1)[1]*mask[5]+getPixel(i+1,j+1)[1]*mask[2];
+	if(res<0)
+	  res*=-1;
+	gradient8=(unsigned int)(res);
+
+	res=getPixel(i-1,j-1)[2]*mask[6]+getPixel(i,j-1)[2]*mask[3]+getPixel(i+1,j-1)[2]*mask[0]+getPixel(i-1,j)[2]*mask[7]+getPixel(i,j)[2]*mask[4]+getPixel(i+1,j)[2]*mask[1]+getPixel(i-1,j+1)[2]*mask[8]+getPixel(i,j+1)[2]*mask[5]+getPixel(i+1,j+1)[2]*mask[2];
+	if(res<0)
+	  res*=-1;
+	gradient9=(unsigned int)(res);
+
+	grad.setPixel(i-1,j-1,gradient1,gradient1,gradient1);
+	if(gradient2>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient2,gradient2,gradient2);
+	if(gradient3>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient3,gradient3,gradient3);
+	if(gradient4>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient4,gradient4,gradient4);
+	if(gradient5>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient5,gradient5,gradient5);
+	if(gradient6>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient6,gradient6,gradient6);
+	if(gradient7>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient7,gradient7,gradient7);
+	if(gradient8>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient8,gradient8,gradient8);
+	if(gradient9>grad.getPixel(i-1,j-1)[0])
+	  grad.setPixel(i-1,j-1,gradient9,gradient9,gradient9);
+
+      }
+
+  return grad;
+}
+
+void Lisic::Image::seuil(const unsigned int& numCanal, const unsigned int& s)
+{
+  assert(numCanal<3);
+  for(unsigned int i=0;i<_pixels.size();i++)
+    if(_pixels[i][numCanal]<s)
+      _pixels[i][numCanal]=0;
+    else
+      _pixels[i][numCanal]=_profondeurCouleur;
+}
+
+double Lisic::Image::PSNR(const Image& im, const unsigned int& numCanal) const
+{
+  assert(numCanal<3);
+  assert(im._tailleX==_tailleY && im._tailleY==_tailleY && im._profondeurCouleur==_profondeurCouleur);
+  double eqm=0;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    eqm+=(_pixels[i][numCanal]-im._pixels[i][numCanal])*(_pixels[i][numCanal]-im._pixels[i][numCanal]);
+  eqm/=_pixels.size();
+  return (10.0*log10(_profondeurCouleur*_profondeurCouleur/eqm));
+}
+
+std::tuple<double, double, double> Lisic::Image::PSNR(const Image& im) const
+{
+  assert(im._tailleX==_tailleY && im._tailleY==_tailleY && im._profondeurCouleur==_profondeurCouleur);
+  return std::make_tuple(PSNR(im,0),PSNR(im,1),PSNR(im,2));
+}
+
+std::tuple<fftw_complex*, Lisic::Image, Lisic::Image> Lisic::Image::fourier() const
+{
+  /* assert(_tailleX%2==0 && _tailleY%2==0);
+  Lisic::Image img1(_tailleX,_tailleY,_profondeurCouleur);
+  Lisic::Image img2(_tailleX,_tailleY,_profondeurCouleur);
+
+  double *listModule = new double[_tailleX*_tailleY];
+  double *listPhase = new double[_tailleX*_tailleY];
+
+  double module, phase, moduleMax=0.0;
+  
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	double partieReel=0, partieImaginaire=0;
+	for(unsigned int jImg=0;jImg<_tailleY;jImg++)
+	  for(unsigned int iImg=0;iImg<_tailleX;iImg++)
+	    {
+	      partieReel+=getPixel(iImg,jImg)[0]*cos(-2*M_PI*((i*iImg*1.0)/_tailleX+(j*jImg*1.0)/_tailleY));
+	      partieImaginaire+=getPixel(iImg,jImg)[0]*sin(-2*M_PI*((i*iImg*1.0)/_tailleX+(j*jImg*1.0)/_tailleY));
+	    }
+	
+	module = sqrt(partieReel*partieReel+partieImaginaire*partieImaginaire);
+	if(module > moduleMax && (i>10 && i<_tailleX-10 && j>10 && j<_tailleY-10))
+	  moduleMax=module;
+	phase = (atan2(partieImaginaire,partieReel)+M_PI)/7.0*_profondeurCouleur;
+ 
+	listModule[j*_tailleX+i]=module;
+	listPhase[j*_tailleX+i]=phase;
+      }
+  
+
+
+  if(moduleMax==0)
+    moduleMax=1;
+
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	img1.setPixel(i,j,(unsigned int)(listModule[j*_tailleX+i]/moduleMax*_profondeurCouleur),(unsigned int)(listModule[j*_tailleX+i]/moduleMax*_profondeurCouleur),(unsigned int)(listModule[j*_tailleX+i]/moduleMax*_profondeurCouleur));
+	img2.setPixel(i,j,(unsigned int)(listPhase[j*_tailleX+i]),(unsigned int)(listPhase[j*_tailleX+i]),(unsigned int)(listPhase[j*_tailleX+i]));
+      }
+
+  delete[] listModule;
+  delete[] listPhase;
+
+  for(unsigned int j=0;j<_tailleY/2;j++)
+    for(unsigned int i=0;i<_tailleX/2;i++)
+      {
+	unsigned int echang=img1.getPixel(i,j)[0];
+	img1.setPixel(i,j,img1.getPixel(i+_tailleX/2,j+_tailleY/2)[0],img1.getPixel(i+_tailleX/2,j+_tailleY/2)[0],img1.getPixel(i+_tailleX/2,j+_tailleY/2)[0]);
+	img1.setPixel(i+_tailleX/2,j+_tailleY/2,echang,echang,echang);
+      }
+
+  for(unsigned int j=0;j<_tailleY/2;j++)
+    for(unsigned int i=_tailleX/2;i<_tailleX;i++)
+      {
+	unsigned int echang=img1.getPixel(i,j)[0];
+	img1.setPixel(i,j,img1.getPixel(i-_tailleX/2,j+_tailleY/2)[0],img1.getPixel(i-_tailleX/2,j+_tailleY/2)[0],img1.getPixel(i-_tailleX/2,j+_tailleY/2)[0]);
+	img1.setPixel(i-_tailleX/2,j+_tailleY/2,echang,echang,echang);
+      }
+
+      return std::make_pair(img1,img2);*/
+
+  fftw_complex* spatial_repr;
+  fftw_complex* frequency_repr;
+  fftw_plan plan;
+  unsigned int x,y;
+  std::vector<float> imOut;
+  imOut.resize(_tailleX*_tailleY);
+  std::vector<float> reOut;
+  reOut.resize(_tailleX*_tailleY);
+  std::vector<float> listeModule;
+  listeModule.resize(_tailleX*_tailleY);
+  std::vector<float> listePhase;
+  listePhase.resize(_tailleX*_tailleY);
+  float moduleMax=0;
+  
+  spatial_repr= (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*_tailleX*_tailleY);
+  frequency_repr= (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*_tailleX*_tailleY);
+  
+  /*On remplit la structure qui sera utilisée par fftw*/
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	spatial_repr[j*_tailleX+i][0] = getPixel(i,j)[0];
+	spatial_repr[j*_tailleX+i][1] =  0.0f;
+    }
+  
+  /*on calcule le plan d'exécution*/
+  plan=fftw_plan_dft_2d(_tailleY, _tailleX, spatial_repr, frequency_repr, FFTW_FORWARD, FFTW_ESTIMATE);
+  
+  /*on effectue la transformée de Fourier*/
+  fftw_execute(plan);
+
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	/*on recentre l'image*/
+	x=i;
+	y=j;
+	if (i<_tailleX/2 && j<_tailleY/2){ x=i+_tailleX/2; y=j+_tailleY/2; }
+	if (i>=_tailleX/2 && j<_tailleY/2){ x=i-_tailleX/2; y=j+_tailleY/2; }
+	if (i<_tailleX/2 && j>=_tailleY/2){ x=i+_tailleX/2; y=j-_tailleY/2; }
+	if (i>=_tailleX/2 && j>=_tailleY/2){ x=i-_tailleX/2; y=j-_tailleY/2; }
+	reOut[y*_tailleX+x]=frequency_repr[j*_tailleX+i][0];
+	imOut[y*_tailleX+x]=frequency_repr[j*_tailleX+i][1];
+	listeModule[y*_tailleX+x]=sqrt(reOut[y*_tailleX+x]*reOut[y*_tailleX+x]+imOut[y*_tailleX+x]*imOut[y*_tailleX+x]);
+	listePhase[y*_tailleX+x]=((atan2(imOut[y*_tailleX+x],reOut[y*_tailleX+x]))+M_PI)/(2*M_PI)*_profondeurCouleur;
+	//std::cout << "(" << i << "," << j << ") : " << listePhase[y*_tailleX+x] << std::endl;
+	if(listeModule[y*_tailleX+x]>moduleMax && i>_tailleX/20 && i<_tailleX*0.8 && j>_tailleY/20 && j<_tailleY*0.8)
+	  moduleMax=listeModule[y*_tailleX+x];
+      }
+
+  
+  Lisic::Image img1(_tailleX,_tailleY,_profondeurCouleur);
+  Lisic::Image img2(_tailleX,_tailleY,_profondeurCouleur);
+
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+    {
+      listeModule[j*_tailleX+i]=listeModule[j*_tailleX+i]/moduleMax*_profondeurCouleur;
+      img1.setPixel(i,j,listeModule[j*_tailleX+i],listeModule[j*_tailleX+i],listeModule[j*_tailleX+i]);
+      img2.setPixel(i,j,listePhase[j*_tailleX+i],listePhase[j*_tailleX+i],listePhase[j*_tailleX+i]);
+    }
+  
+  /*on détruit les objets*/
+  fftw_destroy_plan(plan);
+  fftw_free(spatial_repr);
+
+  return std::make_tuple(frequency_repr,img1,img2);
+  
+}
+
+double Lisic::Image::genereAleatoireUniforme(int precision){
+  int puiss=1;
+  for(int i=0;i<precision;i++)
+    puiss*=10;
+  
+  return ((rand()%puiss)*1.0)/puiss;
+}
+
+void Lisic::Image::bruitUniforme(const double& force, const int& type, const bool& verbeux)
+{
+  assert(type==Lisic::Image::GLOBAL || type==Lisic::Image::PARCANAL);
+  struct timespec ts_start;
+  clock_gettime(CLOCK_MONOTONIC, &ts_start);
+  long temps=ts_start.tv_nsec;
+  srand(temps);
+
+  int nvr,nvv,nvb;
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	if(type==Lisic::Image::GLOBAL){
+	  double alea=(genereAleatoireUniforme()-0.5)*0.2*force;
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+alea*_profondeurCouleur/255.0;
+	  nvv=v+alea*_profondeurCouleur/255.0;
+	  nvb=b+alea*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << alea << " " << alea << " " << alea << std::endl;
+	}
+	else{
+	  double alea1=(genereAleatoireUniforme()-0.5)*0.2*force;
+	  double alea2=(genereAleatoireUniforme()-0.5)*0.2*force;
+	  double alea3=(genereAleatoireUniforme()-0.5)*0.2*force;
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+alea1*_profondeurCouleur/255.0;
+	  nvv=v+alea2*_profondeurCouleur/255.0;
+	  nvb=b+alea3*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << alea1 << " " << alea2 << " " << alea3 << std::endl;
+	}
+	if(nvr<0)
+	  nvr=0;
+	if(nvv<0)
+	  nvv=0;
+	if(nvb<0)
+	  nvb=0; 
+	if((unsigned int)nvr>_profondeurCouleur)
+	  nvr=_profondeurCouleur;
+	if((unsigned int)nvv>_profondeurCouleur)
+	  nvv=_profondeurCouleur;
+	if((unsigned int)nvb>_profondeurCouleur)
+	  nvb=_profondeurCouleur;
+	setPixel(i,j,nvr,nvv,nvb);
+      }
+}
+
+std::pair<double,double> Lisic::Image::genereAleatoireGaussien(){
+  //d'après https://www.unilim.fr/pages_perso/jean.debord/math/random/random.htm#III
+  /*double x1=(((rand()%1000)*1.0+1.0)/1001.0); //x1 doit etre different de 0 car on fait un log dessus juste apres
+    double x2=(((rand()%1000)*1.0)/1000.0);
+    double v1=sqrt(-2*log(x1))*cos(2*M_PI*x2);
+    double v2=sqrt(-2*log(x1))*sin(2*M_PI*x2);
+    return std::make_pair(v1,v2);
+  */
+
+  /*D'après the art of computer programming section 3.4.1 sousection C - algorithm P*/
+  double s;
+  double u1,u2,v1=0,v2=0;
+  while(v2<1e-6 && v2>-1e-6){
+    s=1.1;
+    v2=0;
+    while(s>=1.0 || (s<1e-6 && s>-1e-6)){
+      u1=genereAleatoireUniforme();
+      u2=genereAleatoireUniforme();
+      u1=u1*2-1;      
+      u2=u2*2-1;
+      s=u1*u1+u2*u2;
+    }
+      v1=u1*sqrt(-2*log(s)/s);
+      v2=u2*sqrt(-2*log(s)/s);
+  }
+  return std::make_pair(v1,v2);
+}
+
+void Lisic::Image::bruitGaussien(const double& force, const int& type, const bool& verbeux)
+{
+  assert(type==Lisic::Image::GLOBAL || type==Lisic::Image::PARCANAL);
+  
+  struct timespec ts_start;
+  clock_gettime(CLOCK_MONOTONIC, &ts_start);
+  long temps=ts_start.tv_nsec;
+  srand(temps);
+
+  int nvr,nvv,nvb;
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	if(type==Lisic::Image::GLOBAL){
+	  double aleaGaussien=genereAleatoireGaussien().first*force;
+
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+aleaGaussien*_profondeurCouleur/255.0;
+	  nvv=v+aleaGaussien*_profondeurCouleur/255.0;
+	  nvb=b+aleaGaussien*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << aleaGaussien << " " << aleaGaussien << " " << aleaGaussien << std::endl;
+	}
+	else{
+	  double aleaGaussien1=genereAleatoireGaussien().first*0.1*force;
+	  double aleaGaussien2=genereAleatoireGaussien().first*0.1*force;
+	  double aleaGaussien3=genereAleatoireGaussien().first*0.1*force;
+	  
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+aleaGaussien1*_profondeurCouleur/255.0;
+	  nvv=v+aleaGaussien2*_profondeurCouleur/255.0;
+	  nvb=b+aleaGaussien3*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << aleaGaussien1 << " " << aleaGaussien2 << " " << aleaGaussien3 << std::endl;
+	}
+	if(nvr<0)
+	  nvr=0;
+	if(nvv<0)
+	  nvv=0;
+	if(nvb<0)
+	  nvb=0;
+	if((unsigned int)nvr>_profondeurCouleur)
+	  nvr=_profondeurCouleur;
+	if((unsigned int)nvv>_profondeurCouleur)
+	  nvv=_profondeurCouleur;
+	if((unsigned int)nvb>_profondeurCouleur)
+	  nvb=_profondeurCouleur;
+	setPixel(i,j,nvr,nvv,nvb);
+      }
+}
+
+void Lisic::Image::bruitPoivreSel(const double& force, const double& proportion, const int& type, const bool& verbeux)
+{
+  assert(type==Lisic::Image::GLOBAL || type==Lisic::Image::PARCANAL);
+  std::vector<unsigned int> aModif;
+
+
+  struct timespec ts_start;
+  clock_gettime(CLOCK_MONOTONIC, &ts_start);
+  long temps=ts_start.tv_nsec;
+  srand(temps);
+  
+  //Calcul des pixels à modifier
+  if(proportion>0.5){
+    for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+      aModif.push_back(i);
+    for(unsigned int i=0;i<(unsigned int)(_tailleX*_tailleY*(1-proportion));i++)
+      aModif.erase(aModif.begin()+(rand()%(_tailleX*_tailleY-i)));
+  }
+  else{
+    for(unsigned int i=0;i<(unsigned int)(_tailleX*_tailleY*proportion);i++){
+      unsigned int alea=rand()%(_tailleX*_tailleY);
+      bool trouve=false;
+      for(unsigned int j=0;j<aModif.size();j++){
+	if(aModif[j]==alea)
+	  trouve=true;
+      }
+      if(!trouve)
+	aModif.push_back(alea);
+      else
+	i--;
+      
+    }
+  }
+
+  int nvr,nvv,nvb;
+
+    for(unsigned int i=0;i<aModif.size();i++){
+      int coeff=1.0;
+      if(rand()%2)
+	coeff=-1.0;
+      unsigned int x=aModif[i]%_tailleX,y=aModif[i]/_tailleX;
+      double bruit=coeff*0.5*force;
+      if(type==Lisic::Image::GLOBAL){
+	int r=getPixel(x,y).r();
+	int v=getPixel(x,y).v();
+	int b=getPixel(x,y).b();
+	nvr=(int)(r+bruit*_profondeurCouleur/255.0);
+	nvv=(int)(v+bruit*_profondeurCouleur/255.0);
+	nvb=(int)(b+bruit*_profondeurCouleur/255.0);
+	if(verbeux)
+	    std::cout << x << " " << y << " " << bruit << " " << bruit << " " << bruit << std::endl;
+      }
+      else{
+	int r=getPixel(x,y).r();
+	int v=getPixel(x,y).v();
+	int b=getPixel(x,y).b();
+	nvr=r;nvv=v;nvb=b;
+	
+	int alea=(rand()%7);
+	switch(alea){
+	case 0 :
+	  nvb=(int)(b+bruit*_profondeurCouleur/255.0);
+	  if(verbeux)
+	    std::cout << x << " " << y << " 0 0 " << bruit << std::endl;
+	  break;
+	case 1:
+	  nvv=(int)(v+bruit*_profondeurCouleur/255.0);
+	  if(verbeux)
+	    std::cout << x << " " << y << " 0 " << bruit << " 0" << std::endl;
+	  break;
+	case 2:
+	  nvv=(int)(v+bruit*_profondeurCouleur/255.0);
+	  nvb=(int)(b+bruit*_profondeurCouleur/255.0);
+	  if(verbeux)
+	    std::cout << x << " " << y << " 0 " << bruit << " " << bruit << std::endl;
+	  break;
+	case 3:
+	  nvr=(int)(r+bruit*_profondeurCouleur/255.0);
+	  if(verbeux)
+	    std::cout << x << " " << y << " " << bruit << " 0 0" << std::endl;
+	  break;
+	case 4:
+	  nvr=(int)(r+bruit*_profondeurCouleur/255.0);
+	  nvb=(int)(b+bruit*_profondeurCouleur/255.0);
+	  if(verbeux)
+	    std::cout << x << " " << y << " " << bruit << " 0 " << bruit << std::endl;
+	  break;
+	case 5:
+	  nvr=(int)(r+bruit*_profondeurCouleur/255.0);
+	  nvv=(int)(v+bruit*_profondeurCouleur/255.0);
+	  if(verbeux)
+	    std::cout << x << " " << y << " " << bruit << " " << bruit << " 0" << std::endl;
+	  break;
+	default :
+	  nvr=(int)(r+bruit*_profondeurCouleur/255.0);
+	  nvv=(int)(v+bruit*_profondeurCouleur/255.0);
+	  nvb=(int)(b+bruit*_profondeurCouleur/255.0);
+	  if(verbeux)
+	    std::cout << x << " " << y << " " << bruit << " " << bruit << " " << bruit << std::endl;
+	}
+      }
+      if(nvr<0)
+	nvr=0;
+      if(nvv<0)
+	nvv=0;
+      if(nvb<0)
+	nvb=0;
+      if((unsigned int)nvr>_profondeurCouleur)
+	nvr=_profondeurCouleur;
+      if((unsigned int)nvv>_profondeurCouleur)
+	nvv=_profondeurCouleur;
+      if((unsigned int)nvb>_profondeurCouleur)
+	nvb=_profondeurCouleur;
+      setPixel(x,y,nvr,nvv,nvb);
+    }
+}
+
+double Lisic::Image::genereAleatoireCauchy(){
+  std::pair<double,double> p=genereAleatoireGaussien();
+  return (p.first/p.second);
+}
+
+void Lisic::Image::bruitCauchyLorentz(const double& force, const int& type, const bool& verbeux)
+{
+  /*assert(type==Lisic::Image::GLOBAL || type==Lisic::Image::PARCANAL);
+  struct timespec ts_start;
+  clock_gettime(CLOCK_MONOTONIC, &ts_start);
+  long temps=ts_start.tv_nsec;
+  srand(temps);
+
+  double min=0;
+  double max=0;
+  int nb=0;
+  
+  for(int i=0;i<10000000;i++){
+
+    double s;
+    double u1,u2,v1=0,v2=0;
+    while(v2<1e-6 && v2>-1e-6){
+      s=1.1;
+      v2=0;
+      while(s>=1.0 || (s<1e-6 && s>-1e-6)){
+	u1=((rand()%1000)*1.0)/1000.0;
+	u1=u1*2-1;
+	u2=((rand()%1000)*1.0)/1000.0;
+	u2=u2*2-1;
+	s=u1*u1+u2*u2;
+      }
+      v1=u1*sqrt(-2*log(s)/s);
+      v2=u2*sqrt(-2*log(s)/s);
+    }
+      
+    double aleaCauchy=v1/v2;
+    
+    if(aleaCauchy>max)
+      max=aleaCauchy;
+    if(aleaCauchy<min)
+      min=aleaCauchy;
+    //std::cout << aleaCauchy << " ";
+    if(aleaCauchy<4)
+      nb++;
+  }
+  std::cout << std::endl << "min,max : " << min << ";" << max << std::endl;
+  std::cout << (nb*1.0)/10000000.0 << " - " << atan(4)/M_PI+0.5 << std::endl;*/
+
+
+
+  assert(type==Lisic::Image::GLOBAL || type==Lisic::Image::PARCANAL);
+  
+  struct timespec ts_start;
+  clock_gettime(CLOCK_MONOTONIC, &ts_start);
+  long temps=ts_start.tv_nsec;
+  srand(temps);
+
+  int nvr,nvv,nvb;
+
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	if(type==Lisic::Image::GLOBAL){ 
+	  double aleaCauchy=genereAleatoireCauchy()*0.0002*force;
+	  
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+aleaCauchy*_profondeurCouleur/255.0;
+	  nvv=v+aleaCauchy*_profondeurCouleur/255.0;
+	  nvb=b+aleaCauchy*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << aleaCauchy << " " << aleaCauchy << " " << aleaCauchy << std::endl;
+	  
+	}
+	else{
+	  double aleaCauchy1=genereAleatoireCauchy()*0.0002*force;
+	  double aleaCauchy2=genereAleatoireCauchy()*0.0002*force;
+	  double aleaCauchy3=genereAleatoireCauchy()*0.0002*force;
+	  
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+aleaCauchy1*_profondeurCouleur/255.0;
+	  nvv=v+aleaCauchy2*_profondeurCouleur/255.0;
+	  nvb=b+aleaCauchy3*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << aleaCauchy1 << " " << aleaCauchy2 << " " << aleaCauchy3 << std::endl;	   
+	}
+	if(nvr<0)
+	  nvr=0;
+	if(nvv<0)
+	  nvv=0;
+	if(nvb<0)
+	  nvb=0;
+	if((unsigned int)nvr>_profondeurCouleur)
+	  nvr=_profondeurCouleur;
+	if((unsigned int)nvv>_profondeurCouleur)
+	  nvv=_profondeurCouleur;
+	if((unsigned int)nvb>_profondeurCouleur)
+	  nvb=_profondeurCouleur;
+	setPixel(i,j,nvr,nvv,nvb);
+      }
+}
+
+double Lisic::Image::genereAleatoireLaplace(double mu, double b){
+  //D'après wikipédia http://en.wikipedia.org/wiki/Laplace_distribution
+  double alea=genereAleatoireUniforme()+0.00005-0.5;//un nombre entre -0.49995 et 0.49995 pour éviter le -infini
+  double signe=alea<0?-1.0:1.0;
+  double absAlea=alea*signe;
+  return mu-b*signe*log(1-2*absAlea);
+}
+
+void Lisic::Image::bruitLaplacien(const double& force, const int& type, const bool& verbeux)
+{
+  assert(type==Lisic::Image::GLOBAL || type==Lisic::Image::PARCANAL);
+  
+  struct timespec ts_start;
+  clock_gettime(CLOCK_MONOTONIC, &ts_start);
+  long temps=ts_start.tv_nsec;
+  srand(temps);
+  
+  int nvr,nvv,nvb;
+  
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	if(type==Lisic::Image::GLOBAL){ 
+	  double aleaLaplace=genereAleatoireLaplace()*0.1*force;
+	  
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+aleaLaplace*_profondeurCouleur/255.0;
+	  nvv=v+aleaLaplace*_profondeurCouleur/255.0;
+	  nvb=b+aleaLaplace*_profondeurCouleur/255.0; 
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << aleaLaplace << " " << aleaLaplace << " " << aleaLaplace << std::endl;
+	  
+	}
+	else{
+	  double aleaLaplace1=genereAleatoireLaplace()*0.1*force;	  
+	  double aleaLaplace2=genereAleatoireLaplace()*0.1*force;	  
+	  double aleaLaplace3=genereAleatoireLaplace()*0.1*force;
+	  
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+aleaLaplace1*_profondeurCouleur/255.0;
+	  nvv=v+aleaLaplace2*_profondeurCouleur/255.0;
+	  nvb=b+aleaLaplace3*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << aleaLaplace1 << " " << aleaLaplace2 << " " << aleaLaplace3 << std::endl;	   
+	}
+	if(nvr<0)
+	  nvr=0;
+	if(nvv<0)
+	  nvv=0;
+	if(nvb<0)
+	  nvb=0;
+	if((unsigned int)nvr>_profondeurCouleur)
+	  nvr=_profondeurCouleur;
+	if((unsigned int)nvv>_profondeurCouleur)
+	  nvv=_profondeurCouleur;
+	if((unsigned int)nvb>_profondeurCouleur)
+	  nvb=_profondeurCouleur;
+	setPixel(i,j,nvr,nvv,nvb);
+      }
+}
+
+double Lisic::Image::genereAleatoireLogNormale(){
+  //D'après wikipédia http://fr.wikipedia.org/wiki/Loi_normale#Lois_usuelles
+  double alea=genereAleatoireGaussien().first;
+  return exp(alea);
+}
+
+void Lisic::Image::bruitLogNormale(const double& force, const int& type, const bool& verbeux)
+{
+  assert(type==Lisic::Image::GLOBAL || type==Lisic::Image::PARCANAL);
+
+  struct timespec ts_start;
+  clock_gettime(CLOCK_MONOTONIC, &ts_start);
+  long temps=ts_start.tv_nsec;
+  srand(temps);
+  
+  int nvr,nvv,nvb;
+  
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	if(type==Lisic::Image::GLOBAL){ 
+	  double aleaLogNormale=genereAleatoireLogNormale()*0.05*force;
+	  
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+aleaLogNormale*_profondeurCouleur/255.0;
+	  nvv=v+aleaLogNormale*_profondeurCouleur/255.0;
+	  nvb=b+aleaLogNormale*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << aleaLogNormale << " " << aleaLogNormale << " " << aleaLogNormale << std::endl;
+	  
+	}
+	else{
+	  double aleaLogNormale1=genereAleatoireLogNormale()*0.05*force;
+	  double aleaLogNormale2=genereAleatoireLogNormale()*0.05*force;  
+	  double aleaLogNormale3=genereAleatoireLogNormale()*0.05*force;
+	  
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+aleaLogNormale1*_profondeurCouleur/255.0;
+	  nvv=v+aleaLogNormale2*_profondeurCouleur/255.0;
+	  nvb=b+aleaLogNormale3*_profondeurCouleur/255.0;
+	  if(verbeux)
+	    std::cout << i << " " << j << " " << aleaLogNormale1 << " " << aleaLogNormale2 << " " << aleaLogNormale3 << std::endl;	   
+	}
+	if(nvr<0)
+	  nvr=0;
+	if(nvv<0)
+	  nvv=0;
+	if(nvb<0)
+	  nvb=0;
+	if((unsigned int)nvr>_profondeurCouleur)
+	  nvr=_profondeurCouleur;
+	if((unsigned int)nvv>_profondeurCouleur)
+	  nvv=_profondeurCouleur;
+	if((unsigned int)nvb>_profondeurCouleur)
+	  nvb=_profondeurCouleur;
+	setPixel(i,j,nvr,nvv,nvb);
+      }
+}
+
+void Lisic::Image::bruitMultiplicatifUniforme(const double& force, const int& type, const bool& verbeux)
+{
+  assert(type==Lisic::Image::GLOBAL || type==Lisic::Image::PARCANAL);
+  struct timespec ts_start;
+  clock_gettime(CLOCK_MONOTONIC, &ts_start);
+  long temps=ts_start.tv_nsec;
+  srand(temps);
+
+  int nvr,nvv,nvb;
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	if(type==Lisic::Image::GLOBAL){
+	  double alea=(genereAleatoireUniforme()-0.5)*0.002*force;
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+r*alea;
+	  nvv=v+v*alea;
+	  nvb=b+b*alea;
+	  if(verbeux)
+	    std::cout << i << " " << j << " * * *" << std::endl;
+	}
+	else{
+	  double alea1=(genereAleatoireUniforme()-0.5)*0.002*force;
+	  double alea2=(genereAleatoireUniforme()-0.5)*0.002*force;
+	  double alea3=(genereAleatoireUniforme()-0.5)*0.002*force;
+	  int r=getPixel(i,j).r();
+	  int v=getPixel(i,j).v();
+	  int b=getPixel(i,j).b();
+	  nvr=r+r*alea1;
+	  nvv=v+v*alea2;
+	  nvb=b+b*alea3;
+	  if(verbeux)
+	    std::cout << i << " " << j << " * * *" << std::endl;
+	}
+	if(nvr<0)
+	  nvr=0;
+	if(nvv<0)
+	  nvv=0;
+	if(nvb<0)
+	  nvb=0; 
+	if((unsigned int)nvr>_profondeurCouleur)
+	  nvr=_profondeurCouleur;
+	if((unsigned int)nvv>_profondeurCouleur)
+	  nvv=_profondeurCouleur;
+	if((unsigned int)nvb>_profondeurCouleur)
+	  nvb=_profondeurCouleur;
+	setPixel(i,j,nvr,nvv,nvb);
+      }
+  std::cout << std::endl;
+}
+
+void Lisic::Image::bruitMasque(std::string chemin){
+  std::ifstream fic(chemin);
+  assert(fic.good() && fic.is_open());
+  while(!fic.eof()){
+    int x,y;
+    double br,bv,bb,nvr,nvv,nvb;
+    fic >> x >> y >> br >> bv >> bb;
+    int r=getPixel(x,y).r();
+    int v=getPixel(x,y).v();
+    int b=getPixel(x,y).b();
+    nvr=r+br*_profondeurCouleur/255.0;
+    nvv=v+bv*_profondeurCouleur/255.0;
+    nvb=b+bb*_profondeurCouleur/255.0;
+    if(nvr<0)
+      nvr=0;
+    if(nvv<0)
+      nvv=0;
+    if(nvb<0)
+      nvb=0; 
+    if((unsigned int)nvr>_profondeurCouleur)
+      nvr=_profondeurCouleur;
+    if((unsigned int)nvv>_profondeurCouleur)
+      nvv=_profondeurCouleur;
+    if((unsigned int)nvb>_profondeurCouleur)
+      nvb=_profondeurCouleur;
+    setPixel(x,y,nvr,nvv,nvb);
+  }
+}
+
+
+std::vector<double> Lisic::Image::SVD() const
+{
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++){
+      if(getPixel(i,j).r()-getPixel(i,j).v()!=0 || 
+	 getPixel(i,j).r()-getPixel(i,j).b()!=0 || 
+	 getPixel(i,j).b()-getPixel(i,j).v()!=0)
+	std::cout << "Pixel en (" << i << "," << j << ") - (" << getPixel(i,j).r() << "," << getPixel(i,j).v() << "," << getPixel(i,j).b() << ")" << std::endl;
+      assert(!(getPixel(i,j).r()-getPixel(i,j).v()!=0 || 
+	     getPixel(i,j).r()-getPixel(i,j).b()!=0 || 
+	       getPixel(i,j).b()-getPixel(i,j).v()!=0));
+    }
+  
+  Eigen::MatrixXf m(_tailleY,_tailleX);
+
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      m(j,i)=getPixel(i,j).r();
+
+  Eigen::JacobiSVD<Eigen::MatrixXf> svd(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
+  Eigen::VectorXf valeursSingulieres(svd.singularValues());
+
+  std::vector<double> v;
+  for(int i=0;i<valeursSingulieres.size();i++)
+    v.push_back(valeursSingulieres(i));
+
+  return v;
+
+}
+
+double Lisic::Image::SVD(const unsigned int& num) const
+{
+  std::vector<double> tab=SVD();
+  assert(num<tab.size());
+  return tab[num];
+}
+
+double Lisic::Image::SVD_entropy() const
+{
+  /*Voir Feature selection with SVD entropy : somes modification and extension*/
+  std::vector<double> svd=SVD();
+
+  std::vector<double> eigenValues;
+  double sommeEigenValues = 0;
+  
+  for(unsigned int i=0;i<svd.size();i++){
+    eigenValues.push_back(svd[i]*svd[i]);
+    sommeEigenValues+=svd[i]*svd[i];
+  }
+
+  std::vector<double> v;
+
+  for(unsigned int i=0;i<eigenValues.size();i++)
+    v.push_back(eigenValues[i]/sommeEigenValues);
+
+  double SVD_entropy = 0;
+
+  for(unsigned int i=0;i<eigenValues.size();i++)
+    SVD_entropy+=(v[i]*log(v[i]));
+
+  SVD_entropy*=-1;
+  //Ici, on a des matrices carrées donc on divise par eigenValues.size()
+  //De toute façon, l'étape de calcul du min entre largeur et hauteur de la matrice est faite lors du calcul du SVD
+  SVD_entropy/=log(eigenValues.size());
+
+  return SVD_entropy;
+}
+
+double Lisic::Image::SVD_entropy(std::vector<unsigned int> colonne) const
+{for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++){
+      if(getPixel(i,j).r()-getPixel(i,j).v()!=0 || 
+	 getPixel(i,j).r()-getPixel(i,j).b()!=0 || 
+	 getPixel(i,j).b()-getPixel(i,j).v()!=0)
+	std::cout << "Pixel en (" << i << "," << j << ") - (" << getPixel(i,j).r() << "," << getPixel(i,j).v() << "," << getPixel(i,j).b() << ")" << std::endl;
+      assert(!(getPixel(i,j).r()-getPixel(i,j).v()!=0 || 
+	     getPixel(i,j).r()-getPixel(i,j).b()!=0 || 
+	       getPixel(i,j).b()-getPixel(i,j).v()!=0));
+    }
+  
+  Eigen::MatrixXf m(_tailleY,_tailleX-colonne.size());
+
+  int nbDejaTrouve=0;
+  for(unsigned int i=0;i<_tailleX;i++){
+    bool aAjouter=true;
+    for(unsigned int k=0;k<colonne.size();k++)
+      if(colonne[k]==i)
+	aAjouter=false;
+    if(aAjouter){	
+      for(unsigned int j=0;j<_tailleY;j++)
+	m(j,i-nbDejaTrouve)=getPixel(i,j).r();
+    }else{
+      nbDejaTrouve++;
+    }
+  }
+
+  Eigen::JacobiSVD<Eigen::MatrixXf> temp(m, Eigen::ComputeThinU | Eigen::ComputeThinV);
+  Eigen::VectorXf valeursSingulieres(temp.singularValues());
+
+  std::vector<double> svd;
+  for(int i=0;i<valeursSingulieres.size();i++)
+    svd.push_back(valeursSingulieres(i));
+
+  std::vector<double> eigenValues;
+  double sommeEigenValues = 0;
+  
+  for(unsigned int i=0;i<svd.size();i++){
+    eigenValues.push_back(svd[i]*svd[i]);
+    sommeEigenValues+=svd[i]*svd[i];
+  }
+
+  std::vector<double> v;
+
+  for(unsigned int i=0;i<eigenValues.size();i++)
+    v.push_back(eigenValues[i]/sommeEigenValues);
+
+  double SVD_entropy = 0;
+
+  for(unsigned int i=0;i<eigenValues.size();i++)
+    SVD_entropy+=(v[i]*log(v[i]));
+
+  SVD_entropy*=-1;
+  //Ici, on a des matrices carrées donc on divise par eigenValues.size()
+  //De toute façon, l'étape de calcul du min entre largeur et hauteur de la matrice est faite lors du calcul du SVD
+  SVD_entropy/=log(eigenValues.size());
+
+  return SVD_entropy;
+ 
+}
+
+double Lisic::Image::MSE(const Image& im, const unsigned int& numCanal) const
+{
+  assert(numCanal<=2);
+  assert(_profondeurCouleur==im._profondeurCouleur);
+  assert(_tailleX==im._tailleX && _tailleY==im._tailleY);
+
+  double somme=0;
+  
+  for(unsigned int i=0;i<_tailleX;i+=1)
+    for(unsigned int j=0;j<_tailleY;j+=1)
+      {
+	double inter=((getPixel(i,j)[numCanal])*1.0)-((im.getPixel(i,j)[numCanal])*1.0);
+	somme+=inter*inter;
+      }
+	
+  return somme/(_tailleX*_tailleY);
+  
+}
+
+std::tuple<double, double, double> Lisic::Image::MSE(const Image& im) const
+{
+  assert(im._tailleX==_tailleY && im._tailleY==_tailleY && im._profondeurCouleur==_profondeurCouleur);
+  return std::make_tuple(MSE(im,0),MSE(im,1),MSE(im,2));
+}
+
+double Lisic::Image::SSIM(const Image& im, const unsigned int& numCanal) const
+{
+  assert(numCanal<=2);
+  assert(_tailleX%8==0);
+  assert(_tailleY%8==0);
+  assert(_profondeurCouleur==im._profondeurCouleur);
+  assert(_tailleX==im._tailleX && _tailleY==im._tailleY);
+
+  std::vector<double> listX;
+  listX.resize(64);
+  std::vector<double> listY;
+  listY.resize(64);
+  double somme=0;
+  
+  for(unsigned int depX=0;depX<_tailleX;depX+=8)
+    for(unsigned int depY=0;depY<_tailleY;depY+=8)
+      {
+	
+	for(unsigned int i=0;i<8;i++)
+	  for(unsigned int j=0;j<8;j++){
+	    listX[j*8+i]=((getPixel(depX+i,depY+j)[numCanal])*1.0);
+	    listY[j*8+i]=((im.getPixel(depX+i,depY+j)[numCanal])*1.0);
+	  }
+	
+	double moyX=moyenne(listX);
+	double moyY=moyenne(listY);
+	double varX=variance(listX);
+	double varY=variance(listY);
+	double covXY=covariance(listX,listY);
+	double c1=(0.01*255)*(0.01*255);
+	double c2=(0.03*255)*(0.03*255);
+	somme+=((2*moyX*moyY+c1)*(2*covXY+c2))/((moyX*moyX+moyY*moyY+c1)*(varX+varY+c2));
+      }
+  return somme/(_tailleX*_tailleY/64);
+  
+}
+
+std::tuple<double, double, double> Lisic::Image::SSIM(const Image& im) const
+{
+  assert(im._tailleX==_tailleY && im._tailleY==_tailleY && im._profondeurCouleur==_profondeurCouleur);
+  return std::make_tuple(SSIM(im,0),SSIM(im,1),SSIM(im,2));
+}
+
+double Lisic::Image::DSSIM(const Image& im, const unsigned int& numCanal) const
+{
+  assert(numCanal<=2);
+  assert(_tailleX%8==0);
+  assert(_tailleY%8==0);
+  assert(_profondeurCouleur==im._profondeurCouleur);
+  assert(_tailleX==im._tailleX && _tailleY==im._tailleY);
+
+  double ssim=SSIM(im,numCanal);
+  return (1.0-ssim)/2.0;
+}
+
+std::tuple<double, double, double> Lisic::Image::DSSIM(const Image& im) const
+{
+  assert(im._tailleX==_tailleY && im._tailleY==_tailleY && im._profondeurCouleur==_profondeurCouleur);
+  return std::make_tuple(DSSIM(im,0),DSSIM(im,1),DSSIM(im,2));
+}
+
+Lisic::Image Lisic::Image::filtre_moyenneur(const unsigned int& taille_filtre) const
+{
+  assert((taille_filtre%2)==1);
+  
+  Lisic::Image img_retour(_tailleX,_tailleY);
+  for(unsigned int i=0;i<_tailleX;i++)
+    for(unsigned int j=0;j<_tailleY;j++){
+      unsigned int aAjouter_r=0;
+      unsigned int aAjouter_v=0;
+      unsigned int aAjouter_b=0;
+      int nbValeur=0;
+      for(int i_f=(((int)(taille_filtre))/2)*-1;i_f<=((int)(taille_filtre))/2;i_f++)
+	for(int j_f=(((int)(taille_filtre))/2)*-1;j_f<=((int)(taille_filtre))/2;j_f++){
+	  if(i+i_f>=0 && i+i_f<_tailleX && j+j_f>=0 && j+j_f<_tailleY){
+	    nbValeur++;
+	    aAjouter_r+=getPixel(i+i_f,j+j_f)[0];
+	    aAjouter_v+=getPixel(i+i_f,j+j_f)[1];
+	    aAjouter_b+=getPixel(i+i_f,j+j_f)[2];
+	  }
+	}
+      
+      aAjouter_r/=nbValeur;
+      aAjouter_v/=nbValeur;
+      aAjouter_b/=nbValeur;
+
+      img_retour.setPixel(i,j,aAjouter_r,aAjouter_v,aAjouter_b);
+    }
+
+  return img_retour;
+}
+
+Lisic::Image Lisic::Image::filtre_Gaussien(const unsigned int& taille_filtre, const double& sigma) const
+{
+  assert((taille_filtre%2)==1);
+  
+  Lisic::Image img_retour(_tailleX,_tailleY);
+  for(unsigned int i=0;i<_tailleX;i++)
+    for(unsigned int j=0;j<_tailleY;j++){
+      unsigned int aAjouter_r=0;
+      unsigned int aAjouter_v=0;
+      unsigned int aAjouter_b=0;
+      int nbValeur=0;
+      double coeff,sommeCoeff=0;
+      for(int i_f=(((int)(taille_filtre))/2)*-1;i_f<=((int)(taille_filtre))/2;i_f++)
+	for(int j_f=(((int)(taille_filtre))/2)*-1;j_f<=((int)(taille_filtre))/2;j_f++){
+	  coeff=(1.0/(2*M_PI*sigma*sigma))*exp(-((i_f*i_f+j_f*j_f)/(2*sigma*sigma)));
+	  if(i+i_f>=0 && i+i_f<_tailleX && j+j_f>=0 && j+j_f<_tailleY){
+	    nbValeur++;
+	    aAjouter_r+=coeff*getPixel(i+i_f,j+j_f)[0];
+	    aAjouter_v+=coeff*getPixel(i+i_f,j+j_f)[1];
+	    aAjouter_b+=coeff*getPixel(i+i_f,j+j_f)[2];
+	    sommeCoeff+=coeff;
+	  }
+	}
+      aAjouter_r/=sommeCoeff;
+      aAjouter_v/=sommeCoeff;
+      aAjouter_b/=sommeCoeff;
+
+      img_retour.setPixel(i,j,aAjouter_r,aAjouter_v,aAjouter_b);
+    }
+
+  return img_retour;
+}
+
+Lisic::Image Lisic::Image::filtre_median(const unsigned int& taille_filtre) const
+{
+  assert((taille_filtre%2)==1);
+  
+  Lisic::Image img_retour(_tailleX,_tailleY);
+  for(unsigned int i=0;i<_tailleX;i++)
+    for(unsigned int j=0;j<_tailleY;j++){
+      std::vector<unsigned int> liste_r;
+      std::vector<unsigned int> liste_v;
+      std::vector<unsigned int> liste_b;
+      liste_r.clear();
+      liste_v.clear();
+      liste_b.clear();
+      for(int i_f=(((int)(taille_filtre))/2)*-1;i_f<=((int)(taille_filtre))/2;i_f++)
+	for(int j_f=(((int)(taille_filtre))/2)*-1;j_f<=((int)(taille_filtre))/2;j_f++){
+	  if(i+i_f>=0 && i+i_f<_tailleX && j+j_f>=0 && j+j_f<_tailleY){
+	    liste_r.push_back(getPixel(i+i_f,j+j_f)[0]);
+	    liste_v.push_back(getPixel(i+i_f,j+j_f)[1]);
+	    liste_b.push_back(getPixel(i+i_f,j+j_f)[2]);
+	  }
+	}
+
+      std::sort(liste_r.begin(),liste_r.end());
+      std::sort(liste_v.begin(),liste_v.end());
+      std::sort(liste_b.begin(),liste_b.end());
+      
+      img_retour.setPixel(i,j,liste_r[(liste_r.size()/2)+1],liste_v[(liste_v.size()/2)+1],liste_b[(liste_b.size()/2)+1]);
+    }
+
+  return img_retour;
+}
+
+Lisic::Image Lisic::Image::filtre_Wiener(const unsigned int& taille_filtre) const
+{
+  assert((taille_filtre%2)==1);
+
+  Lisic::Image img_retour(_tailleX,_tailleY);
+  std::vector<double> moyenne_locale_r;
+  std::vector<double> moyenne_locale_v;
+  std::vector<double> moyenne_locale_b;
+  std::vector<double> variance_locale_r;
+  std::vector<double> variance_locale_v;
+  std::vector<double> variance_locale_b;
+  
+  for(unsigned int i=0;i<_tailleX;i++)
+    for(unsigned int j=0;j<_tailleY;j++){
+      std::vector<double> voisinage_r;
+      std::vector<double> voisinage_v;
+      std::vector<double> voisinage_b;
+      for(int i_f=(((int)(taille_filtre))/2)*-1;i_f<=((int)(taille_filtre))/2;i_f++)
+	for(int j_f=(((int)(taille_filtre))/2)*-1;j_f<=((int)(taille_filtre))/2;j_f++){
+	  if(i+i_f>=0 && i+i_f<_tailleX && j+j_f>=0 && j+j_f<_tailleY){
+	    voisinage_r.push_back(getPixel(i+i_f,j+j_f)[0]);
+	    voisinage_v.push_back(getPixel(i+i_f,j+j_f)[1]);
+	    voisinage_b.push_back(getPixel(i+i_f,j+j_f)[2]);
+	  }
+	}
+      moyenne_locale_r.push_back(moyenne(voisinage_r));
+      moyenne_locale_v.push_back(moyenne(voisinage_v));
+      moyenne_locale_b.push_back(moyenne(voisinage_b));
+      variance_locale_r.push_back(variance(voisinage_r));
+      variance_locale_v.push_back(variance(voisinage_v));
+      variance_locale_b.push_back(variance(voisinage_b));
+    }
+
+  double moyenne_variance_r=moyenne(variance_locale_r);
+  double moyenne_variance_v=moyenne(variance_locale_v);
+  double moyenne_variance_b=moyenne(variance_locale_b);
+  
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++){
+      
+      double nv_r=0,nv_b=0,nv_v=0;
+      double sommeCoeff_r=0,sommeCoeff_v=0,sommeCoeff_b=0;
+      for(int i_f=(((int)(taille_filtre))/2)*-1;i_f<=((int)(taille_filtre))/2;i_f++)
+	for(int j_f=(((int)(taille_filtre))/2)*-1;j_f<=((int)(taille_filtre))/2;j_f++){
+	  if(i+i_f>=0 && i+i_f<_tailleX && j+j_f>=0 && j+j_f<_tailleY){
+	    double moyenne_r=moyenne_locale_r[(i+i_f)*_tailleY+(j+j_f)];
+	    double variance_r=variance_locale_r[(i+i_f)*_tailleY+(j+j_f)];
+	    double moyenne_v=moyenne_locale_v[(i+i_f)*_tailleY+(j+j_f)];
+	    double variance_v=variance_locale_v[(i+i_f)*_tailleY+(j+j_f)];
+	    double moyenne_b=moyenne_locale_b[(i+i_f)*_tailleY+(j+j_f)];
+	    double variance_b=variance_locale_b[(i+i_f)*_tailleY+(j+j_f)];
+	    if(variance_r==0) variance_r=0.00001;
+	    if(variance_v==0) variance_v=0.00001;
+	    if(variance_b==0) variance_b=0.00001;
+	    double coul_r=moyenne_r+((variance_r-moyenne_variance_r)/(variance_r))*(getPixel(i+i_f,j+j_f)[0]-moyenne_r);
+	    double coul_v=moyenne_v+((variance_v-moyenne_variance_v)/(variance_v))*(getPixel(i+i_f,j+j_f)[1]-moyenne_v);
+	    double coul_b=moyenne_b+((variance_b-moyenne_variance_b)/(variance_b))*(getPixel(i+i_f,j+j_f)[2]-moyenne_b);
+	    sommeCoeff_r+=coul_r;
+	    sommeCoeff_v+=coul_v;
+	    sommeCoeff_b+=coul_b;
+	    nv_r+=coul_r*getPixel(i+i_f,j+j_f)[0];
+	    nv_v+=coul_v*getPixel(i+i_f,j+j_f)[1];
+	    nv_b+=coul_b*getPixel(i+i_f,j+j_f)[2];
+	  }
+	}
+      nv_r/=sommeCoeff_r;
+      nv_v/=sommeCoeff_v;
+      nv_b/=sommeCoeff_b;
+      if(nv_r<0) nv_r=0;
+      if(nv_v<0) nv_v=0;
+      if(nv_b<0) nv_b=0;
+      if(nv_r>_profondeurCouleur) nv_r=_profondeurCouleur;
+      if(nv_v>_profondeurCouleur) nv_v=_profondeurCouleur;
+      if(nv_b>_profondeurCouleur) nv_b=_profondeurCouleur;
+      
+      img_retour.setPixel(i,j,(unsigned int)(nv_r),(unsigned int)(nv_v),(unsigned int)(nv_b));
+    }
+  
+  return img_retour;
+}
+
+Lisic::Image Lisic::Image::filtre_ondelette(const unsigned int& nbIteration) const
+{
+  cv::Mat Src=cv::Mat(_tailleY, _tailleX, CV_32FC1);
+  cv::Mat Dst=cv::Mat(_tailleY, _tailleX, CV_32FC1);
+  cv::Mat Temp=cv::Mat(_tailleY, _tailleX, CV_32FC1);
+  cv::Mat Filtered=cv::Mat(_tailleY, _tailleX, CV_32FC1);
+
+  
+  cv::Mat GrayFrame=image2Mat(*this);
+  
+  GrayFrame.convertTo(Src,CV_32FC1);
+  cvHaarWavelet(Src,Dst,nbIteration);
+  
+  Dst.copyTo(Temp);
+  
+  cvInvHaarWavelet(Temp,Filtered,nbIteration,HARD,30);
+  
+  Lisic::Image img2(*this);
+  for(unsigned int i=0;i<_tailleX;i++)
+    for(unsigned int j=0;j<_tailleY;j++){
+      float valeur=Temp.at<float>(j,i);
+      img2.setPixel(i,j,(unsigned int)valeur,(unsigned int)valeur,(unsigned int)valeur);
+    }
+  
+  return img2;
+}
+
+double Lisic::Image::param_Andre_filtre_moyenneur_3_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_moyenneur(3);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_moyenneur_3_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_moyenneur(3);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_moyenneur_5_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_moyenneur(5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_moyenneur_5_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_moyenneur(5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_3_05_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(3,0.5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_3_05_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(3,0.5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_3_10_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(3,1);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_3_10_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(3,1);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_3_15_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(3,1.5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_3_15_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(3,1.5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_5_05_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(5,0.5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_5_05_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(5,0.5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_5_10_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(5,1);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_5_10_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(5,1);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_5_15_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(5,1.5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Gaussien_5_15_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Gaussien(5,1.5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_median_3_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_median(3);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_median_3_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_median(3);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_median_5_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_median(5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_median_5_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_median(5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Wiener_3_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Wiener(3);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Wiener_3_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Wiener(3);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Wiener_5_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Wiener(5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_Wiener_5_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_Wiener(5);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_ondelette_2_moyenne() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_ondelette(2);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  return moyenne(tab);
+}
+
+double Lisic::Image::param_Andre_filtre_ondelette_2_ecart_type() const
+{
+  assert(estNiveauGris());
+  Image imgTemp(*this); imgTemp.normaliserA255();
+  std::vector<double> tab;
+  Lisic::Image img_f=imgTemp.filtre_ondelette(2);
+  imgTemp.normaliserA255(); Lisic::Image img2=imgTemp-img_f;
+  for(unsigned int i=0;i<_pixels.size();i++)
+    tab.push_back(img2._pixels[i][0]);
+  
+  return ecartType(tab);
+}
+
+Lisic::Image Lisic::Image::operator-(const Image& im) const
+{
+  assert(im._tailleX==_tailleY && im._tailleY==_tailleY && im._profondeurCouleur==_profondeurCouleur);
+  
+  Lisic::Image img(_tailleX,_tailleY,_profondeurCouleur);
+
+  for(unsigned int j=0;j<_tailleY;j++)
+    for(unsigned int i=0;i<_tailleX;i++)
+      {
+	if((int)(_pixels[j*_tailleX+i][0]-im._pixels[j*_tailleX+i][0])<0)
+	  img._pixels[j*_tailleX+i][0]=im._pixels[j*_tailleX+i][0]-_pixels[j*_tailleX+i][0];
+	else
+	  img._pixels[j*_tailleX+i][0]=_pixels[j*_tailleX+i][0]-im._pixels[j*_tailleX+i][0];
+
+	if((int)(_pixels[j*_tailleX+i][1]-im._pixels[j*_tailleX+i][1])<0)
+	  img._pixels[j*_tailleX+i][1]=im._pixels[j*_tailleX+i][1]-_pixels[j*_tailleX+i][1];
+	else
+	  img._pixels[j*_tailleX+i][1]=_pixels[j*_tailleX+i][1]-im._pixels[j*_tailleX+i][1];
+
+	if((int)(_pixels[j*_tailleX+i][2]-im._pixels[j*_tailleX+i][2])<0)
+	  img._pixels[j*_tailleX+i][2]=im._pixels[j*_tailleX+i][2]-_pixels[j*_tailleX+i][2];
+	else
+	  img._pixels[j*_tailleX+i][2]=_pixels[j*_tailleX+i][2]-im._pixels[j*_tailleX+i][2];
+	//if(img._pixels[j*_tailleX+i][0]!=0 || img._pixels[j*_tailleX+i][1]!=0 || img._pixels[j*_tailleX+i][2]!=0)
+	//std::cout << "(" << i << "," << j << ") : " << (img._pixels[j*_tailleX+i][0]+img._pixels[j*_tailleX+i][1]+img._pixels[j*_tailleX+i][2]) << std::endl;
+      }
+  
+  return img;
+}
+
+bool Lisic::Image::operator==(const Lisic::Image& im) const
+{
+  if(_tailleX!=im._tailleX || _tailleY!=im._tailleY)
+    return false;
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    if(_pixels[i]!=im._pixels[i])
+      return false;
+  return true;
+}
+
+bool Lisic::Image::operator!=(const Lisic::Image& im) const
+{
+  if(_tailleX!=im._tailleX || _tailleY!=im._tailleY)
+    return true;
+  for(unsigned int i=0;i<_tailleX*_tailleY;i++)
+    if(_pixels[i]!=im._pixels[i])
+      return true;
+  return false;
+}
+
+double Lisic::Image::moyenne(std::vector<double> x)
+{
+  double somme=0;
+  for(unsigned int i=0;i<x.size();i++)
+    somme+=x[i];
+  return (somme/x.size());
+}
+
+double Lisic::Image::variance(std::vector<double> x)
+{
+  double moy=moyenne(x),somme=0;
+  for(unsigned int i=0;i<x.size();i++)
+    somme+=(x[i]-moy)*(x[i]-moy);
+  return (somme/x.size());
+}
+
+double Lisic::Image::ecartType(std::vector<double> x)
+{
+  return sqrt(variance(x));
+}
+
+double Lisic::Image::covariance(std::vector<double> x, std::vector<double> y)
+{
+  assert(x.size()==y.size());
+  double centerX=0,centerY=0,somme=0;
+  for(unsigned int i=0;i<x.size();i++)
+    {
+      centerX+=x[i];
+      centerY+=y[i];
+    }
+  centerX/=x.size();centerY/=x.size();
+
+  for(unsigned int i=0;i<x.size();i++)
+    {
+      double tempx=x[i]-centerX;
+      double tempy=y[i]-centerY;
+      double mul=tempx*tempy;
+      somme+=mul;
+    }
+
+  somme/=x.size();
+
+  return somme;
+}
+
+//------------------------------
+//Pour la partie ondelette
+//------------------------------
+//--------------------------------
+// signum
+//--------------------------------
+float Lisic::Image::sgn(float x)
+{
+    float res=0;
+    if(x==0)
+    {
+        res=0;
+    }
+    if(x>0)
+    {
+        res=1;
+    }
+    if(x<0)
+    {
+        res=-1;
+    }
+    return res;
+}
+//--------------------------------
+// Soft shrinkage
+//--------------------------------
+float Lisic::Image::soft_shrink(float d,float T)
+{
+    float res;
+    if(fabs(d)>T)
+    {
+        res=sgn(d)*(fabs(d)-T);
+    }
+    else
+    {
+        res=0;
+    }
+
+    return res;
+}
+//--------------------------------
+// Hard shrinkage
+//--------------------------------
+float Lisic::Image::hard_shrink(float d,float T)
+{
+    float res;
+    if(fabs(d)>T)
+    {
+        res=d;
+    }
+    else
+    {
+        res=0;
+    }
+
+    return res;
+}
+//--------------------------------
+// Garrot shrinkage
+//--------------------------------
+float Lisic::Image::Garrot_shrink(float d,float T)
+{
+    float res;
+    if(fabs(d)>T)
+    {
+        res=d-((T*T)/d);
+    }
+    else
+    {
+        res=0;
+    }
+
+    return res;
+}
+//--------------------------------
+// Wavelet transform
+//--------------------------------
+void Lisic::Image::cvHaarWavelet(cv::Mat &src,cv::Mat &dst,int NIter)
+{
+    float c,dh,dv,dd;
+    assert( src.type() == CV_32FC1 );
+    assert( dst.type() == CV_32FC1 );
+    int width = src.cols;
+    int height = src.rows;
+    for (int k=0;k<NIter;k++) 
+    {
+        for (int y=0;y<(height>>(k+1));y++)
+        {
+            for (int x=0; x<(width>>(k+1));x++)
+            {
+                c=(src.at<float>(2*y,2*x)+src.at<float>(2*y,2*x+1)+src.at<float>(2*y+1,2*x)+src.at<float>(2*y+1,2*x+1))*0.5;
+                dst.at<float>(y,x)=c;
+
+                dh=(src.at<float>(2*y,2*x)+src.at<float>(2*y+1,2*x)-src.at<float>(2*y,2*x+1)-src.at<float>(2*y+1,2*x+1))*0.5;
+                dst.at<float>(y,x+(width>>(k+1)))=dh;
+
+                dv=(src.at<float>(2*y,2*x)+src.at<float>(2*y,2*x+1)-src.at<float>(2*y+1,2*x)-src.at<float>(2*y+1,2*x+1))*0.5;
+                dst.at<float>(y+(height>>(k+1)),x)=dv;
+
+                dd=(src.at<float>(2*y,2*x)-src.at<float>(2*y,2*x+1)-src.at<float>(2*y+1,2*x)+src.at<float>(2*y+1,2*x+1))*0.5;
+                dst.at<float>(y+(height>>(k+1)),x+(width>>(k+1)))=dd;
+            }
+        }
+        dst.copyTo(src);
+    }   
+}
+//--------------------------------
+//Inverse wavelet transform
+//--------------------------------
+void Lisic::Image::cvInvHaarWavelet(cv::Mat &src,cv::Mat &dst,int NIter, int SHRINKAGE_TYPE, float SHRINKAGE_T)
+{
+    float c,dh,dv,dd;
+    assert( src.type() == CV_32FC1 );
+    assert( dst.type() == CV_32FC1 );
+    int width = src.cols;
+    int height = src.rows;
+    //--------------------------------
+    // NIter - number of iterations 
+    //--------------------------------
+    for (int k=NIter;k>0;k--) 
+    {
+        for (int y=0;y<(height>>k);y++)
+        {
+            for (int x=0; x<(width>>k);x++)
+            {
+                c=src.at<float>(y,x);
+                dh=src.at<float>(y,x+(width>>k));
+                dv=src.at<float>(y+(height>>k),x);
+                dd=src.at<float>(y+(height>>k),x+(width>>k));
+
+               // (shrinkage)
+                switch(SHRINKAGE_TYPE)
+                {
+                case HARD:
+                    dh=hard_shrink(dh,SHRINKAGE_T);
+                    dv=hard_shrink(dv,SHRINKAGE_T);
+                    dd=hard_shrink(dd,SHRINKAGE_T);
+                    break;
+                case SOFT:
+                    dh=soft_shrink(dh,SHRINKAGE_T);
+                    dv=soft_shrink(dv,SHRINKAGE_T);
+                    dd=soft_shrink(dd,SHRINKAGE_T);
+                    break;
+                case GARROT:
+                    dh=Garrot_shrink(dh,SHRINKAGE_T);
+                    dv=Garrot_shrink(dv,SHRINKAGE_T);
+                    dd=Garrot_shrink(dd,SHRINKAGE_T);
+                    break;
+                }
+
+                //-------------------
+                dst.at<float>(y*2,x*2)=0.5*(c+dh+dv+dd);
+                dst.at<float>(y*2,x*2+1)=0.5*(c-dh+dv-dd);
+                dst.at<float>(y*2+1,x*2)=0.5*(c+dh-dv-dd);
+                dst.at<float>(y*2+1,x*2+1)=0.5*(c-dh-dv+dd);            
+            }
+        }
+        cv::Mat C=src(cv::Rect(0,0,width>>(k-1),height>>(k-1)));
+        cv::Mat D=dst(cv::Rect(0,0,width>>(k-1),height>>(k-1)));
+        D.copyTo(C);
+    }   
+}
+//--------------------------------
+//Image to cv::Mat
+//--------------------------------
+cv::Mat Lisic::Image::image2Mat(Lisic::Image img)
+{
+  assert(img.estNiveauGris());
+
+  cv::Mat m=cv::Mat(img._tailleY,img._tailleX,CV_8UC1);
+  for(unsigned int i=0;i<img._tailleX;i++)
+    for(unsigned int j=0;j<img._tailleY;j++)
+      m.at<unsigned char>(j,i)=img.getPixel(i,j).r();
+
+  return m;
+}

+ 158 - 0
classeImage/Image.hpp

@@ -0,0 +1,158 @@
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include <cassert>
+#include <time.h>
+#include <iostream>
+#include <fstream>
+#include <cstring>
+#include <cmath>
+#include <cstdlib>
+#include <vector>
+#include <tuple>
+
+#ifdef IM6
+#include <ImageMagick-6/Magick++.h>
+#include <ImageMagick-6/magick/MagickCore.h>
+#endif
+
+#ifdef IM7
+#include <ImageMagick-7/Magick++.h>
+#include <ImageMagick-7/MagickCore/MagickCore.h>
+#endif
+
+#include <opencv2/opencv.hpp>
+#include <fftw3.h>
+#include <Eigen/Core>
+#include <Eigen/SVD>
+#include <chrono>
+#include <thread>
+#include "Pixel.hpp"
+
+//---------------------------------
+//pour la partie ondelette
+//---------------------------------
+// Filter type
+#define NONE 0  // no filter
+#define HARD 1  // hard shrinkage
+#define SOFT 2  // soft shrinkage
+#define GARROT 3  // garrot filter
+
+namespace Lisic{
+  
+  class Image{
+    
+  public :
+    unsigned int _tailleX,_tailleY,_profondeurCouleur;
+    std::vector<Lisic::Pixel> _pixels;
+    static const int GLOBAL = 0x00000000;
+    static const int PARCANAL = 0x00000001;
+    
+  public :
+    Image(const unsigned int& tailleX=1, const unsigned int& tailleY=1, const unsigned int& profondeurCouleur=255);
+    Image(const unsigned int& tailleX, const unsigned int& tailleY, const unsigned int& profondeurCouleur, std::vector<unsigned int> canal1, std::vector<unsigned int> canal2, std::vector<unsigned int> canal3);
+    Image(const char *chemin);
+    Image(const Image& im1, const unsigned int& numeroCanal1, const Image& im2, const unsigned int& numeroCanal2, const Image& im3, const unsigned int& numeroCanal3);
+    Image(const std::vector<Lisic::Image>& vec, const unsigned int& x, const unsigned int& y);
+    Image(const Image &im);
+
+    void normaliserA255();
+    void sauver(const char *chemin) const;
+    void sauver(const std::string chemin) const;
+    void sauverSVG(const char *chemin) const;
+    void sauverSVG(const std::string chemin) const;
+    Image getSousPartie(const unsigned int& imin, const unsigned int& jmin, const unsigned int& tailleXSousPartie, const unsigned int& tailleYSousPartie) const;
+    //retourne un nouveau pixel de même couleur que le pixel demandé
+    Lisic::Pixel getPixel(const unsigned int& i, const unsigned int& j) const;
+    void setPixel(const unsigned int& i, const unsigned int& j, const unsigned int& r, const unsigned int& v, const unsigned int& b);
+    std::vector<unsigned int> extraireCanal(const unsigned int& numCanal) const;
+    bool estNoire() const;
+    bool estBlanche() const;
+    bool estNiveauGris() const;
+    unsigned int nombreDePixel(const unsigned int& r, const unsigned int& v, const unsigned int& b) const;
+    void affiche() const;
+    std::vector<Image> morceler(const unsigned int& nvtailleX, const unsigned int& nvtailleY, const bool& force=false) const;
+    Image gradient(const std::vector<int>& mask) const;
+    Image gradientRotation(const std::vector<int>& mask) const;
+    void seuil(const unsigned int& numCanal, const unsigned int& s);
+    double PSNR(const Image& im, const unsigned int& numCanal) const;
+    std::tuple<double, double, double> PSNR(const Image& im) const;
+    std::tuple<fftw_complex*, Lisic::Image, Lisic::Image> fourier() const;
+    void bruitUniforme(const double& force, const int& type=Lisic::Image::GLOBAL, const bool& verbeux=false);
+    void bruitGaussien(const double& force, const int& type=Lisic::Image::GLOBAL, const bool& verbeux=false);
+    void bruitPoivreSel(const double& force, const double& proportion, const int& type=Lisic::Image::GLOBAL, const bool& verbeux=false);
+    void bruitCauchyLorentz(const double& force, const int& type=Lisic::Image::GLOBAL, const bool& verbeux=false);
+    void bruitLaplacien(const double& force, const int& type=Lisic::Image::GLOBAL, const bool& verbeux=false);
+    void bruitLogNormale(const double& force, const int& type=Lisic::Image::GLOBAL, const bool& verbeux=false);
+    void bruitMultiplicatifUniforme(const double& force, const int& type=Lisic::Image::GLOBAL, const bool& verbeux=false);
+    void bruitMasque(std::string chemin);
+    std::vector<double> SVD() const;
+    double SVD(const unsigned int& num) const;
+    double SVD_entropy() const;
+    double SVD_entropy(std::vector<unsigned int>) const;
+    double MSE(const Image& im, const unsigned int& numCanal) const;
+    std::tuple<double, double, double> MSE(const Image& im) const;
+    double SSIM(const Image& im, const unsigned int& numCanal) const;
+    std::tuple<double, double, double> SSIM(const Image& im) const;
+    double DSSIM(const Image& im, const unsigned int& numCanal) const;
+    std::tuple<double, double, double> DSSIM(const Image& im) const;
+    Image filtre_moyenneur(const unsigned int& taille_filtre) const;
+    Image filtre_Gaussien(const unsigned int& taille_filtre, const double& sigma) const;
+    Image filtre_median(const unsigned int& taille_filtre) const;
+    Image filtre_Wiener(const unsigned int& taille_filtre) const;
+    Image filtre_ondelette(const unsigned int& nbIteration) const;
+    double param_Andre_filtre_moyenneur_3_moyenne() const;
+    double param_Andre_filtre_moyenneur_3_ecart_type() const;
+    double param_Andre_filtre_moyenneur_5_moyenne() const;
+    double param_Andre_filtre_moyenneur_5_ecart_type() const;
+    double param_Andre_filtre_Gaussien_3_05_moyenne() const;
+    double param_Andre_filtre_Gaussien_3_05_ecart_type() const;
+    double param_Andre_filtre_Gaussien_3_10_moyenne() const;
+    double param_Andre_filtre_Gaussien_3_10_ecart_type() const;
+    double param_Andre_filtre_Gaussien_3_15_moyenne() const;
+    double param_Andre_filtre_Gaussien_3_15_ecart_type() const;
+    double param_Andre_filtre_Gaussien_5_05_moyenne() const;
+    double param_Andre_filtre_Gaussien_5_05_ecart_type() const;
+    double param_Andre_filtre_Gaussien_5_10_moyenne() const;
+    double param_Andre_filtre_Gaussien_5_10_ecart_type() const;
+    double param_Andre_filtre_Gaussien_5_15_moyenne() const;
+    double param_Andre_filtre_Gaussien_5_15_ecart_type() const;
+    double param_Andre_filtre_median_3_moyenne() const;
+    double param_Andre_filtre_median_3_ecart_type() const;
+    double param_Andre_filtre_median_5_moyenne() const;
+    double param_Andre_filtre_median_5_ecart_type() const;
+    double param_Andre_filtre_Wiener_3_moyenne() const;
+    double param_Andre_filtre_Wiener_3_ecart_type() const;
+    double param_Andre_filtre_Wiener_5_moyenne() const;
+    double param_Andre_filtre_Wiener_5_ecart_type() const;
+    double param_Andre_filtre_ondelette_2_moyenne() const;
+    double param_Andre_filtre_ondelette_2_ecart_type() const;
+    
+    Image operator-(const Image&) const;
+    bool operator==(const Image&) const;
+    bool operator!=(const Image&) const;
+
+  private :
+    static double genereAleatoireUniforme(int precision=6); // retourne un nombre aléatoire \in [0;1[;
+    static std::pair<double,double> genereAleatoireGaussien(); // retourne un nombre aléatoire suivant la loi normale centrée réduite.
+    static double genereAleatoireCauchy(); // retourne un nombre aléatoire suivant la loi de Cauchy.
+    static double genereAleatoireLaplace(double mu=0, double b=1); //retourne un nombre aléatoire suivant la loi de Laplace ayant mu pour paramètre de position et b de paramètre d'échelle
+    static double genereAleatoireLogNormale(); // retourne un nombre aléatoire suivant la loi Log-normale.
+    static double moyenne(std::vector<double> x);
+    static double variance(std::vector<double> x);
+    static double ecartType(std::vector<double> x);
+    static double covariance(std::vector<double> x, std::vector<double> y);
+    //------------------------
+    //Pour la partie ondelette
+    //------------------------
+    static float sgn(float x);
+    static float soft_shrink(float d,float T);
+    static float hard_shrink(float d,float T);
+    static float Garrot_shrink(float d,float T);
+    static void cvHaarWavelet(cv::Mat &src,cv::Mat &dst,int NIter);
+    static void cvInvHaarWavelet(cv::Mat &src,cv::Mat &dst,int NIter, int SHRINKAGE_TYPE=0, float SHRINKAGE_T=50);
+    static cv::Mat image2Mat(Image img);
+  };
+}
+  
+#endif

File diff suppressed because it is too large
+ 165 - 0
classeImage/Makefile


+ 110 - 0
classeImage/Pixel.cpp

@@ -0,0 +1,110 @@
+#include "Pixel.hpp"
+
+Lisic::Pixel::Pixel(const unsigned int& r, const unsigned int& v, const unsigned int& b)
+{
+  _r=r;_v=v;_b=b;
+}
+
+std::tuple<double,double,double> Lisic::Pixel::RGB2XYZ(double r, double g, double b)
+{
+  if(r>0.04045)
+    r=pow((r+0.055)/1.055,2.4);
+  else
+    r=r/12.92;
+  if(g>0.04045)
+    g=pow((g+0.055)/1.055,2.4);
+  else
+    g=g/12.92;
+  if(b>0.04045)
+    b=pow((b+0.055)/1.055,2.4);
+  else
+    b=b/12.92;
+
+  double x = (r * Lisic::Pixel::matRGB2XYZ[0][0] + g * Lisic::Pixel::matRGB2XYZ[1][0] + b * Lisic::Pixel::matRGB2XYZ[2][0]);
+  double y = (r * Lisic::Pixel::matRGB2XYZ[0][1] + g * Lisic::Pixel::matRGB2XYZ[1][1] + b * Lisic::Pixel::matRGB2XYZ[2][1]);
+  double z = (r * Lisic::Pixel::matRGB2XYZ[0][2] + g * Lisic::Pixel::matRGB2XYZ[1][2] + b * Lisic::Pixel::matRGB2XYZ[2][2]);
+
+  return std::make_tuple(x,y,z);
+}
+
+std::tuple<double,double,double> Lisic::Pixel::RGB2LAB(double r, double g, double b)
+{
+  std::tuple<double, double, double> xyz = Lisic::Pixel::RGB2XYZ(r,g,b);
+
+  std::tuple<double, double, double> xyzNorm=Lisic::Pixel::RGB2XYZ(1.0,1.0,1.0);
+  
+  double xNorm=std::get<0>(xyz)/std::get<0>(xyzNorm);
+  double yNorm=std::get<1>(xyz)/std::get<1>(xyzNorm);
+  double zNorm=std::get<2>(xyz)/std::get<2>(xyzNorm);
+
+  double fx = 7.787*xNorm+(16.0/116.0);
+  double fy = 7.787*yNorm+(16.0/116.0);
+  double fz = 7.787*zNorm+(16.0/116.0);
+
+  if(xNorm>0.008856)
+    fx=pow(xNorm,1.0/3.0);
+  if(yNorm>0.008856)
+    fy=pow(yNorm,1.0/3.0);
+  if(zNorm>0.008856)
+    fz=pow(zNorm,1.0/3.0);
+
+  return std::make_tuple(116*fy-16,500*(fx-fy),200*(fy-fz));
+}
+
+unsigned int& Lisic::Pixel::operator[](const unsigned int& index)
+{
+  assert(index<=2);
+  switch(index)
+    {
+    case 0 :
+      return r();
+      break;
+	
+    case 1 :
+      return v();
+      break;
+
+    default :
+      return b();
+    }
+}
+
+unsigned int Lisic::Pixel::operator[](const unsigned int& index) const
+{
+  assert(index<=2);
+  switch(index)
+    {
+    case 0 :
+      return r();
+      break;
+	
+    case 1 :
+      return v();
+      break;
+
+    default :
+      return b();
+    }
+}
+
+bool Lisic::Pixel::operator==(const Lisic::Pixel& p) const
+{
+  if(_r!=p._r)
+    return false;
+  if(_v!=p._v)
+    return false;
+  if(_b!=p._b)
+    return false;
+  return true;
+}
+
+bool Lisic::Pixel::operator!=(const Lisic::Pixel& p) const
+{
+  if(_r!=p._r)
+    return true;
+  if(_v!=p._v)
+    return true;
+  if(_b!=p._b)
+    return true;
+  return false;
+}

+ 43 - 0
classeImage/Pixel.hpp

@@ -0,0 +1,43 @@
+#ifndef PIXEL_H
+#define PIXEL_H
+
+#include <cassert>
+#include <cmath>
+#include <tuple>
+
+typedef float Pixel[3];
+
+namespace Lisic{
+  class Pixel{
+  private :
+    unsigned int _r,_v,_b;
+
+  public:
+    static constexpr double matRGB2XYZ[3][3] = {{ 0.412424, 0.212656, 0.0193324},  
+						{ 0.357579, 0.715158, 0.119193},   
+						{ 0.180464, 0.0721856, 0.950444}};
+
+    Pixel(const unsigned int& r=0, const unsigned int& v=0, const unsigned int& b=0);
+    
+    inline unsigned int& r(){return _r;}
+    inline unsigned int r() const{return _r;}
+    inline unsigned int& v(){return _v;}
+    inline unsigned int v() const{return _v;}
+    inline unsigned int& b(){return _b;}
+    inline unsigned int b() const{return _b;}
+
+    static std::tuple<double, double, double> RGB2XYZ(double r, double g, double b);
+    static std::tuple<double, double, double> RGB2LAB(double r, double g, double b);
+
+    static std::tuple<double, double, double> RGB2XYZ(Lisic::Pixel p, unsigned int prof){return Lisic::Pixel::RGB2XYZ(p._r/(prof*1.0),p._v/(prof*1.0),p._b/(prof*1.0));}
+    static std::tuple<double, double, double> RGB2LAB(Lisic::Pixel p, unsigned int prof){return Lisic::Pixel::RGB2LAB(p._r/(prof*1.0),p._v/(prof*1.0),p._b/(prof*1.0));}
+
+    unsigned int& operator[](const unsigned int& index);
+    unsigned int operator[](const unsigned int& index) const;
+    bool operator==(const Pixel& p) const;
+    bool operator!=(const Pixel& p) const;
+  };
+}
+
+#endif
+

+ 3 - 0
hdrvdp/AUTHORS

@@ -0,0 +1,3 @@
+Rafal Mantiuk <mantiuk@mpi-sb.mpg.de>
+Karol Myszkowski <karol@mpi-sb.mpg.de>
+

+ 674 - 0
hdrvdp/COPYING

@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions: