PDA

Visualizza la versione completa : [C] Estrazione componenti RGB


boscaanto
28-10-2007, 14:38
Salve a tutti!!
Ho un immagine 320x240 a 24bpp, quello che devo fare è estrarre le componenti RGB e disporre ognuna di queste su un'immagine differente. Ovviamente ogni pixel è formato da 3 byte ognuno dei quali rappresenta una delle 3 componenti (ordinate sempre RGB RGB RGB...)
Quello che in pratica sto cercando di realizzare è un ciclo che prende il file raw e preleva (ad esempio per la componente R) i pixel partendo da zero e spostandosi di 3 in avanti per poi memorizzarli in un buffer...ovviamente non funziona:muro: !! Lascio che sia il codice a parlare :D :


int rows,cols,;
unsigned char **img1,**imgR,**imgG,**imgB;

unsigned char** allocabuffer(int r, int c);
void eliminabuffer(unsigned char **buffer,int r);
void readraw(char *filepath,unsigned char **buffer);
void readrawR(char *filepath,unsigned char **buffer);
void readrawG(char *filepath,unsigned char **buffer);
void readrawB(char *filepath,unsigned char **buffer);
void saveraw(char *filepath,unsigned char **buffer);

FILE *out;

main()
{
int i;
rows=240; cols=320;

imgR=allocabuffer(rows, cols);

readrawR("Immagine.raw",imgR);

saveraw("Immagine_R.raw",imgR);

eliminabuffer(imgR,rows);
}

unsigned char** allocabuffer(int r, int c)
{
int i;
unsigned char **buffer=(unsigned char**)malloc(r*sizeof(unsigned char*));
for(i=0;i<r;i++)
buffer[i]=(unsigned char*)calloc(c,sizeof(unsigned char));
return (buffer);
}

// readraw RGB
void readrawR(char *filepath,unsigned char **buffer)
{
int i;
FILE *source=fopen(filepath,"rb");
for(i=0;i<rows*cols*3;i+3) fread(buffer[i],1,1,source);
fclose(source);
}

void readrawG(char *filepath,unsigned char **buffer)
{
int i;
FILE *source=fopen(filepath,"rb");
for(i=1;i<rows;i+3) fread(buffer[i],1,cols,source);
fclose(source);
}

void readrawB(char *filepath,unsigned char **buffer)
{
int i;
FILE *source=fopen(filepath,"rb");
for(i=2;i<rows;i+3) fread(buffer[i],1,cols,source);
fclose(source);
}

void eliminabuffer(unsigned char **buffer,int r)
{
int i;
for(i=0;i<r;i++) free(buffer[i]);
free(buffer);
}

void saveraw(char *filepath,unsigned char **buffer)
{
int i;
FILE *source=fopen(filepath,"wb");
for(i=0;i<rows;i++) fwrite(buffer[i],1,1,source);
fclose(source);
}


Per il momento ho chiamato solo la funzione che estrae la componente R!!:help:

MacApp
28-10-2007, 15:32
Se ho letto bene nella funzione allocabuffer, allochi un solo byte per pixel, non dovevano essere 3?
EDIT: ok sembra che allochi un solo byte per componente, in questo caso R.

Considera anche che malloc e calloc possone restituire NULL.

EDIT 2: ho trovato l'errore:


for(i=0;i<rows*cols*3;i+3) /* i NON viene incrementato! */


devi scrivere così:



for(i=0;i<rows*cols*3;i+=3) /* i viene incrementato" */


oppure:



for(i=0;i<rows*cols*3;i=i+3) /* i viene incrementato" */

boscaanto
28-10-2007, 15:49
Grazie per aver risposto!! :)
Purtroppo anche dopo la correzione il programma non funziona. L'unica cosa che mi viene in mente è qualche errore nel buffer...

andbin
28-10-2007, 16:11
Fammi capire, hai un file "raw" (cioè si intende un file non in un formato specifico/standard, senza intestazioni o altro) composto da 320 x 240 pixel in formato RGB.

Il file è quindi una sequenza di byte: RGBRGBRGBRGB.......
Tu vuoi creare 3 file separati con le singole componenti, quindi RRRRR... poi un altro file GGGG..... ecc....
Giusto?

Se così, non capisco la necessità di tutte quelle fopen/fread.

- Alloca una area di memoria di 320*240*3 byte
- Carica tutto il file in memoria in questa area
- Alloca una area di memoria di 320*240 byte
- Per ognuna delle tre componenti sposti tutti i relativi byte dalla prima area alla seconda e la scrivi sul file.

Non è l'unica soluzione. Si tratta solo di stabilire "quanto" tenere in memoria. Si potrebbe gestire la cosa "a righe" o a blocchi di N pixel.

MacApp
28-10-2007, 16:31
Originariamente inviato da boscaanto
Grazie per aver risposto!! :)
Purtroppo anche dopo la correzione il programma non funziona. L'unica cosa che mi viene in mente è qualche errore nel buffer...
Come fai a dire "non funziona"? Come fai a verificarlo?

andbin
28-10-2007, 16:53
Comunque ha poco senso leggere il file in 3 passate in cui per ognuna si fanno read da 1 byte da mettere ad un certo offset 'i' nel buffer. Assolutamente scomodo, inutile, inefficiente.

boscaanto
28-10-2007, 17:10
Originariamente inviato da andbin
Fammi capire, hai un file "raw" (cioè si intende un file non in un formato specifico/standard, senza intestazioni o altro) composto da 320 x 240 pixel in formato RGB.

Il file è quindi una sequenza di byte: RGBRGBRGBRGB.......
Tu vuoi creare 3 file separati con le singole componenti, quindi RRRRR... poi un altro file GGGG..... ecc....
Giusto?

Se così, non capisco la necessità di tutte quelle fopen/fread.

- Alloca una area di memoria di 320*240*3 byte
- Carica tutto il file in memoria in questa area
- Alloca una area di memoria di 320*240 byte
- Per ognuna delle tre componenti sposti tutti i relativi byte dalla prima area alla seconda e la scrivi sul file.

Non è l'unica soluzione. Si tratta solo di stabilire "quanto" tenere in memoria. Si potrebbe gestire la cosa "a righe" o a blocchi di N pixel.

Si esatto, hai capito bene ciò che devo fare :)
Praticamente ci è stato dato un codice e ci è stato chiesto di modificarlo affinchè facesse ciò che ho descritto nel primo posto! Dopo aver compilato, una volta che eseguo la finestra dos rimane inattiva, come se il programma stesse continuando a girare senza terminare.

Nel main per il momento ho chiamato solo readrawR, le altre le ho messe nel codice per far capire quale fosse l'idea che c'era alla base del ragionamento.

MacApp
28-10-2007, 17:24
Originariamente inviato da boscaanto
Si esatto, hai capito bene ciò che devo fare :)
Praticamente ci è stato dato un codice e ci è stato chiesto di modificarlo affinchè facesse ciò che ho descritto nel primo posto! Dopo aver compilato, una volta che eseguo la finestra dos rimane inattiva, come se il programma stesse continuando a girare senza terminare.

Questo perché (come ti ho detto prima) nella funzione readrawR, la variabile "i" non viene incrementata e rimane sempre uguale a zero, perciò minore di rows*cols*3;

boscaanto
28-10-2007, 17:35
Si si, solo che ci dev'essere qualche altra problema perchè anche dopo la correzione il programma non gira!

MacApp
28-10-2007, 17:38
Hai scritto di chiamare solo la readrawR... chi alloca il buffer allora?

Loading