diff options
Diffstat (limited to 'src/lib/seg/util.c')
-rw-r--r-- | src/lib/seg/util.c | 92 |
1 files changed, 82 insertions, 10 deletions
diff --git a/src/lib/seg/util.c b/src/lib/seg/util.c index 10b8fa8..238fa1c 100644 --- a/src/lib/seg/util.c +++ b/src/lib/seg/util.c @@ -1,4 +1,4 @@ -#include <lib/seg/util.h> + #include <lib/seg/util.h> #include <lib/algo/flood_fill.h> #include <lib/png.h> #include <tiffio.h> @@ -7,6 +7,12 @@ #include <stdlib.h> #include <string.h> +// Suppress Tiff Warnings +void TiffDummyHandler(const char* module, const char* fmt, va_list ap) +{ + // ignore errors and warnings (or handle them your own way) +} + // Convert x,y coords to linear coordinate size_t xy_to_coord(size_t x, size_t y, uint32_t width, uint32_t height) { @@ -51,7 +57,7 @@ bool_t is_on_mask_boundary(uint16_t* mask, uint32_t width, uint32_t height, size } // Dilate masks by one 4-connected pixel -uint16_t* dilate(uint16_t* mask, uint32_t width, uint32_t height) +uint16_t* _dilate(uint16_t* mask, uint32_t width, uint32_t height) { uint16_t *new_mask = (uint16_t*)calloc(width*height,sizeof(uint16_t)); for (size_t y = 0; y < height; y++) { @@ -95,8 +101,18 @@ uint16_t* dilate(uint16_t* mask, uint32_t width, uint32_t height) return new_mask; } +// Dilate masks by one 4-connected pixel +void dilate(uint16_t** mask, uint32_t width, uint32_t height) +{ + uint16_t *new_mask = _dilate(*mask, width, height); + if (new_mask != NULL) { + free(*mask); + *mask = new_mask; + } +} + // Erode masks by one 4-connected pixel -uint16_t* erode(uint16_t* mask, uint32_t width, uint32_t height) +uint16_t* _erode(uint16_t* mask, uint32_t width, uint32_t height) { uint16_t *new_mask = (uint16_t*)calloc(width*height,sizeof(uint16_t)); for (size_t y = 0; y < height; y++) { @@ -141,20 +157,26 @@ uint16_t* erode(uint16_t* mask, uint32_t width, uint32_t height) return new_mask; } +// Erode masks by one 4-connected pixel +void erode(uint16_t** mask, uint32_t width, uint32_t height) +{ + uint16_t *new_mask = _erode(*mask, width, height); + if (new_mask != NULL) { + free(*mask); + *mask = new_mask; + } +} + // Close up masks by N-pixels -uint16_t* closeup(uint16_t* mask, uint32_t width, uint32_t height, size_t num_pixels) +uint16_t* _closeup(uint16_t* mask, uint32_t width, uint32_t height, size_t num_pixels) { uint16_t *new_mask = (uint16_t*)calloc(width*height,sizeof(uint16_t)); memcpy(new_mask, mask, width*height*sizeof(uint16_t)); for (size_t count = 0; count < num_pixels; count++) { - uint16_t *new_labels = dilate(new_mask, width, height); - free(new_mask); - new_mask = new_labels; + dilate(&new_mask, width, height); } for (size_t count = 0; count < num_pixels; count++) { - uint16_t *new_labels = erode(new_mask, width, height); - free(new_mask); - new_mask = new_labels; + erode(&new_mask, width, height); } // Retain original mask at the very least for (size_t y = 0; y < height; y++) { @@ -170,6 +192,17 @@ uint16_t* closeup(uint16_t* mask, uint32_t width, uint32_t height, size_t num_pi return new_mask; } +// Close up masks by N-pixels +// Update pointer +void closeup(uint16_t** mask, uint32_t width, uint32_t height, size_t num_pixels) +{ + uint16_t *new_mask = _closeup(*mask, width, height, num_pixels); + if (new_mask != NULL) { + free(*mask); + *mask = new_mask; + } +} + // Combine Label Masks // For all empty spaces in the destination, put the extra label if it exists // Allocates an array if destination is unallocated @@ -194,6 +227,7 @@ uint16_t* combine_masks(uint16_t *destination, uint16_t *extra_labels, uint32_t // starting_label_p will be incremented for each label found in the image uint16_t* tif_to_labels(char* tif_file_name, uint32_t *width, uint32_t *height, uint16_t *starting_label_p) { + TIFFSetWarningHandler(TiffDummyHandler); //-TIFF-IMAGE-OPEN------------------------------- TIFF *tif = TIFFOpen(tif_file_name, "r"); if (!tif) { @@ -290,3 +324,41 @@ struct bitmap_t* uint16_to_bitmap(uint16_t* buffer, uint32_t width, uint32_t hei bitmap->height = (size_t)height; return bitmap; } + +// Reduce a mask to the contiguous regions +uint16_t* _reduce_contiguous_regions(uint16_t* masks, uint32_t width, uint32_t height, uint16_t* total_labels) +{ + uint16_t starting_label = 1; + uint16_t* new_masks = (uint16_t*)calloc(width*height, sizeof(uint16_t)); + if (new_masks == NULL) { + return NULL; + } + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < width; x++) { + size_t coord = x + y*width; + uint8_t channels = 2; // uint16_t = 2*uint8_t + if (flood((uint8_t*)masks, new_masks, width, height, channels, x, y, &(((uint8_t*)masks)[coord*channels]), starting_label)) { + starting_label++; + } + } + } + if (total_labels != NULL) { + *total_labels = starting_label; + } + return new_masks; +} + +// Reduce a mask to the contiguous regions +// Automatically update pointer to contiguous mask +// Freeing previous mask +void reduce_contiguous_regions(uint16_t** masks_p, uint32_t width, uint32_t height, uint16_t* total_labels) +{ + if (masks_p == NULL) { + return; + } + uint16_t* new_masks = _reduce_contiguous_regions(*masks_p, width, height, total_labels); + if (new_masks != NULL) { + free(*masks_p); + *masks_p = new_masks; + } +} |