Newsgroup: it.comp.lang.c++
Titolo: Accesso array tridimensionale!!

Salve a tutti,mi presento:
Sono in fase di tesi e sto elaborando un sistema di image processing usando appunto c++.
Ora mi trovo a dover costruire un istogramma RGB tridimensionale in cui ogni dimensione ha 256
compnenti!!
Provando a dichiarare int RGB[256][256][256],il prog mi da' errore di overflow della memoria,sicche'
manuale alla mano ho sfruttato l'heap con l'operatore new allocando dinamicamente la memoria!!
Magari sto dicendo un sacco di castronerie,scusatemi.
il pezzo di codice e' questo
void alfa::RGB_Out(BYTE *data, int width, int height)
{
 
	int x, y;
	int r, g, b;
	int i,j,k;
	int (*histogram)[256][256];
	histogram = new int[256][256][256];
 
	  for(i = 0; i<256; i++){
	  for(j = 0; j<256; j++){
	  for(k = 0; k<256; k++){
	  histogram[i][j][k]=0;
	  }
	  }
	  }
 
 
	//delete[] histogram;*/
 
	for (x = 0; x < width; x++) {
		for (y = 0; y < height; y++) {
			// calcola le componenti RGB
			r = (int)data[(y * width * 3) + (x * 3)];			
			g = (int)data[(y * width * 3) + (x * 3) + 1];		
			b = (int)data[(y * width * 3) + (x * 3) + 2];
			histogram[r][g][b]++;
			//printf("r=%d g=%d b=%d",r,g,b);
		}
	}
}
in cui RGBOut e' un metodo della classe alfa!!!
data e' il raster dell'imagine rgb!!
Tutto funziona,solo che ora mi trovo in difficolta nell'aceddere agli elementi dell'array,poiche' la
miglior cosa sarebbe accedervi tramite puntatori,ma su un array tridimensionale non ho idea di come
si faccia!!!
Avevo pensato di non creare una funzione void,ma ottenere in uscita l'istogramma rgb una volta
caricata un'immagine!!
Ogni aiuto e' gradito!!!
Bye Joshua®
                    ||||||||||||............Salve Dottor Falken.........||||||||||||        
-----------
*/-*leva nospam per rispondere*-\*

 Ogni aiuto e' gradito!!!
E' molto semplice.
int *p = &data[0][0][0];
p + 1 == &data[0][0][1];
p + 2 == &data[0][0][2];
p + 256 == &data[0][1][0];
p + 256 + 1== &data[0][1][1];
p + 65536 = &data[1][0][0];
se consideriamo data[x][y][z] i dati sono disposti cosě:
0-0-0, 0-0-1... 0-0-255, 0-1-0, 0-1-1,...0-1-255,0-2-0...0-255-255,1-0-0...
Quindi la memoria puň essere considerata o come un cubo o come un array di
quadrato o come un quadrato di array.
---- bye

premetto che le mie conoscenze sono assai limitate, comunque pensavo questa
cosa:
se crei il cubo così:
int ***histogram;
 histogram=(int***) calloc (256,sizeof(int**));        (***)
 for (i = 0; i<256; i++) {
  histogram[i]=(int**) calloc (256,sizeof(int*));        (**)
  for(j = 0; j<256; j++){
   histogram[i][j]=(int*) calloc(256,sizeof(int));        (*)
  }
 }
