|
@@ -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;
|
|
|
+}
|