ARMv8/extension/examples/MNIST/mnist_loader.h

196 lines
5.0 KiB
C

/*
Takafumi Hoiruchi. 2018.
https://github.com/takafumihoriuchi/MNIST_for_C
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
// set appropriate path for data
#define TRAIN_IMAGE "examples/MNIST/data/train-images.idx3-ubyte"
#define TRAIN_LABEL "examples/MNIST/data/train-labels.idx1-ubyte"
#define TEST_IMAGE "examples/MNIST/data/t10k-images.idx3-ubyte"
#define TEST_LABEL "examples/MNIST/data/t10k-labels.idx1-ubyte"
#define SIZE 784 // 28*28
#define NUM_TRAIN 60000
#define NUM_TEST 10000
#define LEN_INFO_IMAGE 4
#define LEN_INFO_LABEL 2
#define MAX_IMAGESIZE 1280
#define MAX_BRIGHTNESS 255
#define MAX_FILENAME 256
#define MAX_NUM_OF_IMAGES 1
unsigned char image[MAX_NUM_OF_IMAGES][MAX_IMAGESIZE][MAX_IMAGESIZE];
int width[MAX_NUM_OF_IMAGES], height[MAX_NUM_OF_IMAGES];
int info_image[LEN_INFO_IMAGE];
int info_label[LEN_INFO_LABEL];
unsigned char train_image_char[NUM_TRAIN][SIZE];
unsigned char test_image_char[NUM_TEST][SIZE];
unsigned char train_label_char[NUM_TRAIN][1];
unsigned char test_label_char[NUM_TEST][1];
double train_image[NUM_TRAIN][SIZE];
double test_image[NUM_TEST][SIZE];
int train_label[NUM_TRAIN];
int test_label[NUM_TEST];
void FlipLong(unsigned char * ptr)
{
register unsigned char val;
// Swap 1st and 4th bytes
val = *(ptr);
*(ptr) = *(ptr+3);
*(ptr+3) = val;
// Swap 2nd and 3rd bytes
ptr += 1;
val = *(ptr);
*(ptr) = *(ptr+1);
*(ptr+1) = val;
}
void read_mnist_char(char *file_path, int num_data, int len_info, int arr_n, unsigned char data_char[][arr_n], int info_arr[])
{
int i, j, k, fd;
unsigned char *ptr;
if ((fd = open(file_path, O_RDONLY)) == -1) {
fprintf(stderr, "couldn't open image file");
exit(-1);
}
read(fd, info_arr, len_info * sizeof(int));
// read-in information about size of data
for (i=0; i<len_info; i++) {
ptr = (unsigned char *)(info_arr + i);
FlipLong(ptr);
ptr = ptr + sizeof(int);
}
// read-in mnist numbers (pixels|labels)
for (i=0; i<num_data; i++) {
read(fd, data_char[i], arr_n * sizeof(unsigned char));
}
close(fd);
}
void image_char2double(int num_data, unsigned char data_image_char[][SIZE], double data_image[][SIZE])
{
int i, j;
for (i=0; i<num_data; i++)
for (j=0; j<SIZE; j++)
data_image[i][j] = (double)data_image_char[i][j] / 255.0;
}
void label_char2int(int num_data, unsigned char data_label_char[][1], int data_label[])
{
int i;
for (i=0; i<num_data; i++)
data_label[i] = (int)data_label_char[i][0];
}
void load_mnist()
{
read_mnist_char(TRAIN_IMAGE, NUM_TRAIN, LEN_INFO_IMAGE, SIZE, train_image_char, info_image);
image_char2double(NUM_TRAIN, train_image_char, train_image);
read_mnist_char(TEST_IMAGE, NUM_TEST, LEN_INFO_IMAGE, SIZE, test_image_char, info_image);
image_char2double(NUM_TEST, test_image_char, test_image);
read_mnist_char(TRAIN_LABEL, NUM_TRAIN, LEN_INFO_LABEL, 1, train_label_char, info_label);
label_char2int(NUM_TRAIN, train_label_char, train_label);
read_mnist_char(TEST_LABEL, NUM_TEST, LEN_INFO_LABEL, 1, test_label_char, info_label);
label_char2int(NUM_TEST, test_label_char, test_label);
}
void print_mnist_pixel(double data_image[][SIZE], int num_data)
{
int i, j;
for (i=0; i<num_data; i++) {
printf("image %d/%d\n", i+1, num_data);
for (j=0; j<SIZE; j++) {
printf("%1.1f ", data_image[i][j]);
if ((j+1) % 28 == 0) putchar('\n');
}
putchar('\n');
}
}
void print_mnist_label(int data_label[], int num_data)
{
int i;
if (num_data == NUM_TRAIN)
for (i=0; i<num_data; i++)
printf("train_label[%d]: %d\n", i, train_label[i]);
else
for (i=0; i<num_data; i++)
printf("test_label[%d]: %d\n", i, test_label[i]);
}
// name: path for saving image (ex: "./images/sample.pgm")
void save_image(int n, char name[])
{
char file_name[MAX_FILENAME];
FILE *fp;
int x, y;
if (name[0] == '\0') {
printf("output file name (*.pgm) : ");
scanf("%s", file_name);
} else strcpy(file_name, name);
if ( (fp=fopen(file_name, "wb"))==NULL ) {
printf("could not open file\n");
exit(1);
}
fputs("P5\n", fp);
fputs("# Created by Image Processing\n", fp);
fprintf(fp, "%d %d\n", width[n], height[n]);
fprintf(fp, "%d\n", MAX_BRIGHTNESS);
for (y=0; y<height[n]; y++)
for (x=0; x<width[n]; x++)
fputc(image[n][x][y], fp);
fclose(fp);
printf("Image was saved successfully\n");
}
// save mnist image (call for each image)
// store train_image[][] into image[][][]
void save_mnist_pgm(double data_image[][SIZE], int index)
{
int n = 0; // id for image (set to 0)
int x, y;
width[n] = 28;
height[n] = 28;
for (y=0; y<height[n]; y++) {
for (x=0; x<width[n]; x++) {
image[n][x][y] = data_image[index][y * width[n] + x] * 255.0;
}
}
save_image(n, "");
}