rendered paste body#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();
}
}