/* Il file MNIST in formato IDX ha questa struttura: Byte 0-3: Numero magico (4 byte). Byte 4-7: Numero di immagini (4 byte). Byte 8-11: Numero di righe per immagine (4 byte). Byte 12-15: Numero di colonne per immagine (4 byte). Byte 16 in poi: Dati delle immagini (ogni immagine è composta da 28x28 = 784 byte). Le immagini sono 28x28 pixel. I dati sono byte non firmati (valori da 0 a 255). Il file contiene 60.000 immagini (per il training set), */ #include #include #define N_PIXEL 784 // Immagine 28x28 // Siccome il char è un byte che rappresenta il valore tra 0 e 255. Per evitare confusioni definisco il tipo "byte" come in Java typedef unsigned char byte; // Singola istanza del dataset. typedef struct { byte categoria; byte immagine[N_PIXEL]; } Istanza; // Questo tipo fornisce il vettore delle istanze e il size (dimensione) del vettore typedef struct { int size; Istanza *istanze; } Dataset; Dataset *get_dataset(char *, char *); // Questo metodo legge il file in questione e restituisce un puntatore a Dataset se il file esiste, altrimenti NULL // Ritorna un puntatore perchè in questo caso posso gestire il ritorno NULL. Dataset *get_dataset(char *path_mnist, char *path_categoria) { Dataset *set = (Dataset *)malloc(sizeof(Dataset)); FILE *file; FILE *categorie; Istanza *istanze = (Istanza *)malloc(sizeof(Istanza)); file = fopen(path_mnist, "rb"); if (file == NULL) { printf("Errore nella funzione fopen() nelle immagini\n"); return NULL; } categorie = fopen(path_categoria, "rb"); if (file == NULL) { printf("Errore nella funzione fopen() nelle categorie\n"); return NULL; } int numero_righe = 0; //Leggo male il file, cambiare in base alle dichiarazioni sopra if(fread(istanze[numero_righe].immagine, sizeof(byte), 16, file) == 16) while (fread(istanze[numero_righe].immagine, sizeof(byte), N_PIXEL, file) == N_PIXEL) { if(fread(&istanze[numero_righe].categoria, sizeof(byte), 1, categorie) == 1) { numero_righe++; istanze = (Istanza *)realloc(istanze, sizeof(Istanza) * (numero_righe + 1)); } } // Dataset set; (*set).size = numero_righe; (*set).istanze = istanze; fclose(file); return set; } void salva_dataset(const char *filename, Dataset *set) { FILE *file = fopen(filename, "wb"); if (!file) { perror("Errore nell'apertura del file"); exit(EXIT_FAILURE); } for (int indice_istanze = 0; indice_istanze < set->size; indice_istanze++) { fwrite(&set->istanze[indice_istanze].categoria, sizeof(byte), 1, file); fwrite(&set->istanze[indice_istanze].immagine, sizeof(byte), N_PIXEL, file); } fclose(file); } /* void main() { Dataset *set = get_dataset("t10k-images.idx3-ubyte", "t10k-labels.idx1-ubyte"); if(set == NULL) { printf("Nullo esco\n"); return; } for(int i = 0; i < set->size; i++) { printf("immagine %d - valore rappresentato: %d\n", i, set->istanze[i].categoria); } } */