Ciao e grazie dei consigli..
Allora io penso di aver risolto il mio problema..magari non è il metodo più efficace però al momento va.
Descrivo il problema generale: volevo creare un metodo che mi scandagliasse un'immagine e tenesse i pixel più "significativi" di questa. Per significativi intendo tra i pixel più frequenti eliminasse le sfumature togliendo quindi dalla lista dei colori quelli troppo prossimi a colori già individuati.
Le prestazioni dell'algoritmo sono un po' scadenti infatti se l'immagine ha molti colori tempi di elaborazione sono piuttosto lunghi..
questo è il codice del metodo:
codice:
public static ImageProcessor CompressRGBGlobalAdaptive(ImageProcessor ip,int nx,int ny,int numCol)
{
int array[] = new int[4];
HashMap<Integer,ColorCounter> map = new HashMap<Integer,ColorCounter> ();
//inserisco i differenti colori in una HashMap --> chiave = colore RGB convertito in intero
//poi incremento un contatore che indica il numero di voltein cui trovo quel colore
for(int x = 0;x<nx;x++) {
for(int y=0;y<ny;y++) {
array = ip.getPixel(x,y,array);
Integer i = ((array[0] & 0xFF) << 16)+((array[1] & 0xFF) << 8)+(array[2] & 0xFF);
ColorCounter cc = map.get(i);
if (cc == null)
{
cc = new ColorCounter(i);
cc.increment();
map.put (i, cc);
}
else {
cc.increment ();
map.put(i,cc);
}
}
}
// crea lista
ArrayList<ColorCounter> list = new ArrayList<ColorCounter> (map.size());
for (Integer c : map.keySet ())
list.add (map.get (c));
// ordina lista per frequenza nell'immagine
Collections.sort (list, new CounterComparator ());
//seconda lista uguale alla prima per il confronto
ArrayList<ColorCounter> secondList = new ArrayList<ColorCounter> (list.size());
int j=0,cont=0; //contatori
IJ.write("Colori iniziali: "+list.size());
int toll = 30; //tolleranza iniziale
if((list.size()-numCol)>0) { //nell'immagine ho più colori di quelli che mi servono
for(int i = 0;i<list.size() && list.size()>numCol;i++) { //prima indicizzazione della lista
secondList.clear(); //pulisco la lista dei colori da rimuovere
toll = toll - 2; //riduco la toleranza
for(int k = 0;k<list.size() && list.size()>numCol;k++) { //seconda indicizzazione della lista
if(i!=k && (DistanceComparator.getDistance(list.get(i),list.get(k)) < toll)) { //controllo che non sto confrontando un elemento con se stesso
//e che la dist euclidea dall'altro sia < della toll
secondList.add(list.get(k));
}
}//fine for secondList
//elimino i colori precedentemente selezionati
for(int a = 0;a<list.size();a++) {
for(int l = 0;l<secondList.size();l++) {
if(list.get(a).getColor()==secondList.get(l).getColor() && list.size()>numCol)
list.remove(secondList.get(l));
}
}
}
}
//riempio l'array con i soli numCol colori rimanenti
int[] histo = new int[numCol];
j=0;
for (ColorCounter cc : list ) {
if(j>=numCol) break;
histo[j] = cc.getColor();
j++;
}
int index=0,i;
double d;
int[] histomed = new int[4];
//associo ai pixel dell'immagine il più vicino tra quelli selezionati nel vettore histo
//la distanza è quella euclidea
for(int x = 0;x<nx;x++) {
for(int y=0;y<ny;y++) {
double min = 1000;
array = ip.getPixel(x,y,array);
for(i = 0; i < histo.length; i++) {
histomed[0] = ((histo[i] & 0xFF0000) >> 16);
histomed[1] = ((histo[i] & 0x00FF00) >> 8);
histomed[2] = (histo[i] & 0x0000FF);
d = Math.sqrt(Math.pow((array[0]-histomed[0]),2)+Math.pow((array[1]-histomed[1]),2)+Math.pow((array[2]-histomed[2]),2));
if(d < min) {
min = d;
index = i;
}
}
ip.putPixel(x,y,histo[index]);
}
}
//scrivo tutto su file
writeFile(ip, nx, ny, "C:/Programmi/ImageJ/plugins/GIF/prova.gif");
return ip;
}
se avete altri consigli per ottimizzare sono bene accetti!!
Ciao a tutti
Giovanni
P.S. Ringrazio anche dvjack per l'aiuto