#include "image.h" image::image (string nomFichier) { largeur = hauteur = -1; donnees = NULL; regionsSplit = NULL; charger(nomFichier); } int image::charger (string nomFichier) { ifstream img (nomFichier.c_str(), ios::in | ios::binary); string tmp; if (!img.is_open()) { cout << "[-] image::charger > Impossible d'ouvrir le fichier " << nomFichier << endl; return -1; } /* lecture de la MagicValue */ do { img >> tmp; } while (tmp[0]=='#'); if (tmp != "P5") { cout << "[-] image::charger > MagicValue incorrecte.\n"; return -1; } /* lecture de la taille de l'image (largeur) */ do { img >> tmp; } while (tmp[0]=='#'); istringstream conv1 (tmp); conv1 >> largeur; /* lecture de la taille de l'image (hauteur) */ do { img >> tmp; } while (tmp[0]=='#'); istringstream conv2 (tmp); conv2 >> hauteur; if (largeur<=0 || hauteur<=0) { cout << "[-] image::charger > Dimensions de l'image incorrectes.\n"; return -1; } /* allocation de l'image */ donnees = new unsigned char[largeur*hauteur]; /* lecture de la teinte maximale */ do { img >> tmp; } while (tmp[0]=='#'); /* lecture de l'image (et inversion) */ for (int i=0; i!=hauteur; i++) for (int j=0; j!=largeur; j++) img.read((char *)&(donnees[(hauteur-i)*hauteur+j]), sizeof(char)); img.close(); /* allocation dynamique du masque des régions (affichage du split) */ regionsSplit = new bool [largeur*hauteur]; for (int i=0; i!=largeur*hauteur; i++) regionsSplit[i] = false; /* allocation dynamique du masque des régions (affichage du merge) */ regionsMerge = new bool [largeur*hauteur]; for (int i=0; i!=largeur*hauteur; i++) regionsMerge[i] = false; /* allocation dynamique du masque des régions */ regions = new double [largeur*hauteur]; for (int i=0; i!=largeur*hauteur; i++) regions[i] = 0.0; return 0; } image::~image () { if (donnees) delete [] donnees; if (regionsSplit) delete [] regionsSplit; if (regionsMerge) delete [] regionsMerge; if (regions) delete [] regions; } int image::getLargeur () { return largeur; } int image::getHauteur () { return hauteur; } unsigned char *image::getDonnees () { return donnees; } int image::getNbPixelRegion (int xMin, int xMax, int yMin, int yMax) { return (xMax-xMin) * (yMax-yMin); } double image::getMoyenneRegion (int xMin, int xMax, int yMin, int yMax, int nbPixel) { double moyenne = 0.0; /* calcul de la moyenne */ for (int i=yMin; i!=yMax; i++) for (int j=xMin; j!=xMax; j++) moyenne += (double)donnees[i*hauteur+j]; moyenne /= nbPixel; return moyenne; } bool image::isRegionHomogene (int xMin, int xMax, int yMin, int yMax, double moyenne) { double ecartType; /* calcul de l'écart type */ ecartType = 0; for (int i=yMin; i!=yMax; i++) { for (int j=xMin; j!=xMax; j++) { double diff = donnees[i*hauteur+j] - moyenne; ecartType += (diff*diff); } } return (ecartType < 100000); } void image::diviser () { diviser(0,largeur,0,hauteur,1); } void image::diviser (int xMin, int xMax, int yMin, int yMax, int niveau = 1) { int nbPixel = getNbPixelRegion(xMin,xMax,yMin,yMax); double moyenne = getMoyenneRegion(xMin,xMax,yMin,yMax,nbPixel); /* si la région est homogène, alors on la stocke */ if (niveau>NIVEAU_MAX || nbPixel<100 || isRegionHomogene(xMin,xMax,yMin,yMax,moyenne)) { for (int i=yMin; i!=yMax; i++) { regionsSplit[i*hauteur+xMin] = true; regionsSplit[i*hauteur+xMax] = true; for (int j=xMin; j!=xMax; j++) { regionsSplit[yMin*hauteur+j] = true; regions[i*hauteur+j] = moyenne; regionsSplit[yMax*hauteur+j] = true; } } } else { int xInter = xMin + (xMax-xMin)/2 -1; int yInter = yMin + (yMax-yMin)/2 -1; diviser(xMin , xInter, yInter, yMax , niveau+1); diviser(xInter, xMax , yInter, yMax , niveau+1); diviser(xInter, xMax , yMin , yInter, niveau+1); diviser(xMin , xInter, yMin , yInter, niveau+1); } } void image::grouper () { for (int i=0; i!=hauteur; i++) for (int j=0; j!=largeur; j++) donnees[i*hauteur+j] = (unsigned char)regions[i*hauteur+j]; float dist; for (int i=0; i!=hauteur-1; i++) { for (int j=0; j!=largeur-1; j++) { dist = fabs(regions[i*hauteur+j] - regions[(i+1)*hauteur+j]); if (dist > 0.1) { regionsMerge[i*hauteur+j] = true; } else { dist = fabs(regions[i*hauteur+j] - regions[i*hauteur+j+1]); if (dist > 0.1) { regionsMerge[i*hauteur+j] = true; } } } } } void image::afficherDivision () { if (regionsSplit) { glColor3f(1,1,1); glBegin(GL_POINTS); for (int i=0; i!=hauteur; i++) for (int j=0; j!=largeur; j++) if (regionsSplit[i*hauteur+j]) glVertex2i(j,i); glEnd(); } } void image::afficherGroupement () { if (regionsSplit) { glColor3f(1,1,1); glBegin(GL_POINTS); for (int i=0; i!=hauteur; i++) for (int j=0; j!=largeur; j++) if (regionsMerge[i*hauteur+j]) glVertex2i(j,i); glEnd(); } }