From c61bb864c026d26a393f2a09c82de9bbc5043c6f Mon Sep 17 00:00:00 2001 From: Christian C Date: Tue, 4 Mar 2025 19:10:07 -0800 Subject: Modularization --- src/lib/algo/flood_fill.c | 34 ++++++++++++ src/lib/color.c | 39 +++++++++++++ src/lib/dir.c | 49 ++++++++++++++++ src/lib/time.c | 13 +++++ src/main.c | 138 +++------------------------------------------- 5 files changed, 143 insertions(+), 130 deletions(-) create mode 100644 src/lib/algo/flood_fill.c create mode 100644 src/lib/color.c create mode 100644 src/lib/dir.c create mode 100644 src/lib/time.c (limited to 'src') diff --git a/src/lib/algo/flood_fill.c b/src/lib/algo/flood_fill.c new file mode 100644 index 0000000..91f94ad --- /dev/null +++ b/src/lib/algo/flood_fill.c @@ -0,0 +1,34 @@ +#include + +//----------------------------------------------- +// Flood +// Floods a mask from a given set of image to determine the contiguous regions +// 1. Check that the (x,y) is within the picture +// 2. Check if the (x,y) coordinate in the mask is unused +// 3. Check if the (x,y) coordinate in the image is non-background +// 4. Check if the (x,y) coordinate in the image is the same color as the fill color +// 5. If all hold, set the label for the pixel, and check each neighbor +// Otherwise, stop flooding +bool_t flood(uint8_t* image, uint16_t* mask, size_t width, size_t height, size_t channels, size_t x, size_t y, uint8_t* fill_color, uint16_t label) +{ + if ((x >= width) | (y >= height)) { + return FALSE; + } + size_t coord = x + y*width; + if (mask[coord] != 0) { + return FALSE; + } + if (color_zero(&(image[coord*channels]), channels)) { + return FALSE; + } + if (color_equal(&(image[coord*channels]), fill_color, channels)) { + mask[coord] = label; + flood(image, mask, width, height, channels, x, y+1, fill_color, label); + flood(image, mask, width, height, channels, x, y-1, fill_color, label); + flood(image, mask, width, height, channels, x+1, y, fill_color, label); + flood(image, mask, width, height, channels, x-1, y, fill_color, label); + return TRUE; + } + return FALSE; +} + diff --git a/src/lib/color.c b/src/lib/color.c new file mode 100644 index 0000000..035a3e9 --- /dev/null +++ b/src/lib/color.c @@ -0,0 +1,39 @@ +#include +#include +#include + +//----------------------------------------------- +// Color Equal to Background +// Background: zeros in RGB, alpha can be whatever +bool_t color_zero(uint8_t* color1, size_t channels) { + for (size_t idx = 0; idx < channels; idx++) { + if (idx == 3) { + break; + } + if (color1[idx] != 0) { + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------- +// Color Equality +// Determine if two colors are identical +bool_t color_equal(uint8_t* color1, uint8_t* color2, size_t channels) { + for (size_t idx = 0; idx < channels; idx++) { + if (color1[idx] != color2[idx]) { + return FALSE; + } + } + return TRUE; +} + +//----------------------------------------------- +// Print out the `channels` length color vector +void print_color(uint8_t* color, size_t channels) { + for (size_t index = 0; index < channels; index++) { + printf("%hhu ", color[index]); + } + printf("\n"); +} diff --git a/src/lib/dir.c b/src/lib/dir.c new file mode 100644 index 0000000..150d5bf --- /dev/null +++ b/src/lib/dir.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include + +//----------------------------------------------- +// Is directory +bool_t is_directory(char* dirname) { + struct stat st; + if (stat(dirname, &st) == 0) { + if (S_ISDIR(st.st_mode)) { + return TRUE; + } + } + return FALSE; +} + +//----------------------------------------------- +// List directory +char** lsdir(char* dirname) { + DIR *d; + struct dirent *dir; + d = opendir(dirname); + char** file_names = (char**)malloc(sizeof(char*)); + if (!file_names) { + return NULL; + } + file_names[0] = NULL; + size_t file_count = 0; + if (d) { + while ((dir = readdir(d)) != NULL) { + if (dir->d_type == DT_REG) { + // When a regular file is reached + /// Create space for it in the list + file_names = realloc(file_names, (file_count+1+1)*sizeof(char*)); + /// Create space for the name + file_names[file_count] = calloc(strlen(dir->d_name)+1, sizeof(char)); + /// Copy the name + strcpy(file_names[file_count], dir->d_name); + /// Mark the end of the file list with a NULL entry + file_names[++file_count] = NULL; + } + } + return file_names; + } + return NULL; +} + diff --git a/src/lib/time.c b/src/lib/time.c new file mode 100644 index 0000000..2e5777b --- /dev/null +++ b/src/lib/time.c @@ -0,0 +1,13 @@ +#include + +//----------------------------------------------- +// Difference in Time +// Compute the difference between timespec structs +double diff_time(struct timespec *time1, struct timespec *time0) { + return (time1->tv_sec - time0->tv_sec) + + (time1->tv_nsec - time0->tv_nsec) / 1000000000.0; +} + +void get_time(struct timespec *ts) { + timespec_get(ts, TIME_UTC); +} diff --git a/src/main.c b/src/main.c index 3fd58a6..9594e80 100644 --- a/src/main.c +++ b/src/main.c @@ -1,144 +1,22 @@ #include #include -#include #include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include #define TAG 50839 #define OFFSET 16 #define ONE_ROW 1 -#define bool_t uint8_t -#define FALSE 0 -#define TRUE 1 - -//----------------------------------------------- -// Is directory -bool_t is_directory(char* dirname) { - struct stat st; - if (stat(dirname, &st) == 0) { - if (S_ISDIR(st.st_mode)) { - return TRUE; - } - } - return FALSE; -} - -//----------------------------------------------- -// List directory -char** lsdir(char* dirname) { - DIR *d; - struct dirent *dir; - d = opendir(dirname); - char** file_names = (char**)malloc(sizeof(char*)); - if (!file_names) { - return NULL; - } - file_names[0] = NULL; - size_t file_count = 0; - if (d) { - while ((dir = readdir(d)) != NULL) { - if (dir->d_type == DT_REG) { - // When a regular file is reached - /// Create space for it in the list - file_names = realloc(file_names, (file_count+1+1)*sizeof(char*)); - /// Create space for the name - file_names[file_count] = calloc(strlen(dir->d_name)+1, sizeof(char)); - /// Copy the name - strcpy(file_names[file_count], dir->d_name); - /// Mark the end of the file list with a NULL entry - file_names[++file_count] = NULL; - } - } - return file_names; - } - return NULL; -} - -//----------------------------------------------- -// Difference in Time -// Compute the difference between timespec structs -double diff_timespec(struct timespec *time1, struct timespec *time0) { - return (time1->tv_sec - time0->tv_sec) - + (time1->tv_nsec - time0->tv_nsec) / 1000000000.0; -} - -//----------------------------------------------- -// Color Equal to Background -// Background: zeros in RGB, alpha can be whatever -bool_t color_zero(uint8_t* color1, size_t channels) { - for (size_t idx = 0; idx < channels; idx++) { - if (idx == 3) { - break; - } - if (color1[idx] != 0) { - return FALSE; - } - } - return TRUE; -} - -//----------------------------------------------- -// Color Equality -// Determine if two colors are identical -bool_t color_equal(uint8_t* color1, uint8_t* color2, size_t channels) { - for (size_t idx = 0; idx < channels; idx++) { - if (color1[idx] != color2[idx]) { - return FALSE; - } - } - return TRUE; -} - -//----------------------------------------------- -// Print out the `channels` length color vector -void print_color(uint8_t* color, size_t channels) { - for (size_t index = 0; index < channels; index++) { - printf("%hhu ", color[index]); - } - printf("\n"); -} - -//----------------------------------------------- -// Flood -// Floods a mask from a given set of image to determine the contiguous regions -// 1. Check that the (x,y) is within the picture -// 2. Check if the (x,y) coordinate in the mask is unused -// 3. Check if the (x,y) coordinate in the image is non-background -// 4. Check if the (x,y) coordinate in the image is the same color as the fill color -// 5. If all hold, set the label for the pixel, and check each neighbor -// Otherwise, stop flooding -bool_t flood(uint8_t* image, uint16_t* mask, size_t width, size_t height, size_t channels, size_t x, size_t y, uint8_t* fill_color, uint16_t label) -{ - if ((x >= width) | (y >= height)) { - return FALSE; - } - size_t coord = x + y*width; - if (mask[coord] != 0) { - return FALSE; - } - if (color_zero(&(image[coord*channels]), channels)) { - return FALSE; - } - if (color_equal(&(image[coord*channels]), fill_color, channels)) { - mask[coord] = label; - flood(image, mask, width, height, channels, x, y+1, fill_color, label); - flood(image, mask, width, height, channels, x, y-1, fill_color, label); - flood(image, mask, width, height, channels, x+1, y, fill_color, label); - flood(image, mask, width, height, channels, x-1, y, fill_color, label); - return TRUE; - } - return FALSE; -} - int main(int argc, char** argv) { //----------------------------------------------- @@ -237,7 +115,7 @@ int main(int argc, char** argv) //----------------------------------------------- struct timespec ts_start, ts_end; - timespec_get(&ts_start, TIME_UTC); + get_time(&ts_start); //----------------------------------------------- //-FLOOD-FILL-SEGMENTATION----------------------- //-CONTIGUOUS-REGION-FINDING--------------------- @@ -269,8 +147,8 @@ int main(int argc, char** argv) } } //----------------------------------------------- - timespec_get(&ts_end, TIME_UTC); - printf("Time difference: %.3fms\n", 1000*diff_timespec(&ts_end, &ts_start)); + get_time(&ts_end); + printf("Time difference: %.3fms\n", 1000*diff_time(&ts_end, &ts_start)); printf("N_labels: %u\n", starting_label-1); uint32_t *raster = NULL; -- cgit v1.2.1