All pastes #746100 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-10-22 23:04 UTC
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();
	}
}