atharendil | Bonjour,
je suis sur un projet qui demande d'enregistrer / charger des images cérébrales 3D au format NIfTI. Ce format est constitué d'un fichier contenant un header puis, toujours à partir de l'offset 352 (taille du header), les niveaux de gris de l'image.
L'enregistrement et le chargement fonctionnent parfaitement sous ce format et j'ai donc décidé de pouvoir utiliser la compression / décompression de fichiers avec zlib. Et c'est là que rien ne va plus.
En effet, après sauvegarde et compression, lorsque l'on recharge le fichier, l'image se trouve légèrement décalée. Cela n'est pas du au chargement puisque les fichiers externes dont je me sers pour tester le programme s'ouvrent correctement.
Les informations du header me semblent bien enregistrées étant donné qu'elles sont toutes récupérées au chargement. Il s'agit très certainement d'un problème à l'enregistrement des niveaux de gris de l'image.
Voici comment je les enregistre (après avoir enregistré le header) :
Code :
- if(!write_raw(fich, image, 352)){
- remove(fich);
- PUT_ERROR("Erreur lors de la sauvegarde des donnees MRI de l'image" );
- return 0;
- }
|
Ceci est l'appel de la fonction d'enregistrement des données avec comme argument le nom du fichier, la structure contenant les données à enregistrer ("image" ) et la position d'enregistrement (l'offset).
Voilà le code de cette fonction, d'où vient certainement le bug :
Code :
- int write_raw(const char *file_img, grphic3d *graphic, int offset)
- {
- gzFile f_img;
- int i=0,j=0,k=0;
- char *buffchar;
- short *buffshort;
- long *bufflong;
- void *buffer;
- int data_size,num_items;
- f_img=gzopen(file_img, "a+" );
- if(f_img==NULL || (long)gzseek(f_img, offset, SEEK_SET)==-1)
- {
- char tmp[256];
- sprintf(tmp,"pas possible ecrire fichier %s\n",file_img);
- PUT_ERROR(tmp);
- return 0;
- }
- //---------------------IMG Section
- data_size = graphic->bitppixel/8;
- num_items = graphic->width*graphic->depth;
- switch(data_size)
- {
- case sizeof(char):
- buffchar = CALLOC(num_items,char);
- if(buffchar == NULL) {
- PUT_ERROR(
- "[save_mri_ipb_3d] memory allocation error (2)!\n" );
- gzclose(f_img);
- FREE(buffchar);
- return 0;
- }
- buffer = buffchar;
- for(j=0; j<graphic->height; j++)
- {
- buffchar = buffer;
- for(k=0; k<graphic->depth; k++)
- for(i=0; i<graphic->width; i++)
- *buffchar ++ = graphic->mri[i][graphic->height-j-1][graphic->depth-k-1];
- if(gzwrite(f_img,(void *)buffer, data_size * num_items) / data_size != num_items) {
- PUT_ERROR(
- "[save_mri_ipb_3d] error writing data (2)!\n" );
- gzclose(f_img);
- FREE(buffchar);
- return 0;
- }
- }
- gzflush(f_img, Z_SYNC_FLUSH);
- break;
- case sizeof(short):
- buffshort = CALLOC(num_items,short);
- if(buffshort == NULL) {
- PUT_ERROR(
- "[save_mri_ipb_3d] memory allocation error (4)!\n" );
- gzclose(f_img);
- FREE(buffshort);
- return 0;
- }
- buffer = buffshort;
- for(j=0; j<graphic->height; j++)
- {
- buffshort = buffer;
- for(k=0; k<graphic->depth; k++)
- for(i=0; i<graphic->width; i++)
- if (!_is_bigEndian) *buffshort ++ = graphic->mri[i][graphic->height-j-1][graphic->depth-k-1];
- else *buffshort ++ = shEndianConversion(graphic->mri[i][graphic->height-j-1][graphic->depth-k-1]);
- if(gzwrite(f_img, (void *)buffer, data_size * num_items) / data_size != num_items) {
- PUT_ERROR(
- "[save_mri_ipb_3d] error writing data (4)!\n" );
- gzclose(f_img);
- FREE(buffshort);
- return 0;
- }
- }
- gzflush(f_img, Z_SYNC_FLUSH);
- break;
- case sizeof(long):
- bufflong = CALLOC(num_items*2,long);
- if(bufflong == NULL) {
- PUT_ERROR(
- "[save_mri_ipb_3d] memory allocation error (6)!\n" );
- gzclose(f_img);
- FREE(bufflong);
- return 0;
- }
- buffer = bufflong;
- for(j=0; j<graphic->height; j++)
- {
- bufflong = buffer;
- for(k=0; k<graphic->depth; k++)
- for(i=0; i<graphic->width; i++)
- if (!_is_bigEndian) *bufflong ++ = graphic->mri[i][graphic->height-j-1][graphic->depth-k-1];
- else *bufflong ++ = longEndianConversion(graphic->mri[i][graphic->height-j-1][graphic->depth-k-1]);
- if(gzwrite(f_img, (void *)buffer, data_size * num_items) / data_size != num_items) {
- PUT_ERROR(
- "[save_mri_ipb_3d] error writing data (6)!\n" );
- gzclose(f_img);
- FREE(bufflong);
- return 0;
- }
- }
- gzflush(f_img, Z_SYNC_FLUSH);
- break;
- default:
- PUT_ERROR(
- "[save_mri_ipb_3d] invalid data size\n" );
- return 0;
- }
- FREE(buffer);
- return 1;
- }
|
Le paramètre graphic est la structure contenant les données importantes sur l'image comme les dimensions (width, height, depth) ainsi que le nombre de bits par pixel (bitppixel) que l'on divise par 8 pour connaître le type de données et enregistrer les niveaux de gris (champ mri) en conséquence.
Ce même code enregistre sans aucun problème les données en utilisant les primitives fopen, fwrite, etc...
Merci à qui me répondra Message édité par atharendil le 06-06-2006 à 10:29:32
|