diff options
author | Christian C <cc@localhost> | 2025-03-23 17:47:36 -0700 |
---|---|---|
committer | Christian C <cc@localhost> | 2025-03-23 17:47:36 -0700 |
commit | 848a0f6e2d634001e30cbfebef05d93f7301facd (patch) | |
tree | 45b062c90d59e6f48284bc73c42d17d7fde19740 /lib/seg/util.c | |
parent | 2fe858c22d27722130339c0d26de00aa78ef1f4d (diff) |
Migration to Mask
Diffstat (limited to 'lib/seg/util.c')
-rw-r--r-- | lib/seg/util.c | 233 |
1 files changed, 101 insertions, 132 deletions
diff --git a/lib/seg/util.c b/lib/seg/util.c index 844d4a1..bc2f837 100644 --- a/lib/seg/util.c +++ b/lib/seg/util.c @@ -13,43 +13,31 @@ 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) -{ - return x + y*width; -} - // Determine if coordinate is on a mask boundary // Assumes mask is (WxH) -bool_t is_on_mask_boundary(MaskData_t* mask, uint32_t width, uint32_t height, size_t x, size_t y) +bool_t is_on_mask_boundary(Mask* mask, size_t x, size_t y) { - size_t starting_coord = xy_to_coord(x, y, width, height); - size_t proposed_position; - MaskData_t current_value = mask[starting_coord]; + MaskData_t current_value = mask->image[y][x]; // Left neighbor if (x != 0) { - proposed_position = xy_to_coord(x-1, y, width, height); - if (mask[proposed_position] != current_value) { + if (mask->image[y][x-1] != current_value) { return TRUE; } } // Right neighbor - if ((x+1) != width) { - proposed_position = xy_to_coord(x+1, y, width, height); - if (mask[proposed_position] != current_value) { + if ((x+1) != mask->width) { + if (mask->image[y][x+1] != current_value) { return TRUE; } } if (y != 0) { - proposed_position = xy_to_coord(x, y-1, width, height); - if (mask[proposed_position] != current_value) { + if (mask->image[y-1][x] != current_value) { return TRUE; } } - if ((y+1) != height) { - proposed_position = xy_to_coord(x, y+1, width, height); - if (mask[proposed_position] != current_value) { + if ((y+1) != mask->height) { + if (mask->image[y+1][x] != current_value) { return TRUE; } } @@ -57,145 +45,151 @@ bool_t is_on_mask_boundary(MaskData_t* mask, uint32_t width, uint32_t height, si } // Dilate masks by one 4-connected pixel -MaskData_t* _dilate(MaskData_t* mask, uint32_t width, uint32_t height) +MaskData_t* _dilate(const Mask* mask) { - MaskData_t *new_mask = (MaskData_t*)calloc(width*height,sizeof(MaskData_t)); + uint32_t width = mask->width; + uint32_t height = mask->height; + Mask *new_mask = create_image_mask(width, height); for (size_t y = 0; y < height; y++) { for (size_t x = 0; x < width; x++) { - size_t current_position = xy_to_coord(x, y, width, height); - if (mask[current_position] != 0) { - new_mask[current_position] = mask[current_position]; + if (mask->image[y][x] != 0) { + new_mask->image[y][x] = mask->image[y][x]; continue; } - size_t proposed_position; if (x != 0) { - proposed_position = xy_to_coord(x-1, y, width, height); - if (mask[proposed_position] != 0) { - new_mask[current_position] = mask[proposed_position]; + if (mask->image[y][x-1] != 0) { + new_mask->image[y][x] = mask->image[y][x-1]; continue; } } if ((x+1) != width) { - proposed_position = xy_to_coord(x+1, y, width, height); - if (mask[proposed_position] != 0) { - new_mask[current_position] = mask[proposed_position]; + if (mask->image[y][x+1] != 0) { + new_mask->image[y][x] = mask->image[y][x+1]; continue; } } if (y != 0) { - proposed_position = xy_to_coord(x, y-1, width, height); - if (mask[proposed_position] != 0) { - new_mask[current_position] = mask[proposed_position]; + if (mask->image[y-1][x] != 0) { + new_mask->image[y][x] = mask->image[y-1][x]; continue; } } if ((y+1) != height) { - proposed_position = xy_to_coord(x, y+1, width, height); - if (mask[proposed_position] != 0) { - new_mask[current_position] = mask[proposed_position]; + if (mask->image[y+1][x] != 0) { + new_mask->image[y][x] = mask->image[y+1][x]; continue; } } } } - return new_mask; + MaskData_t *ret_mask = new_mask->image[0]; + free(new_mask->image); + free(new_mask); + return ret_mask; } // Dilate masks by one 4-connected pixel -void dilate(MaskData_t** mask, uint32_t width, uint32_t height) +void dilate(Mask* mask) { - MaskData_t *new_mask = _dilate(*mask, width, height); + MaskData_t *new_mask = _dilate(mask); if (new_mask != NULL) { - free(*mask); - *mask = new_mask; + free(mask->image[0]); + for (size_t y = 0; y < mask->height; y++) { + mask->image[y] = &(new_mask[y*mask->width]); + } } } // Erode masks by one 4-connected pixel -MaskData_t* _erode(MaskData_t* mask, uint32_t width, uint32_t height) +MaskData_t* _erode(const Mask* mask) { - MaskData_t *new_mask = (MaskData_t*)calloc(width*height,sizeof(MaskData_t)); - memcpy(new_mask, mask, width*height*sizeof(MaskData_t)); + uint32_t width = mask->width; + uint32_t height = mask->height; + Mask *new_mask = create_image_mask(width, height); + memcpy(new_mask->image[0], mask->image[0], width*height*sizeof(MaskData_t)); for (size_t y = 0; y < height; y++) { for (size_t x = 0; x < width; x++) { - size_t current_position = xy_to_coord(x, y, width, height); - size_t proposed_position; if (x != 0) { - proposed_position = xy_to_coord(x-1, y, width, height); - if (mask[proposed_position] == 0) { - new_mask[current_position] = 0; + if (mask->image[y][x-1] == 0) { + new_mask->image[y][x] = 0; continue; } } if ((x+1) != width) { - proposed_position = xy_to_coord(x+1, y, width, height); - if (mask[proposed_position] == 0) { - new_mask[current_position] = 0; + if (mask->image[y][x+1] == 0) { + new_mask->image[y][x] = 0; continue; } } if (y != 0) { - proposed_position = xy_to_coord(x, y-1, width, height); - if (mask[proposed_position] == 0) { - new_mask[current_position] = 0; + if (mask->image[y-1][x] == 0) { + new_mask->image[y][x] = 0; continue; } } if ((y+1) != height) { - proposed_position = xy_to_coord(x, y+1, width, height); - if (mask[proposed_position] == 0) { - new_mask[current_position] = 0; + if (mask->image[y+1][x] == 0) { + new_mask->image[y][x] = 0; continue; } } } } - return new_mask; + MaskData_t *ret_mask = new_mask->image[0]; + free(new_mask->image); + free(new_mask); + return ret_mask; } // Erode masks by one 4-connected pixel -void erode(MaskData_t** mask, uint32_t width, uint32_t height) +void erode(Mask* mask) { - MaskData_t *new_mask = _erode(*mask, width, height); + MaskData_t *new_mask = _erode(mask); if (new_mask != NULL) { - free(*mask); - *mask = new_mask; + free(mask->image[0]); + for (size_t y = 0; y < mask->height; y++) { + mask->image[y] = &(new_mask[y*mask->width]); + } } } // Close up masks by N-pixels -MaskData_t* _closeup(MaskData_t* mask, uint32_t width, uint32_t height, size_t num_pixels) +MaskData_t* _closeup(Mask* mask, size_t num_pixels) { - MaskData_t *new_mask = (MaskData_t*)calloc(width*height,sizeof(MaskData_t)); - memcpy(new_mask, mask, width*height*sizeof(MaskData_t)); + Mask *new_mask = create_image_mask(mask->width, mask->height); + memcpy(new_mask->image[0], mask->image[0], + mask->width * mask->height * sizeof(MaskData_t)); for (size_t count = 0; count < num_pixels; count++) { - dilate(&new_mask, width, height); + dilate(mask); } for (size_t count = 0; count < num_pixels; count++) { - erode(&new_mask, width, height); - } - // Retain original mask at the very least - for (size_t y = 0; y < height; y++) { - for (size_t x = 0; x < width; x++) { - size_t coord = x + y*width; - if (mask[coord] != 0) { - if (new_mask[coord] != mask[coord]) { - new_mask[coord] = mask[coord]; - } + erode(mask); + } + for (size_t y = 0; y < mask->height; y++) { + for (size_t x = 0; x < mask->width; x++) { + if (mask->image[y][x] != 0) { + if (new_mask->image[y][x] != mask->image[y][x]) { + new_mask->image[y][x] = mask->image[y][x]; + } } } } - return new_mask; + MaskData_t *ret_mask = new_mask->image[0]; + free(new_mask->image); + free(new_mask); + return ret_mask; } // Close up masks by N-pixels // Update pointer -void closeup(MaskData_t** mask, uint32_t width, uint32_t height, size_t num_pixels) +void closeup(Mask* mask, size_t num_pixels) { - MaskData_t *new_mask = _closeup(*mask, width, height, num_pixels); + MaskData_t *new_mask = _closeup(mask, num_pixels); if (new_mask != NULL) { - free(*mask); - *mask = new_mask; + free(mask->image[0]); + for (size_t y = 0; y < mask->height; y++) { + mask->image[y] = &(new_mask[y*mask->width]); + } } } @@ -220,8 +214,10 @@ Mask* combine_masks(Mask *destination, Mask *extra_labels) // Process Tif File to Labels // width, height will be overwritten with image dimensions // starting_label_p will be incremented for each label found in the image -Mask* tif_to_labels(char* tif_file_name, uint32_t *width, uint32_t *height, MaskData_t *starting_label_p) +Mask *tif_to_labels(char *tif_file_name, MaskData_t *starting_label_p) { + uint32_t width = 0; + uint32_t height = 0; TIFFSetWarningHandler(TiffDummyHandler); //-TIFF-IMAGE-OPEN------------------------------- TIFF *tif = TIFFOpen(tif_file_name, "r"); @@ -231,17 +227,13 @@ Mask* tif_to_labels(char* tif_file_name, uint32_t *width, uint32_t *height, Mask } //-TIFF-FIND-DIMENSIONS-------------------------- - size_t channels = 1; - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, width); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, height); + size_t channels; + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); tmsize_t STRIP_LENGTH = TIFFStripSize(tif); tmsize_t STRIP_COUNT = TIFFNumberOfStrips(tif); - if ((*width)*(*height)*3 == STRIP_LENGTH*STRIP_COUNT) { - channels = 3; - } else if ((*width)*(*height)*4 == STRIP_LENGTH*STRIP_COUNT) { - channels = 4; - } + channels = (STRIP_LENGTH*STRIP_COUNT)/(width*height); //-TIFF-LOAD-DATA-------------------------------- void* buffer = malloc(STRIP_LENGTH*sizeof(ImageData_t)); @@ -250,8 +242,8 @@ Mask* tif_to_labels(char* tif_file_name, uint32_t *width, uint32_t *height, Mask TIFFClose(tif); return NULL; } - ImageData_t* image_data = calloc((*width)*(*height)*channels,sizeof(ImageData_t)); - if (image_data == NULL) { + Image *image = create_image(width, height, channels); + if (image == NULL) { fprintf(stderr, "Memory allocation error\n"); free(buffer); TIFFClose(tif); @@ -261,55 +253,30 @@ Mask* tif_to_labels(char* tif_file_name, uint32_t *width, uint32_t *height, Mask tmsize_t strip_size = TIFFReadRawStrip(tif, y, buffer, STRIP_LENGTH); assert(strip_size == STRIP_LENGTH); for (size_t x = 0; x < STRIP_LENGTH; x++) { - image_data[x + y*STRIP_LENGTH] = ((ImageData_t*)buffer)[x]; + image->image[0][0][x + y*STRIP_LENGTH] = ((ImageData_t*)buffer)[x]; } } free(buffer); //-FLOOD-FILL-SEGMENTATION----------------------- //-CONTIGUOUS-REGION-FINDING--------------------- - Mask *im_data = create_image_mask((size_t)*width, (size_t)*height); + Mask *im_data = create_image_mask((size_t)width, (size_t)height); if (im_data == NULL) { fprintf(stderr, "Memory allocation error\n"); - free(image_data); + free_image(image); TIFFClose(tif); return NULL; } - if (im_data->image == NULL) { - fprintf(stderr, "Memory allocation error\n"); - free_image_mask(im_data); - free(image_data); - TIFFClose(tif); - return NULL; - } - if (im_data->image[0] == NULL) { - fprintf(stderr, "Memory allocation error\n"); - free_image_mask(im_data); - free(image_data); - TIFFClose(tif); - return NULL; - } - MaskData_t *labels = im_data->image[0]; - /* - labels = (MaskData_t*)calloc((*width)*(*height),sizeof(MaskData_t)); - if (labels == NULL) { - fprintf(stderr, "Memory allocation error\n"); - free(image_data); - TIFFClose(tif); - return NULL; - } - */ // Flood fill on each pixel // Increase label for each success - for (size_t y = 0; y < *height; y++) { - for (size_t x = 0; x < *width; x++) { - size_t coord = x + y*(*width); - if(flood(image_data, labels, *width, *height, channels, x, y, &(image_data[coord*channels]), *starting_label_p)) { + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < width; x++) { + if(flood(image->image[0][0], im_data->image[0], width, height, channels, x, y, image->image[y][x], *starting_label_p)) { *starting_label_p += 1; } } } - free(image_data); + free_image(image); TIFFClose(tif); return im_data; //return labels; @@ -370,14 +337,16 @@ MaskData_t* _reduce_contiguous_regions(MaskData_t* masks, uint32_t width, uint32 // Reduce a mask to the contiguous regions // Automatically update pointer to contiguous mask // Freeing previous mask -void reduce_contiguous_regions(MaskData_t** masks_p, uint32_t width, uint32_t height, MaskData_t* total_labels) +void reduce_contiguous_regions(Mask* mask, MaskData_t* total_labels) { - if (masks_p == NULL) { + if (mask == NULL) { return; } - MaskData_t* new_masks = _reduce_contiguous_regions(*masks_p, width, height, total_labels); + MaskData_t* new_masks = _reduce_contiguous_regions(mask->image[0], mask->width, mask->height, total_labels); if (new_masks != NULL) { - free(*masks_p); - *masks_p = new_masks; + free(mask->image[0]); + for (size_t y = 0; y < mask->height; y++) { + mask->image[y] = &new_masks[y*mask->width]; + } } } |