CANDA Antoine
VERSCHAEVE Théo
TP2 ACT : réduction de palette

Excusez nous pour le retard. J'ai eu un probleme de connexion ce samedi 29 octobre. 
Cela ne se reproduira plus.

La reduction de palette fonctionne. 
On a testé notamment sur le babouin. 

La commande pour executer : 

java -jar reduction.jar <chemin image> < nombre couleur final> <nom image resultat> 



1 - Implémentation des fonctions de base

On a implanté les fonctions de base de notre projet en premier lieu. 

Dans une classe ImageAction, on a reuni les methodes manipulant directement l'image que l'on souhaite modifier. Elle possede 3 methodes. 
On a une fonction qui va récupérer la liste des couples valeurs/poids pour chaque couleur de l'image qui est triée en ordre croissant: getHistogramFromImage.
On a une fonction qui créer un tableau à deux dimensions de l'image pour avoir la couleur associe a un pixel en position (x,y). Ce tableau servira pour la reconstruction de l'image:
loadPixelsFromImage
On a une fonction qui va recreer l'image avec les nouvelles couleurs: createNewImage.
Ces methodes ont ete testees avec l'image du babouin et semble coherente. 

On a une classe Interval qui definit un interval c'est a dire un indice de debut et de fin ainsi que deux accesseurs. 
On a une classe Couple qui definit un couple valeur/poids d'un pixel avec notamment des accesseurs.

On a une classe NiveauxGris qui représente le coeur de l'algorithme.
On a implanté les fonctions meilleurGris et distanceMin comme présenté dans le TP. 
On a pu tester avec les données issues du TP (réduction de la palette de 7 couleurs en une notamment avec le calcul de la 2e couleur). 
On a bien eu les résultats attendus.
On a egalement creer la fonction getCouleurFinal qui a partir d'une liste d'interval renvoye la liste des valeurs des couleurs resultats en utilisant meilleurGris. 
Avec cette methode on a pu creer la methode createNewPaletteGris qui a partir de la liste des couples de pixel, des intervals et des des couleurs resultantes permet de creer
une table de hachage qui associe la valeur de la couleur du pixel de depart a la valeur de la couleur resultat. On utilise cette map dans la creation de l'image resultat. 
Ces fonctions ont ete testees en utilisant des valeurs d'intervals de maniere aleatoire afin de voir si il y avait bien une modification des pixels de l'image de base. 
En reutilisant sur l'image resultat la methode permettant d'avoir l'histogramme des couleurs on a bien le nombre de couleurs issues de la reduction de palette. 

2 - Implementation du coeur de l'algorithme 

La methode distanceTotalMin(int debut, int nombreCouleur) est la methode permettant de calculer la distance globale minimale. 
Elle effectue un appel recursif.
Elle utilisera deux tableaux : tab[taille palette][taille palette] et tabDistImageMin[taille palette][nombreCouleur] qui sont des variables globale

pseudo code: 

Entree : tab et tabDistImageMin deux tableaux initialisé à -1 et deux entiers nombreCouleur et debut 
Sortie : entier res 

	int min = + infini (on prend un entier plus grand que 256*256*nombrePixel)

	// Cas de base 
	Si(nombreCouleur == 1 ){
		Si tab[debut][taille palette - 1 ] == -1{
			gris = meilleurGris(debut, taille palette -1);
			tab[debut][taille palette -1 ] = distanceMin(debut, taille palette -1 , gris)
		}
		return tab[debut][taille palette -1];
	}
	Pour(j = debut; j < taille palette - (nombreCouleur -1)); j++){
		
		Si (tab[debut][j]== -1){
			// on le calculer
			gris = meilleurGris(debut,j);
			tab[debut][j] = distanceMin(debut, j, gris);
		}
		Si( tabDistImageMin[j+1][nombreCouleur-1] == -1){
			// on calculer et on utilise pour cela la recursion et on reduit le probleme
			tabDistImageMin[j+1][nombreCouleur-1] = distanceTotalMin(j+1, nombreCouleur-1);
		}
		
		int res = tabDistImageMin[j+1][k-1] + tab[debut][j];
		
		Si(min> res){
			min = res
		}
	}
	return min ; 
	
	Complexite : remplissage des tableaux = O(n²).
	Cas de base :  O(1)
	Complexite : O(n²)
	