ora histogram all'ultimo livello, cioè j, è un puntatore ad un int
cioè avrai che histogram[][][j] punta ad un intero   (*)
poi al secondo livello avrai dei puntatori a questi puntatori
(potresti vederlo come puntatori ad un'array...)     (**)
stessa cosa per il primo livello ***int sono puntatori ad una matrice
bidimensionale di puntatori...
almeno credo...
(fra parentesi questa matrice tridimensionale, o cubo, è GIA' inizializzata
a 0)
ora se voglio inserire dei valori solo sull'ultima colonna, basta questo
ciclo:
 for (i = 0; i<256; i++) {
  *(*histogram[i]) = i;
 }
cioè nell'ultima colonna ci andranno i valori da 1 a 256
se hai capito il meccanismo accedere ad altri elementi è facile...
non l'ho testato ma per accedere ad un generico elemento della
 matrice bidimensionale (livello 2) dovrebbe essere:
*(histogram[23][144]) = 666;
e per accedere al cubo ancora meglio:
histogram[10][20][30] = 1000;
ciao ciao
PS: quando vuoi passare il cubo come parametro di una funzione
 basta che gli passi  (histogram,...,....), è
 già un puntatore ed è efficiente!!!  (ok di questa non sono molto sicuro)

...
Ciao,
solo per curiosità:
stai allocando 64 MB di memoria per costruire l'histo di un'immagine RGB
(che suppongo saranno pochi MB).
Poi cosa ci fai con un tale istogramma?
Anche ammesso di avere RAM a sufficienza (image processing su swap file =
suicidio), sarebbe cmq paurosamente inefficiente a causa dei cahe miss....
Solo a "farci un giro" perderesti un sacco di tempo.
Forse ti conviene ottimizzare la struttura dati.
Se mi fai sapere a cosa ti serve l'istogramma, potrei darti qualche
dritta....


Mi serve per crearci una bool,cioe modellando l'histogramma,o meglio alcuni valori
dell'istogramma,dovrei riuscire a sogliarlo,in modo che data in ingresso una tripla R,G,B mi dia in
uscita un valore true se appartiene all'intervallo che ho creato all'interno dello spazio RGB,false
altrimenti!!
Pensavo che cmq accedervi tramite puntatori potesse semplificarmi la vita e parecchio!!!
Considera poi che tale struttura deve stare sempre in piedi,cioe' analizzare ogni pixel di ogni
singolo frame ad almeno 15 fps!!!


 singolo frame ad almeno 15 fps!!!
A occhio e croce mi sembra che una struttura OCTREE possa fare a caso tuo.
Sicuramente risparmi memoria e (tutto da valutare) potresti risparmiare
anche tempo.
http://www.google.it/search?hl=it&ie=UTF-8&oe=UTF-8&q=octree+rgb&lr
Ciao
Beppe

>Solo a "farci un giro" perderesti un sacco di tempo.
Non e' ragionevole allocare 64 MB automaticamente (cioe' sullo stack).
Dovresti o allocarli staticamente, premettendo "static" alla 
dichiarazione, o allocarli dinamicamente, usando new.
 > Pensavo che cmq accedervi tramite puntatori potesse semplificarmi la
 > vita e parecchio!!!
Per le elaborazioni da eseguire su tutto l'array puoi vedere l'array 
come una struttura monodimensionale, nel seguente modo.
Il seguente codice:
   for(i = 0; i<256; i++){
     for(j = 0; j<256; j++){
       for(k = 0; k<256; k++){
         histogram[i][j][k]=0;
       }
     }
   }
puo' essere trasformato nel seguente:
   int *p = reinterpret_cast<int *>(histogram);
   for(int i = 0; i<256 * 256 * 256; i++){
     p[i]=0;
   }
 > Mi serve per crearci una bool,cioe modellando l'histogramma,o meglio 
alcuni valori
 > dell'istogramma,dovrei riuscire a sogliarlo,in modo che data in 
ingresso una tripla R,G,B mi dia in
 > uscita un valore true se appartiene all'intervallo che ho creato 
all'interno dello spazio RGB,false
 > altrimenti!!
bool?
 > Considera poi che tale struttura deve stare sempre in piedi,cioe' 
analizzare ogni pixel di ogni
 > singolo frame ad almeno 15 fps!!!
Stare in piedi?
Per migliorare le prestastioni potresti, se l'algoritmo lo consente, 
usare un tipo piu' piccolo (unsigned short o unsigned char) come 
elemento dell'array, sostituendo il tuo:
   histogram[r][g][b]++;
con qualcosa come:
   if (histogram[r][g][b]) < 255) histogram[r][g][b]++;
oppure, usare solo 128 livelli di colore, scrivendo qualcosa come:
   histogram[r / 2][g / 2][b / 2]++;
Quest'ultimo accorgimento divide per 8 il numero di celle dell'array.
-- 
	Carlo Milanesi
 
http://digilander.libero.it/carlmila

Quest'ultimo accorgimento divide per 8 il numero di celle dell'array.
Praticamente sottocampionare lo spazio colore!!!
Credo che alla fine invece di 256 livelli ne usero' al massimo 32,ma per cominciare 
volevo prendere destrezza con tale struttura!!!
cmq grazie mille,il tuo aiuto e' stato prezioso,come quello degli altri!!!


 valore di r,g o b potra' mai essere maggiore di 255!!!
Sì, ma quella è una matrice di interi, il cui massimo è ben superiore a
255: può capitare che, per un errore, ci sia un valore superiore al
consentito.
Comunque, per risparmiare memoria potresti usare degli unsigned char al
posto degli int, dato che il tuo massimo è 255.
-- 
Per l'e-mail rimuovere le maiuscole e gli underscore

 Praticamente sottocampionare lo spazio colore!!!
Proprio cosi'. Se per le tue esigenze basta un campionamento a 7 (o 
meno) bit invece che a 8 bit, velocizzi di molto l'algoritmo.


"histogram[0][0][0]" varra' "width*height", e tutte le altre varranno zero.
Si',ma il numero di celle sara' sempre e cmq 255!!!
Io almeno mi riferivo a quello!!!
Cmq grazie mille,ho risolto il tutto facendo delle prova a 16x16x16!!!
Invece di usare calloc ho preferito la comodissima new!!!
Adesso tutto funziona e sopratttutto gli inserimenti sono corretti,anche portando le dimensioni a
256x256x256!!!
Mi sa che cmq vi scoccero' con altre richeste,per ora grazie a tutti!!
