113 lines
3.3 KiB
C
113 lines
3.3 KiB
C
/*
|
|
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),
|
|
|
|
Label
|
|
Byte 0-3: Numero magico (0x00000801).
|
|
Byte 4-7: Numero di label (60.000).
|
|
Byte 8 in poi: 60.000 byte, ognuno dei quali rappresenta l'etichetta di un'immagine.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#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 && fread(&istanze[numero_righe].categoria, sizeof(byte), 8, categorie) == 8)
|
|
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);
|
|
}
|
|
} */ |