Compare commits

..
4 Commits
3 changed files with 60 additions and 18 deletions
@@ -6,7 +6,6 @@
#define BUFFER_SIZE 100 #define BUFFER_SIZE 100
#define FILE_HEADER_STRING "__info2_image_file_format__" #define FILE_HEADER_STRING "__info2_image_file_format__"
// TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei
// Lädt eine .info2-Datei und prüft, ob das Dateiformat korrekt ist // Lädt eine .info2-Datei und prüft, ob das Dateiformat korrekt ist
static FILE* openImageFile(const char* path) { static FILE* openImageFile(const char* path) {
FILE* imageFile = NULL; FILE* imageFile = NULL;
@@ -95,7 +94,6 @@ static char getLabelOfImage(FILE* imageFile, GrayScaleImage* image) {
return label; return label;
} }
// TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen
GrayScaleImageSeries *readImages(const char *path) GrayScaleImageSeries *readImages(const char *path)
{ {
// Datei laden und Dateiformat prüfen // Datei laden und Dateiformat prüfen
@@ -179,20 +177,11 @@ GrayScaleImageSeries *readImages(const char *path)
} }
} }
// für jedes Bild gemäß GreyScaleImageSeries.count:
// GreyScaleImage.width = width
// GreyScaleImage.height = height
// GreyScaleImageSeries.buffer = Pixelwerte
// labels = Label des Bilds
// series.labels[i] = (unsigned char)(i % 256);
// Springe in der Datei an die Stelle nach dem i. Bild
fclose(imageFile); fclose(imageFile);
return series; return series;
} }
// TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt
void clearSeries(GrayScaleImageSeries *series) void clearSeries(GrayScaleImageSeries *series)
{ {
//prüfen, ob series überhaupt bereinigt werden muss //prüfen, ob series überhaupt bereinigt werden muss
@@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include "unity.h" #include "unity.h"
#include "imageInput.h" #include "imageInput.h"
#define FILE_HEADER_STRING "__info2_image_file_format__"
static void prepareImageFile(const char *path, unsigned short int width, unsigned short int height, unsigned int short numberOfImages, unsigned char label) static void prepareImageFile(const char *path, unsigned short int width, unsigned short int height, unsigned int short numberOfImages, unsigned char label)
@@ -64,6 +65,19 @@ static void prepareImageFileIncorrectTag(const char *path, unsigned short int wi
} }
} }
void test_readImagesFailsOnIncompleteHeader(void) {
const char *path = "testIncompleteHeader.info2";
FILE *file = fopen(path, "wb");
if (file) {
fwrite(FILE_HEADER_STRING, 1, strlen(FILE_HEADER_STRING), file);
unsigned char incompleteHeader[2] = {0x01, 0x00};
fwrite(incompleteHeader, 1, 2, file);
fclose(file);
}
TEST_ASSERT_NULL(readImages(path));
remove(path);
}
void test_readImagesReturnsCorrectNumberOfImages(void) void test_readImagesReturnsCorrectNumberOfImages(void)
{ {
@@ -159,6 +173,37 @@ void test_openImageFileIncorrectTag(void)
remove(path); remove(path);
} }
void test_clearSeriesFreesMemory(void)
{
// Dummy-Series erstellen
GrayScaleImageSeries *series = (GrayScaleImageSeries*)malloc(sizeof(GrayScaleImageSeries));
series->count = 2;
// Labels allokieren
series->labels = (unsigned char*)malloc(series->count * sizeof(unsigned char));
for (unsigned int i = 0; i < series->count; i++) {
series->labels[i] = (unsigned char)(i + 1);
}
// Images allokieren
series->images = (GrayScaleImage*)malloc(series->count * sizeof(GrayScaleImage));
for (unsigned int i = 0; i < series->count; i++) {
series->images[i].width = 4;
series->images[i].height = 4;
series->images[i].buffer = (GrayScalePixelType*)malloc(series->images[i].width * series->images[i].height);
for (unsigned int j = 0; j < series->images[i].width * series->images[i].height; j++){
series->images[i].buffer[j] = 0;
}
}
// clearSeries aufrufen
clearSeries(series);
// Test
TEST_PASS();
}
void setUp(void) { void setUp(void) {
// Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden // Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden
} }
@@ -179,6 +224,8 @@ int main()
RUN_TEST(test_readImagesReturnsNullOnNotExistingPath); RUN_TEST(test_readImagesReturnsNullOnNotExistingPath);
RUN_TEST(test_readImagesFailsOnWrongFileTag); RUN_TEST(test_readImagesFailsOnWrongFileTag);
RUN_TEST(test_openImageFileIncorrectTag); RUN_TEST(test_openImageFileIncorrectTag);
RUN_TEST(test_readImagesFailsOnIncompleteHeader);
RUN_TEST(test_clearSeriesFreesMemory);
return UNITY_END(); return UNITY_END();
} }
@@ -22,12 +22,19 @@ static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn)
for (unsigned int i = 0; i < nn.numberOfLayers; i++) { for (unsigned int i = 0; i < nn.numberOfLayers; i++) {
Layer layer = nn.layers[i]; Layer layer = nn.layers[i];
unsigned int inputDim = layer.weights.cols; // Anzahl Eingänge
unsigned int outputDim = layer.weights.rows; // Anzahl Ausgänge
// Dimensionen schreiben if(i == 0){
// beim ersten Layer inputDim und outputDim schreiben
unsigned int inputDim = layer.weights.cols; // Anzahl Eingänge
fwrite(&inputDim, sizeof(unsigned int), 1, file); fwrite(&inputDim, sizeof(unsigned int), 1, file);
unsigned int outputDim = layer.weights.rows; // Anzahl Ausgänge
fwrite(&outputDim, sizeof(unsigned int), 1, file); fwrite(&outputDim, sizeof(unsigned int), 1, file);
}
else{
// bei allen anderen Layern nur outputDim schreiben
unsigned int outputDim = layer.weights.rows; // Anzahl Ausgänge
fwrite(&outputDim, sizeof(unsigned int), 1, file);
}
// Gewichte schreiben // Gewichte schreiben
size_t weightCount = layer.weights.rows * layer.weights.cols; size_t weightCount = layer.weights.rows * layer.weights.cols;
@@ -38,8 +45,7 @@ static void prepareNeuralNetworkFile(const char *path, const NeuralNetwork nn)
fwrite(layer.biases.buffer, sizeof(MatrixType), biasCount, file); fwrite(layer.biases.buffer, sizeof(MatrixType), biasCount, file);
} }
// End-Marker (outputDim = 0)
// End-Marker (inputDim = 0)
unsigned int zero = 0; unsigned int zero = 0;
fwrite(&zero, sizeof(unsigned int), 1, file); fwrite(&zero, sizeof(unsigned int), 1, file);