3 - Remontée de table pour construire les intervals

	On utilise pour cela la fonction getInterval qui permet de construire les intervals des fusion de couleurs. 
	Pour cela on va additionner le resultat de distanceMin pour un interval donne avec le resultat TabDistanceImageMin qui correspond aux intervals suivants 
	Si on a une correspondance avec le resultat a trouver on prend l'interval correspondant a distanceMin et on change le resultat par la valeur de TabDistanceImageMin qui est le reste a trouver.
	On fait une boucle jusqu'à avoir 1 seul couleur qui correspond alors au reste des couleurs a fusionner soit debut à taille palette -1
	
	Pseudo code: 
	
	Entree : entier nombre de couleur, resultat global a trouver. On va reutiliser les deux tableaux pour cela
	Sortie : liste des intervales
	
	getInterval(nombreCouleur, res){
		liste interval = new liste;
		
		debut = 0;
		resultat = res;
		
		Pour(int i = nombreCouleur -1; i>0; i--){
			Pour(int j = debut +1; j < taille palette - 1; j++){
				Si(tab[debut][j-1] + tabDistImageMin [j][i] == resultat){
					Interval interval = nouveau Interval(debut, j-1);
					on ajoute interval a la liste des interval;
					resultat = tabDistImageMin[j][i];
					debut = j;
					break;
				}
			}
		}
		Interval interval = nouveau Interval(debut, taille palette - 1);
		ajoute interval à la liste des interval;
		
		return la liste des interval;
	}
	
	A partir de cette liste des intervals on va pouvoir utiliser meilleurGris sur chacun d'eux pour avoir la liste des gris resultat
	On le fait dans la fonction simple getCouleurFinal.
	A partir de cette liste des couleurs on va pouvoir associer les anciennes couleurs aux nouvelles. 
	On utilise pour cela la fonction createNewPaletteGris qui prend en parametre la liste des interval la liste des gris final et la liste des couples initiaux representant la palette de base.
	Pour chaque interval de la liste des intervals, on va faire une boucle allant de debut de l'interval a fin de l'interval et on y associe la j-ieme couleur de la liste des couleurs finals a chaque couleur presente dans la palette intiale 
	comprise dans l'itnervale. 

4 - Reconstruction de l'image

Cette partie avait ete traitee dans les fonctions de base car c'est l'assemblage de toute les etapes precedentes. 

5 - Justification 

On souhaite justifier le fait que les couleurs voisines sont nécessaire pour avoir la distance minimale entre les images de depart et d'arrivee. 

Pour cela on a besoin de justifier distanceMin. 

distanceMin a besoin de meilleurGris pour calculer la moyenne ponderee des differents gris fusionne en un gris.
distanceMin a comme algorithme valeurAbsolue(valeur de la couleur de depart - valeur de la couleur d'arrivee)² * poids de la valeur de depart. 

Imaginons que les valeurs des couleurs ne soient pas triees. On fusionne les couleurs au hasard. Si on tombe sur deux couleurs aux extrimites par exemple 0 et 255 avec respectivement p1 et p2  pixels.

Disons que p1 = p2 = p. 

on aura meilleurGris = 127 ou 128 selon l'arrondi. 

Quand on calculera distanceMin on aura (-128)²*p1 + (127)²*p2. Soit ((-128)²+(127)²)*p ~ 32500*p. 

Le probleme se trouve au niveau du calcul de distanceMin. 

Soit v1<v2<v3<v4 et vG1 = meilleurGris() a partir des pixels de v1 et v2. vG2 = meilleurGris a partir des pixels de v1 et v4 avec p1,p2,p3,p4 > 0 .
On considere que p1 ~ p2 ~ p3 ~ p4. 

	|(v1-vG1)| < |(v1-vG2)|  	et 	|(v2-vG1)| < |(v4-vG2)|
	|(v1-vG1)|² < |(v1-vG2)|²	et 	|(v2-vG1)|² < |(v4-vG2)|²
	|(v1-vG1)|² * p1 < |(v1-vG2)|² * p1 	et 	|(v2-vG1)|² * p2 < |(v4-vG2)|² * p4

	|(v1-vG1)|² * p1 + |(v2-vG1)|² * p2  < |(v1-vG2)|² * p1 + |(v4-vG2)|² * p4