From a2161afe21706d747d457f97553edb10efdeabe3 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sat, 12 May 2012 13:37:44 +0200 Subject: [PATCH 01/84] unwrap: initial commit --- ...apper_with_mask_and_wrap_around_option.cpp | 743 ++++++++++++++++++ 1 file changed, 743 insertions(+) create mode 100755 unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp new file mode 100755 index 00000000..88bdcab6 --- /dev/null +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp @@ -0,0 +1,743 @@ +//This program was written by Munther Gdeisat and Miguel Arevallilo Herra´ez to program the two-dimensional unwrapper +//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by +//reliability following a noncontinuous path" +//by Miguel Arevallilo Herra´ez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat +//published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. +//This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. +//Date 26th August 2007 +//The wrapped phase map is assumed to be of floating point data type. The resultant unwrapped phase map is also of floating point type. +//The mask is of byte data type. +//When the mask is 255 this means that the pixel is valid +//When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) +//This program takes into consideration the image wrap around problem encountered in MRI imaging. +#include +//#include "stdafx.h" +#include +#include +#include + +static float PI = 3.141592654; +static float TWOPI = 6.283185307; +int x_connectivity = 1; +int y_connectivity = 1; +int No_of_edges = 0; + +//PIXELM information +struct PIXELM +{ + //int x; //x coordinate of the pixel + //int y; //y coordinate + int increment; //No. of 2*pi to add to the pixel to unwrap it + int number_of_pixels_in_group; //No. of pixel in the pixel group + float value; //value of the pixel + float reliability; + unsigned char input_mask; //0 pixel is masked. 255 pixel is not masked + unsigned char extended_mask; //0 pixel is masked. 255 pixel is not masked + int group; //group No. + int new_group; + struct PIXELM *head; //pointer to the first pixel in the group in the linked list + struct PIXELM *last; //pointer to the last pixel in the group + struct PIXELM *next; //pointer to the next pixel in the group +}; + + +//the EDGE is the line that connects two pixels. +//if we have S pixels, then we have S horizontal edges and S vertical edges +struct EDGE +{ + float reliab; //reliabilty of the edge and it depends on the two pixels + PIXELM *pointer_1; //pointer to the first pixel + PIXELM *pointer_2; //pointer to the second pixel + int increment; //No. of 2*pi to add to one of the pixels to unwrap it with respect to the second +}; + +void read_data(char *inputfile,float *Data, int length) +{ + printf("Reading the Wrapped Values from Binary File.............>"); + FILE *ifptr; + ifptr = fopen(inputfile,"rb"); + if(ifptr == NULL) printf("Error opening the file\n"); + fread(Data,sizeof(float),length,ifptr); + fclose(ifptr); + printf(" Done.\n"); +} + +void write_data(char *outputfile,float *Data,int length) +{ + printf("Writing the Wrapped Values to Binary File.............>"); + FILE *ifptr; + ifptr = fopen(outputfile,"wb"); + if(ifptr == NULL) printf("Error opening the file\n"); + fwrite(Data,sizeof(float),length,ifptr); + fclose(ifptr); + printf(" Done.\n"); +} + +void read_mask(char *inputfile,unsigned char *Data, int length) +{ + printf("Reading the mask frpm Binary File.............>"); + FILE *ifptr; + ifptr = fopen(inputfile,"rb"); + if(ifptr == NULL) printf("Error opening the file\n"); + fread(Data,sizeof(char),length,ifptr); + fclose(ifptr); + printf(" Done.\n"); +} +//---------------start quicker_sort algorithm -------------------------------- +#define swap(x,y) {EDGE t; t=x; x=y; y=t;} +#define order(x,y) if (x.reliab > y.reliab) swap(x,y) +#define o2(x,y) order(x,y) +#define o3(x,y,z) o2(x,y); o2(x,z); o2(y,z) + +typedef enum {yes, no} yes_no; + +yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) +{ + EDGE a, b, c, *p; + + a = *left; + b = *(left + (right - left) /2 ); + c = *right; + o3(a,b,c); + + if (a.reliab < b.reliab) + { + *pivot_ptr = b.reliab; + return yes; + } + + if (b.reliab < c.reliab) + { + *pivot_ptr = c.reliab; + return yes; + } + + for (p = left + 1; p <= right; ++p) + { + if (p->reliab != left->reliab) + { + *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; + return yes; + } + return no; + } +} + +EDGE *partition(EDGE *left, EDGE *right, float pivot) +{ + while (left <= right) + { + while (left->reliab < pivot) + ++left; + while (right->reliab >= pivot) + --right; + if (left < right) + { + swap (*left, *right); + ++left; + --right; + } + } + return left; +} + +void quicker_sort(EDGE *left, EDGE *right) +{ + EDGE *p; + float pivot; + + if (find_pivot(left, right, &pivot) == yes) + { + p = partition(left, right, pivot); + quicker_sort(left, p - 1); + quicker_sort(p, right); + } +} + +//--------------end quicker_sort algorithm ----------------------------------- + +//--------------------start initialse pixels ---------------------------------- +//initialse pixels. See the explination of the pixel class above. +//initially every pixel is assumed to belong to a group consisting of only itself +void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) +{ + PIXELM *pixel_pointer = pixel; + float *wrapped_image_pointer = WrappedImage; + unsigned char *input_mask_pointer = input_mask; + unsigned char *extended_mask_pointer = extended_mask; + int i, j; + + for (i=0; i < image_height; i++) + { + for (j=0; j < image_width; j++) + { + //pixel_pointer->x = j; + //pixel_pointer->y = i; + pixel_pointer->increment = 0; + pixel_pointer->number_of_pixels_in_group = 1; + pixel_pointer->value = *wrapped_image_pointer; + pixel_pointer->reliability = 9999999 + rand(); + pixel_pointer->input_mask = *input_mask_pointer; + pixel_pointer->extended_mask = *extended_mask_pointer; + pixel_pointer->head = pixel_pointer; + pixel_pointer->last = pixel_pointer; + pixel_pointer->next = NULL; + pixel_pointer->new_group = 0; + pixel_pointer->group = -1; + pixel_pointer++; + wrapped_image_pointer++; + input_mask_pointer++; + extended_mask_pointer++; + } + } +} +//-------------------end initialise pixels ----------- + +//gamma function in the paper +float wrap(float pixel_value) +{ + float wrapped_pixel_value; + if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; + else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; + else wrapped_pixel_value = pixel_value; + return wrapped_pixel_value; +} + +// pixelL_value is the left pixel, pixelR_value is the right pixel +int find_wrap(float pixelL_value, float pixelR_value) +{ + float difference; + int wrap_value; + difference = pixelL_value - pixelR_value; + + if (difference > PI) wrap_value = -1; + else if (difference < -PI) wrap_value = 1; + else wrap_value = 0; + + return wrap_value; +} + +void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int image_width, int image_height) +{ + int i,j; + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + unsigned char *IMP = input_mask + image_width + 1; //input mask pointer + unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer + + //extend the mask for the image except borders + for (i=1; i < image_height - 1; ++i) + { + for (j=1; j < image_width - 1; ++j) + { + if ( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width_minus_one) == 255) && (*(IMP - image_width_plus_one) == 255) && + (*(IMP + image_width_minus_one) == 255) && (*(IMP + image_width_plus_one) == 255) ) + { + *EMP = 255; + } + ++EMP; + ++IMP; + } + EMP += 2; + IMP += 2; + } + + if (x_connectivity == 1) + { + //extend the mask for the right border of the image + IMP = input_mask + 2 * image_width - 1; + EMP = extended_mask + 2 * image_width -1; + for (i=1; i < image_height - 1; ++ i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && + (*(IMP + image_width - 1) == 255) && (*(IMP - 2 * image_width + 1) == 255) ) + { + *EMP = 255; + } + EMP += image_width; + IMP += image_width; + } + + //extend the mask for the left border of the image + IMP = input_mask + image_width; + EMP = extended_mask + image_width; + for (i=1; i < image_height - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width + 1) == 255) && (*(IMP + image_width + 1) == 255) && + (*(IMP + image_width - 1) == 255) && (*(IMP + 2 * image_width - 1) == 255) ) + { + *EMP = 255; + } + EMP += image_width; + IMP += image_width; + } + } + + if (y_connectivity == 1) + { + //extend the mask for the top border of the image + IMP = input_mask + 1; + EMP = extended_mask + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP + image_width * (image_height - 1)) == 255) && + (*(IMP + image_width + 1) == 255) && (*(IMP + image_width - 1) == 255) && + (*(IMP + image_width * (image_height - 1) - 1) == 255) && (*(IMP + image_width * (image_height - 1) + 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + + //extend the mask for the bottom border of the image + IMP = input_mask + image_width * (image_height - 1) + 1; + EMP = extended_mask + image_width * (image_height - 1) + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP - image_width) == 255) && (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && + (*(IMP - image_width * (image_height - 1) ) == 255) && + (*(IMP - image_width * (image_height - 1) - 1) == 255) && + (*(IMP - image_width * (image_height - 1) + 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + } +} + +void calculate_reliability(float *wrappedImage, PIXELM *pixel, int image_width, int image_height) +{ + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + PIXELM *pixel_pointer = pixel + image_width_plus_one; + float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer + float H, V, D1, D2; + int i, j; + + for (i = 1; i < image_height -1; ++i) + { + for (j = 1; j < image_width - 1; ++j) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + pixel_pointer += 2; + WIP += 2; + } + + if (x_connectivity == 1) + { + //calculating the reliability for the left border of the image + PIXELM *pixel_pointer = pixel + image_width; + float *WIP = wrappedImage + image_width; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + + //calculating the reliability for the right border of the image + pixel_pointer = pixel + 2 * image_width - 1; + WIP = wrappedImage + 2 * image_width - 1; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); + D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + } + + if (y_connectivity == 1) + { + //calculating the reliability for the top border of the image + PIXELM *pixel_pointer = pixel + 1; + float *WIP = wrappedImage + 1; + + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + + //calculating the reliability for the bottom border of the image + pixel_pointer = pixel + (image_height - 1) * image_width + 1; + WIP = wrappedImage + (image_height - 1) * image_width + 1; + + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + } +} + +//calculate the reliability of the horizontal edges of the image +//it is calculated by adding the reliability of pixel and the relibility of +//its right-hand neighbour +//edge is calculated between a pixel and its next neighbour +void horizontalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height) +{ + int i, j; + EDGE *edge_pointer = edge; + PIXELM *pixel_pointer = pixel; + + for (i = 0; i < image_height; i++) + { + for (j = 0; j < image_width - 1; j++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer + 1)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer+1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } + pixel_pointer++; + } + //construct edges at the right border of the image + if (x_connectivity == 1) + { + pixel_pointer = pixel + image_width - 1; + for (i = 0; i < image_height; i++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width + 1)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer+=image_width; + } + } +} + +//calculate the reliability of the vertical edges of the image +//it is calculated by adding the reliability of pixel and the relibility of +//its lower neighbour in the image. +void verticalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height) +{ + int i, j; + PIXELM *pixel_pointer = pixel; + EDGE *edge_pointer = edge + No_of_edges; + + for (i=0; i < image_height - 1; i++) + { + for (j=0; j < image_width; j++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer + image_width)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer + image_width); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } //j loop + } // i loop + + //construct edges that connect at the bottom border of the image + if (y_connectivity == 1) + { + pixel_pointer = pixel + image_width *(image_height - 1); + for (i = 0; i < image_width; i++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width *(image_height - 1))->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } + } +} + +//gather the pixels of the image into groups +void gatherPIXELs(EDGE *edge, int image_width, int image_height) +{ + int k; + PIXELM *PIXEL1; + PIXELM *PIXEL2; + PIXELM *group1; + PIXELM *group2; + EDGE *pointer_edge = edge; + int incremento; + + for (k = 0; k < No_of_edges; k++) + { + PIXEL1 = pointer_edge->pointer_1; + PIXEL2 = pointer_edge->pointer_2; + + //PIXELM 1 and PIXELM 2 belong to different groups + //initially each pixel is a group by it self and one pixel can construct a group + //no else or else if to this if + if (PIXEL2->head != PIXEL1->head) + { + //PIXELM 2 is alone in its group + //merge this pixel with PIXELM 1 group and find the number of 2 pi to add + //to or subtract to unwrap it + if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) + { + PIXEL1->head->last->next = PIXEL2; + PIXEL1->head->last = PIXEL2; + (PIXEL1->head->number_of_pixels_in_group)++; + PIXEL2->head=PIXEL1->head; + PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; + } + + //PIXELM 1 is alone in its group + //merge this pixel with PIXELM 2 group and find the number of 2 pi to add + //to or subtract to unwrap it + else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) + { + PIXEL2->head->last->next = PIXEL1; + PIXEL2->head->last = PIXEL1; + (PIXEL2->head->number_of_pixels_in_group)++; + PIXEL1->head = PIXEL2->head; + PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; + } + + //PIXELM 1 and PIXELM 2 both have groups + else + { + group1 = PIXEL1->head; + group2 = PIXEL2->head; + //if the no. of pixels in PIXELM 1 group is larger than the no. of pixels + //in PIXELM 2 group. Merge PIXELM 2 group to PIXELM 1 group + //and find the number of wraps between PIXELM 2 group and PIXELM 1 group + //to unwrap PIXELM 2 group with respect to PIXELM 1 group. + //the no. of wraps will be added to PIXELM 2 grop in the future + if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) + { + //merge PIXELM 2 with PIXELM 1 group + group1->last->next = group2; + group1->last = group2->last; + group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; + incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group2 != NULL) + { + group2->head = group1; + group2->increment += incremento; + group2 = group2->next; + } + } + + //if the no. of pixels in PIXELM 2 group is larger than the no. of pixels + //in PIXELM 1 group. Merge PIXELM 1 group to PIXELM 2 group + //and find the number of wraps between PIXELM 2 group and PIXELM 1 group + //to unwrap PIXELM 1 group with respect to PIXELM 2 group. + //the no. of wraps will be added to PIXELM 1 grop in the future + else + { + //merge PIXELM 1 with PIXELM 2 group + group2->last->next = group1; + group2->last = group1->last; + group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; + incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group1 != NULL) + { + group1->head = group2; + group1->increment += incremento; + group1 = group1->next; + } // while + + } // else + } //else + } //if + pointer_edge++; + } +} + +//unwrap the image +void unwrapImage(PIXELM *pixel, int image_width, int image_height) +{ + int i; + int image_size = image_width * image_height; + PIXELM *pixel_pointer=pixel; + + for (i = 0; i < image_size; i++) + { + pixel_pointer->value += TWOPI * (float)(pixel_pointer->increment); + pixel_pointer++; + } +} + +//set the masked pixels (mask = 0) to the minimum of the unwrapper phase +void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int image_height) +{ + int image_width_plus_one = image_width + 1; + int image_height_plus_one = image_height + 1; + int image_width_minus_one = image_width - 1; + int image_height_minus_one = image_height - 1; + + PIXELM *pointer_pixel = pixel; + unsigned char *IMP = input_mask; //input mask pointer + float min=99999999.; + int i, j; + int image_size = image_width * image_height; + + //find the minimum of the unwrapped phase + for (i = 0; i < image_size; i++) + { + if ((pointer_pixel->value < min) && (*IMP == 255)) + min = pointer_pixel->value; + + pointer_pixel++; + IMP++; + } + + pointer_pixel = pixel; + IMP = input_mask; + + //set the masked pixels to minimum + for (i = 0; i < image_size; i++) + { + if ((*IMP) == 0) + { + pointer_pixel->value = min; + } + pointer_pixel++; + IMP++; + } +} + +//the input to this unwrapper is an array that contains the wrapped phase map. +//copy the image on the buffer passed to this unwrapper to over-write the unwrapped +//phase map on the buffer of the wrapped phase map. +void returnImage(PIXELM *pixel, float *unwrappedImage, int image_width, int image_height) +{ + int i; + int image_size = image_width * image_height; + float *unwrappedImage_pointer = unwrappedImage; + PIXELM *pixel_pointer = pixel; + + for (i=0; i < image_size; i++) + { + *unwrappedImage_pointer = pixel_pointer->value; + pixel_pointer++; + unwrappedImage_pointer++; + } +} + +//the main function of the unwrapper +int main() +{ + float *WrappedImage, *UnwrappedImage; + unsigned char *input_mask, *extended_mask; + int image_width = 64; + int image_height = 64; + int i, j; + int image_size = image_height * image_width; + int No_of_Edges_initially = (image_width)*(image_height) + (image_width)*(image_height); + + WrappedImage = (float *) calloc(image_size, sizeof(float)); + read_data("wrapped phase slice 64X64.dat", WrappedImage, image_size); + + input_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); + extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); + read_mask("mask 64X64.dat", input_mask, image_size); + + UnwrappedImage = (float *) calloc(image_size, sizeof(float)); + PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); + EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; + + extend_mask(input_mask, extended_mask, image_width, image_height); + + initialisePIXELs(WrappedImage, input_mask, extended_mask, pixel, image_width, image_height); + + calculate_reliability(WrappedImage, pixel, image_width, image_height); + + horizontalEDGEs(pixel, edge, image_width, image_height); + + verticalEDGEs(pixel, edge, image_width, image_height); + + //sort the EDGEs depending on their reiability. The PIXELs with higher relibility (small value) first + quicker_sort(edge, edge + No_of_edges - 1); + + //gather PIXELs into groups + gatherPIXELs(edge, image_width, image_height); + + unwrapImage(pixel, image_width, image_height); + + maskImage(pixel, input_mask, image_width, image_height); + + //copy the image from PIXELM structure to the unwrapped phase array passed to this function + returnImage(pixel, UnwrappedImage, image_width, image_height); + + free(edge); + free(pixel); + + write_data("unwrapped.dat", UnwrappedImage, image_size); + free(UnwrappedImage); + free(WrappedImage); + free(input_mask); + free(extended_mask); + + return 1; +} From 9c58dd5d0bf0ac9f6e63cdbed6db6924e5f9faee Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sat, 12 May 2012 19:27:12 +0200 Subject: [PATCH 02/84] unwrap: compiles, test passes --- punwrap2D/setup.py | 16 + ...wrapper_with_mask_and_wrap_around_option.c | 703 ++++++++++++++++++ unwrap2D/setup.py | 26 + unwrap2D/test_unwrap.py | 47 ++ unwrap2D/unwrap2D.pyx | 17 + 5 files changed, 809 insertions(+) create mode 100755 punwrap2D/setup.py create mode 100644 unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c create mode 100644 unwrap2D/setup.py create mode 100644 unwrap2D/test_unwrap.py create mode 100644 unwrap2D/unwrap2D.pyx diff --git a/punwrap2D/setup.py b/punwrap2D/setup.py new file mode 100755 index 00000000..9a236dfc --- /dev/null +++ b/punwrap2D/setup.py @@ -0,0 +1,16 @@ +from distutils.core import setup +from distutils.extension import Extension +import numpy as np + +ext_modules = [ + Extension('_punwrap2D', + ['unwrap_phase.c', 'Munther_2D_unwrap.c'], + include_dirs = [np.get_include(),], + #libraries = ['unwrap2D'], + ), + ] + +setup( + name = 'punwrap', + ext_modules = ext_modules, + ) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c new file mode 100644 index 00000000..a77fb98a --- /dev/null +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -0,0 +1,703 @@ +// 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer + +//This program was written by Munther Gdeisat and Miguel Arevallilo Herra´ez to program the two-dimensional unwrapper +//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by +//reliability following a noncontinuous path" +//by Miguel Arevallilo Herra´ez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat +//published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. +//This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. +//Date 26th August 2007 +//The wrapped phase map is assumed to be of floating point data type. The resultant unwrapped phase map is also of floating point type. +//The mask is of byte data type. +//When the mask is 255 this means that the pixel is valid +//When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) +//This program takes into consideration the image wrap around problem encountered in MRI imaging. + +//TODO stdlib instead of malloc.h ? (calloc?) +#include +#include +#include + +//TODO: remove global variables +//TODO: make thresholds independent + +static float PI = 3.141592654; +static float TWOPI = 6.283185307; + + +int x_connectivity = 1; +int y_connectivity = 1; +int No_of_edges = 0; + +//PIXELM information +struct pixelm +{ + int increment; //No. of 2*pi to add to the pixel to unwrap it + int number_of_pixels_in_group; //No. of pixel in the pixel group + float value; //value of the pixel + float reliability; + unsigned char input_mask; //0 pixel is masked. 255 pixel is not masked + unsigned char extended_mask; //0 pixel is masked. 255 pixel is not masked + int group; //group No. + int new_group; + struct pixelm *head; //pointer to the first pixel in the group in the linked list + struct pixelm *last; //pointer to the last pixel in the group + struct pixelm *next; //pointer to the next pixel in the group +}; + +typedef struct pixelm PIXELM; + + +//the EDGE is the line that connects two pixels. +//if we have S pixels, then we have S horizontal edges and S vertical edges +struct edge +{ + float reliab; //reliabilty of the edge and it depends on the two pixels + struct PIXELM *pointer_1; //pointer to the first pixel + struct PIXELM *pointer_2; //pointer to the second pixel + int increment; //No. of 2*pi to add to one of the pixels to unwrap it with respect to the second +}; + +typedef struct edge EDGE; + +//---------------start quicker_sort algorithm -------------------------------- +#define swap(x,y) {EDGE t; t=x; x=y; y=t;} +#define order(x,y) if (x.reliab > y.reliab) swap(x,y) +#define o2(x,y) order(x,y) +#define o3(x,y,z) o2(x,y); o2(x,z); o2(y,z) + +typedef enum {yes, no} yes_no; + +yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) +{ + EDGE a, b, c, *p; + + a = *left; + b = *(left + (right - left) /2 ); + c = *right; + o3(a,b,c); + + if (a.reliab < b.reliab) + { + *pivot_ptr = b.reliab; + return yes; + } + + if (b.reliab < c.reliab) + { + *pivot_ptr = c.reliab; + return yes; + } + + for (p = left + 1; p <= right; ++p) + { + if (p->reliab != left->reliab) + { + *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; + return yes; + } + return no; + } +} + +EDGE *partition(EDGE *left, EDGE *right, float pivot) +{ + while (left <= right) + { + while (left->reliab < pivot) + ++left; + while (right->reliab >= pivot) + --right; + if (left < right) + { + swap (*left, *right); + ++left; + --right; + } + } + return left; +} + +void quicker_sort(EDGE *left, EDGE *right) +{ + EDGE *p; + float pivot; + + if (find_pivot(left, right, &pivot) == yes) + { + p = partition(left, right, pivot); + quicker_sort(left, p - 1); + quicker_sort(p, right); + } +} + +//--------------end quicker_sort algorithm ----------------------------------- + +//--------------------start initialse pixels ---------------------------------- +//initialse pixels. See the explination of the pixel class above. +//initially every pixel is assumed to belong to a group consisting of only itself +void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) +{ + PIXELM *pixel_pointer = pixel; + float *wrapped_image_pointer = WrappedImage; + unsigned char *input_mask_pointer = input_mask; + unsigned char *extended_mask_pointer = extended_mask; + int i, j; + + for (i=0; i < image_height; i++) + { + for (j=0; j < image_width; j++) + { + //pixel_pointer->x = j; + //pixel_pointer->y = i; + pixel_pointer->increment = 0; + pixel_pointer->number_of_pixels_in_group = 1; + pixel_pointer->value = *wrapped_image_pointer; + pixel_pointer->reliability = 9999999 + rand(); + pixel_pointer->input_mask = *input_mask_pointer; + pixel_pointer->extended_mask = *extended_mask_pointer; + pixel_pointer->head = pixel_pointer; + pixel_pointer->last = pixel_pointer; + pixel_pointer->next = NULL; + pixel_pointer->new_group = 0; + pixel_pointer->group = -1; + pixel_pointer++; + wrapped_image_pointer++; + input_mask_pointer++; + extended_mask_pointer++; + } + } +} +//-------------------end initialise pixels ----------- + +//gamma function in the paper +float wrap(float pixel_value) +{ + float wrapped_pixel_value; + if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; + else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; + else wrapped_pixel_value = pixel_value; + return wrapped_pixel_value; +} + +// pixelL_value is the left pixel, pixelR_value is the right pixel +int find_wrap(float pixelL_value, float pixelR_value) +{ + float difference; + int wrap_value; + difference = pixelL_value - pixelR_value; + + if (difference > PI) wrap_value = -1; + else if (difference < -PI) wrap_value = 1; + else wrap_value = 0; + + return wrap_value; +} + +void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int image_width, int image_height) +{ + int i,j; + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + unsigned char *IMP = input_mask + image_width + 1; //input mask pointer + unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer + + //extend the mask for the image except borders + for (i=1; i < image_height - 1; ++i) + { + for (j=1; j < image_width - 1; ++j) + { + if ( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width_minus_one) == 255) && (*(IMP - image_width_plus_one) == 255) && + (*(IMP + image_width_minus_one) == 255) && (*(IMP + image_width_plus_one) == 255) ) + { + *EMP = 255; + } + ++EMP; + ++IMP; + } + EMP += 2; + IMP += 2; + } + + if (x_connectivity == 1) + { + //extend the mask for the right border of the image + IMP = input_mask + 2 * image_width - 1; + EMP = extended_mask + 2 * image_width -1; + for (i=1; i < image_height - 1; ++ i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && + (*(IMP + image_width - 1) == 255) && (*(IMP - 2 * image_width + 1) == 255) ) + { + *EMP = 255; + } + EMP += image_width; + IMP += image_width; + } + + //extend the mask for the left border of the image + IMP = input_mask + image_width; + EMP = extended_mask + image_width; + for (i=1; i < image_height - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width + 1) == 255) && (*(IMP + image_width + 1) == 255) && + (*(IMP + image_width - 1) == 255) && (*(IMP + 2 * image_width - 1) == 255) ) + { + *EMP = 255; + } + EMP += image_width; + IMP += image_width; + } + } + + if (y_connectivity == 1) + { + //extend the mask for the top border of the image + IMP = input_mask + 1; + EMP = extended_mask + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP + image_width * (image_height - 1)) == 255) && + (*(IMP + image_width + 1) == 255) && (*(IMP + image_width - 1) == 255) && + (*(IMP + image_width * (image_height - 1) - 1) == 255) && (*(IMP + image_width * (image_height - 1) + 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + + //extend the mask for the bottom border of the image + IMP = input_mask + image_width * (image_height - 1) + 1; + EMP = extended_mask + image_width * (image_height - 1) + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP - image_width) == 255) && (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && + (*(IMP - image_width * (image_height - 1) ) == 255) && + (*(IMP - image_width * (image_height - 1) - 1) == 255) && + (*(IMP - image_width * (image_height - 1) + 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + } +} + +void calculate_reliability(float *wrappedImage, PIXELM *pixel, int image_width, int image_height) +{ + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + PIXELM *pixel_pointer = pixel + image_width_plus_one; + float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer + float H, V, D1, D2; + int i, j; + + for (i = 1; i < image_height -1; ++i) + { + for (j = 1; j < image_width - 1; ++j) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + pixel_pointer += 2; + WIP += 2; + } + + if (x_connectivity == 1) + { + //calculating the reliability for the left border of the image + PIXELM *pixel_pointer = pixel + image_width; + float *WIP = wrappedImage + image_width; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + + //calculating the reliability for the right border of the image + pixel_pointer = pixel + 2 * image_width - 1; + WIP = wrappedImage + 2 * image_width - 1; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); + D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + } + + if (y_connectivity == 1) + { + //calculating the reliability for the top border of the image + PIXELM *pixel_pointer = pixel + 1; + float *WIP = wrappedImage + 1; + + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + + //calculating the reliability for the bottom border of the image + pixel_pointer = pixel + (image_height - 1) * image_width + 1; + WIP = wrappedImage + (image_height - 1) * image_width + 1; + + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + } +} + +//calculate the reliability of the horizontal edges of the image +//it is calculated by adding the reliability of pixel and the relibility of +//its right-hand neighbour +//edge is calculated between a pixel and its next neighbour +void horizontalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height) +{ + int i, j; + EDGE *edge_pointer = edge; + PIXELM *pixel_pointer = pixel; + + for (i = 0; i < image_height; i++) + { + for (j = 0; j < image_width - 1; j++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer + 1)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer+1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } + pixel_pointer++; + } + //construct edges at the right border of the image + if (x_connectivity == 1) + { + pixel_pointer = pixel + image_width - 1; + for (i = 0; i < image_height; i++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width + 1)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer+=image_width; + } + } +} + +//calculate the reliability of the vertical edges of the image +//it is calculated by adding the reliability of pixel and the relibility of +//its lower neighbour in the image. +void verticalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height) +{ + int i, j; + PIXELM *pixel_pointer = pixel; + EDGE *edge_pointer = edge + No_of_edges; + + for (i=0; i < image_height - 1; i++) + { + for (j=0; j < image_width; j++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer + image_width)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer + image_width); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } //j loop + } // i loop + + //construct edges that connect at the bottom border of the image + if (y_connectivity == 1) + { + pixel_pointer = pixel + image_width *(image_height - 1); + for (i = 0; i < image_width; i++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width *(image_height - 1))->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } + } +} + +//gather the pixels of the image into groups +void gatherPIXELs(EDGE *edge, int image_width, int image_height) +{ + int k; + PIXELM *PIXEL1; + PIXELM *PIXEL2; + PIXELM *group1; + PIXELM *group2; + EDGE *pointer_edge = edge; + int incremento; + + for (k = 0; k < No_of_edges; k++) + { + PIXEL1 = pointer_edge->pointer_1; + PIXEL2 = pointer_edge->pointer_2; + + //PIXELM 1 and PIXELM 2 belong to different groups + //initially each pixel is a group by it self and one pixel can construct a group + //no else or else if to this if + if (PIXEL2->head != PIXEL1->head) + { + //PIXELM 2 is alone in its group + //merge this pixel with PIXELM 1 group and find the number of 2 pi to add + //to or subtract to unwrap it + if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) + { + PIXEL1->head->last->next = PIXEL2; + PIXEL1->head->last = PIXEL2; + (PIXEL1->head->number_of_pixels_in_group)++; + PIXEL2->head=PIXEL1->head; + PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; + } + + //PIXELM 1 is alone in its group + //merge this pixel with PIXELM 2 group and find the number of 2 pi to add + //to or subtract to unwrap it + else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) + { + PIXEL2->head->last->next = PIXEL1; + PIXEL2->head->last = PIXEL1; + (PIXEL2->head->number_of_pixels_in_group)++; + PIXEL1->head = PIXEL2->head; + PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; + } + + //PIXELM 1 and PIXELM 2 both have groups + else + { + group1 = PIXEL1->head; + group2 = PIXEL2->head; + //if the no. of pixels in PIXELM 1 group is larger than the no. of pixels + //in PIXELM 2 group. Merge PIXELM 2 group to PIXELM 1 group + //and find the number of wraps between PIXELM 2 group and PIXELM 1 group + //to unwrap PIXELM 2 group with respect to PIXELM 1 group. + //the no. of wraps will be added to PIXELM 2 grop in the future + if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) + { + //merge PIXELM 2 with PIXELM 1 group + group1->last->next = group2; + group1->last = group2->last; + group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; + incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group2 != NULL) + { + group2->head = group1; + group2->increment += incremento; + group2 = group2->next; + } + } + + //if the no. of pixels in PIXELM 2 group is larger than the no. of pixels + //in PIXELM 1 group. Merge PIXELM 1 group to PIXELM 2 group + //and find the number of wraps between PIXELM 2 group and PIXELM 1 group + //to unwrap PIXELM 1 group with respect to PIXELM 2 group. + //the no. of wraps will be added to PIXELM 1 grop in the future + else + { + //merge PIXELM 1 with PIXELM 2 group + group2->last->next = group1; + group2->last = group1->last; + group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; + incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group1 != NULL) + { + group1->head = group2; + group1->increment += incremento; + group1 = group1->next; + } // while + + } // else + } //else + } //if + pointer_edge++; + } +} + +//unwrap the image +void unwrapImage(PIXELM *pixel, int image_width, int image_height) +{ + int i; + int image_size = image_width * image_height; + PIXELM *pixel_pointer=pixel; + + for (i = 0; i < image_size; i++) + { + pixel_pointer->value += TWOPI * (float)(pixel_pointer->increment); + pixel_pointer++; + } +} + +//set the masked pixels (mask = 0) to the minimum of the unwrapper phase +void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int image_height) +{ + int image_width_plus_one = image_width + 1; + int image_height_plus_one = image_height + 1; + int image_width_minus_one = image_width - 1; + int image_height_minus_one = image_height - 1; + + PIXELM *pointer_pixel = pixel; + unsigned char *IMP = input_mask; //input mask pointer + float min=99999999.; + int i, j; + int image_size = image_width * image_height; + + //find the minimum of the unwrapped phase + for (i = 0; i < image_size; i++) + { + if ((pointer_pixel->value < min) && (*IMP == 255)) + min = pointer_pixel->value; + + pointer_pixel++; + IMP++; + } + + pointer_pixel = pixel; + IMP = input_mask; + + //set the masked pixels to minimum + for (i = 0; i < image_size; i++) + { + if ((*IMP) == 0) + { + pointer_pixel->value = min; + } + pointer_pixel++; + IMP++; + } +} + +//the input to this unwrapper is an array that contains the wrapped phase map. +//copy the image on the buffer passed to this unwrapper to over-write the unwrapped +//phase map on the buffer of the wrapped phase map. +void returnImage(PIXELM *pixel, float *unwrappedImage, int image_width, int image_height) +{ + int i; + int image_size = image_width * image_height; + float *unwrappedImage_pointer = unwrappedImage; + PIXELM *pixel_pointer = pixel; + + for (i=0; i < image_size; i++) + { + *unwrappedImage_pointer = pixel_pointer->value; + pixel_pointer++; + unwrappedImage_pointer++; + } +} + +//the main function of the unwrapper +int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask, + int image_width, int image_height) +{ + unsigned char *extended_mask; + int image_size = image_height * image_width; + int No_of_Edges_initially = 2 * image_width * image_height; + + extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); + PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); + EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; + + extend_mask(input_mask, extended_mask, image_width, image_height); + initialisePIXELs(WrappedImage, input_mask, extended_mask, pixel, image_width, image_height); + calculate_reliability(WrappedImage, pixel, image_width, image_height); + horizontalEDGEs(pixel, edge, image_width, image_height); + verticalEDGEs(pixel, edge, image_width, image_height); + + //sort the EDGEs depending on their reiability. The PIXELs with higher + //relibility (small value) first + quicker_sort(edge, edge + No_of_edges - 1); + + //gather PIXELs into groups + gatherPIXELs(edge, image_width, image_height); + + unwrapImage(pixel, image_width, image_height); + maskImage(pixel, input_mask, image_width, image_height); + + //copy the image from PIXELM structure to the unwrapped phase array + //passed to this function + returnImage(pixel, UnwrappedImage, image_width, image_height); + + free(edge); + free(pixel); + free(extended_mask); + + return 1; + No_of_edges = 0; +} diff --git a/unwrap2D/setup.py b/unwrap2D/setup.py new file mode 100644 index 00000000..284d8374 --- /dev/null +++ b/unwrap2D/setup.py @@ -0,0 +1,26 @@ +from distutils.core import setup +from distutils.extension import Extension +from Cython.Distutils import build_ext +#from Cython.Build import cythonize +import numpy as np + +ext_modules = [ + Extension('unwrap2D', + ['unwrap2D.pyx', + #'Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp', + 'Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c', + ], + include_dirs = [np.get_include(),], + ), + ] + +import numpy as np + +setup( + name = 'unwrp2D', + #ext_modules = cythonize(['cytransient.pyx',], + # include_path = [np.get_include(),], + # ), + cmdclass = {'build_ext': build_ext}, + ext_modules = ext_modules, + ) diff --git a/unwrap2D/test_unwrap.py b/unwrap2D/test_unwrap.py new file mode 100644 index 00000000..cad968cf --- /dev/null +++ b/unwrap2D/test_unwrap.py @@ -0,0 +1,47 @@ +from numpy.testing import * +from unwrap2D import unwrap2D + +import numpy as np +from numpy import outer, arange, ones, abs, empty, power, indices + + +def test_unwrap2D(): + nx, ny = 64, 64 + x = np.arange(nx) + y = np.arange(ny) + x.shape = (1,-1) + y.shape = (-1,1) + + z = np.exp(1j*x*0.5) * np.exp(1j*y*0.1) + phi_w = np.angle(z) + mask = 255*np.ones((nx, ny), dtype = np.uint8) + phi = unwrap2D(phi_w.astype(np.float32), mask) + return phi_w, phi + + +# class test_unwrap(TestCase): +# def test_simple2d(self, level=1): +# grid = outer(ones(64), arange(-32,32)) + \ +# 1.j * outer(arange(-32,32), ones(64)) +# pgrid = abs(grid) +# wr_grid = normalize_angle(pgrid) +# uw_grid = unwrap2D(wr_grid) +# uw_grid += (pgrid[32,32] - uw_grid[32,32]) + +# assert_array_almost_equal(pgrid, uw_grid, decimal=5) + +# def test_simple3d(self): +# grid = indices((64,64,64)) +# grid[0] -= 32 +# grid[1] -= 32 +# grid[2] -= 32 +# # get distance of each point in the grid from 0 +# grid = power(power(grid, 2.0).sum(axis=0), 0.5) +# wr_grid = normalize_angle(grid) +# uw_grid = unwrap3D(wr_grid) +# uw_grid += (grid[32,32,32] - uw_grid[32,32,32]) +# assert_array_almost_equal(grid, uw_grid, decimal=5) + +if __name__=="__main__": + #NumpyTest().run() + p,p2 = test_unwrap2D() diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx new file mode 100644 index 00000000..d92032a4 --- /dev/null +++ b/unwrap2D/unwrap2D.pyx @@ -0,0 +1,17 @@ +import numpy as np +cimport numpy as np + +cdef extern int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask, + int image_width, int image_height) + +def unwrap2D(float[:,::1] array, unsigned char[:,::1] mask): + cdef float[:,::1] unwrapped_array = np.empty_like(array) + cdef int h = array.shape[0] + cdef int w = array.shape[1] + unwrap(&array[0,0], + &unwrapped_array[0,0], + &mask[0,0], + array.shape[0], array.shape[1]) + return unwrapped_array + + From c5681dd85ede3b8f29ebcc326de3a0fadda9f27a Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sat, 12 May 2012 19:31:37 +0200 Subject: [PATCH 03/84] unwrap: cleanups --- punwrap2D/setup.py | 16 - ...apper_with_mask_and_wrap_around_option.cpp | 743 ------------------ 2 files changed, 759 deletions(-) delete mode 100755 punwrap2D/setup.py delete mode 100755 unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp diff --git a/punwrap2D/setup.py b/punwrap2D/setup.py deleted file mode 100755 index 9a236dfc..00000000 --- a/punwrap2D/setup.py +++ /dev/null @@ -1,16 +0,0 @@ -from distutils.core import setup -from distutils.extension import Extension -import numpy as np - -ext_modules = [ - Extension('_punwrap2D', - ['unwrap_phase.c', 'Munther_2D_unwrap.c'], - include_dirs = [np.get_include(),], - #libraries = ['unwrap2D'], - ), - ] - -setup( - name = 'punwrap', - ext_modules = ext_modules, - ) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp deleted file mode 100755 index 88bdcab6..00000000 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp +++ /dev/null @@ -1,743 +0,0 @@ -//This program was written by Munther Gdeisat and Miguel Arevallilo Herra´ez to program the two-dimensional unwrapper -//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by -//reliability following a noncontinuous path" -//by Miguel Arevallilo Herra´ez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat -//published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. -//This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. -//Date 26th August 2007 -//The wrapped phase map is assumed to be of floating point data type. The resultant unwrapped phase map is also of floating point type. -//The mask is of byte data type. -//When the mask is 255 this means that the pixel is valid -//When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) -//This program takes into consideration the image wrap around problem encountered in MRI imaging. -#include -//#include "stdafx.h" -#include -#include -#include - -static float PI = 3.141592654; -static float TWOPI = 6.283185307; -int x_connectivity = 1; -int y_connectivity = 1; -int No_of_edges = 0; - -//PIXELM information -struct PIXELM -{ - //int x; //x coordinate of the pixel - //int y; //y coordinate - int increment; //No. of 2*pi to add to the pixel to unwrap it - int number_of_pixels_in_group; //No. of pixel in the pixel group - float value; //value of the pixel - float reliability; - unsigned char input_mask; //0 pixel is masked. 255 pixel is not masked - unsigned char extended_mask; //0 pixel is masked. 255 pixel is not masked - int group; //group No. - int new_group; - struct PIXELM *head; //pointer to the first pixel in the group in the linked list - struct PIXELM *last; //pointer to the last pixel in the group - struct PIXELM *next; //pointer to the next pixel in the group -}; - - -//the EDGE is the line that connects two pixels. -//if we have S pixels, then we have S horizontal edges and S vertical edges -struct EDGE -{ - float reliab; //reliabilty of the edge and it depends on the two pixels - PIXELM *pointer_1; //pointer to the first pixel - PIXELM *pointer_2; //pointer to the second pixel - int increment; //No. of 2*pi to add to one of the pixels to unwrap it with respect to the second -}; - -void read_data(char *inputfile,float *Data, int length) -{ - printf("Reading the Wrapped Values from Binary File.............>"); - FILE *ifptr; - ifptr = fopen(inputfile,"rb"); - if(ifptr == NULL) printf("Error opening the file\n"); - fread(Data,sizeof(float),length,ifptr); - fclose(ifptr); - printf(" Done.\n"); -} - -void write_data(char *outputfile,float *Data,int length) -{ - printf("Writing the Wrapped Values to Binary File.............>"); - FILE *ifptr; - ifptr = fopen(outputfile,"wb"); - if(ifptr == NULL) printf("Error opening the file\n"); - fwrite(Data,sizeof(float),length,ifptr); - fclose(ifptr); - printf(" Done.\n"); -} - -void read_mask(char *inputfile,unsigned char *Data, int length) -{ - printf("Reading the mask frpm Binary File.............>"); - FILE *ifptr; - ifptr = fopen(inputfile,"rb"); - if(ifptr == NULL) printf("Error opening the file\n"); - fread(Data,sizeof(char),length,ifptr); - fclose(ifptr); - printf(" Done.\n"); -} -//---------------start quicker_sort algorithm -------------------------------- -#define swap(x,y) {EDGE t; t=x; x=y; y=t;} -#define order(x,y) if (x.reliab > y.reliab) swap(x,y) -#define o2(x,y) order(x,y) -#define o3(x,y,z) o2(x,y); o2(x,z); o2(y,z) - -typedef enum {yes, no} yes_no; - -yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) -{ - EDGE a, b, c, *p; - - a = *left; - b = *(left + (right - left) /2 ); - c = *right; - o3(a,b,c); - - if (a.reliab < b.reliab) - { - *pivot_ptr = b.reliab; - return yes; - } - - if (b.reliab < c.reliab) - { - *pivot_ptr = c.reliab; - return yes; - } - - for (p = left + 1; p <= right; ++p) - { - if (p->reliab != left->reliab) - { - *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; - return yes; - } - return no; - } -} - -EDGE *partition(EDGE *left, EDGE *right, float pivot) -{ - while (left <= right) - { - while (left->reliab < pivot) - ++left; - while (right->reliab >= pivot) - --right; - if (left < right) - { - swap (*left, *right); - ++left; - --right; - } - } - return left; -} - -void quicker_sort(EDGE *left, EDGE *right) -{ - EDGE *p; - float pivot; - - if (find_pivot(left, right, &pivot) == yes) - { - p = partition(left, right, pivot); - quicker_sort(left, p - 1); - quicker_sort(p, right); - } -} - -//--------------end quicker_sort algorithm ----------------------------------- - -//--------------------start initialse pixels ---------------------------------- -//initialse pixels. See the explination of the pixel class above. -//initially every pixel is assumed to belong to a group consisting of only itself -void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) -{ - PIXELM *pixel_pointer = pixel; - float *wrapped_image_pointer = WrappedImage; - unsigned char *input_mask_pointer = input_mask; - unsigned char *extended_mask_pointer = extended_mask; - int i, j; - - for (i=0; i < image_height; i++) - { - for (j=0; j < image_width; j++) - { - //pixel_pointer->x = j; - //pixel_pointer->y = i; - pixel_pointer->increment = 0; - pixel_pointer->number_of_pixels_in_group = 1; - pixel_pointer->value = *wrapped_image_pointer; - pixel_pointer->reliability = 9999999 + rand(); - pixel_pointer->input_mask = *input_mask_pointer; - pixel_pointer->extended_mask = *extended_mask_pointer; - pixel_pointer->head = pixel_pointer; - pixel_pointer->last = pixel_pointer; - pixel_pointer->next = NULL; - pixel_pointer->new_group = 0; - pixel_pointer->group = -1; - pixel_pointer++; - wrapped_image_pointer++; - input_mask_pointer++; - extended_mask_pointer++; - } - } -} -//-------------------end initialise pixels ----------- - -//gamma function in the paper -float wrap(float pixel_value) -{ - float wrapped_pixel_value; - if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; - else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; - else wrapped_pixel_value = pixel_value; - return wrapped_pixel_value; -} - -// pixelL_value is the left pixel, pixelR_value is the right pixel -int find_wrap(float pixelL_value, float pixelR_value) -{ - float difference; - int wrap_value; - difference = pixelL_value - pixelR_value; - - if (difference > PI) wrap_value = -1; - else if (difference < -PI) wrap_value = 1; - else wrap_value = 0; - - return wrap_value; -} - -void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int image_width, int image_height) -{ - int i,j; - int image_width_plus_one = image_width + 1; - int image_width_minus_one = image_width - 1; - unsigned char *IMP = input_mask + image_width + 1; //input mask pointer - unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer - - //extend the mask for the image except borders - for (i=1; i < image_height - 1; ++i) - { - for (j=1; j < image_width - 1; ++j) - { - if ( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width_minus_one) == 255) && (*(IMP - image_width_plus_one) == 255) && - (*(IMP + image_width_minus_one) == 255) && (*(IMP + image_width_plus_one) == 255) ) - { - *EMP = 255; - } - ++EMP; - ++IMP; - } - EMP += 2; - IMP += 2; - } - - if (x_connectivity == 1) - { - //extend the mask for the right border of the image - IMP = input_mask + 2 * image_width - 1; - EMP = extended_mask + 2 * image_width -1; - for (i=1; i < image_height - 1; ++ i) - { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && - (*(IMP + image_width - 1) == 255) && (*(IMP - 2 * image_width + 1) == 255) ) - { - *EMP = 255; - } - EMP += image_width; - IMP += image_width; - } - - //extend the mask for the left border of the image - IMP = input_mask + image_width; - EMP = extended_mask + image_width; - for (i=1; i < image_height - 1; ++i) - { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width + 1) == 255) && (*(IMP + image_width + 1) == 255) && - (*(IMP + image_width - 1) == 255) && (*(IMP + 2 * image_width - 1) == 255) ) - { - *EMP = 255; - } - EMP += image_width; - IMP += image_width; - } - } - - if (y_connectivity == 1) - { - //extend the mask for the top border of the image - IMP = input_mask + 1; - EMP = extended_mask + 1; - for (i=1; i < image_width - 1; ++i) - { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP + image_width * (image_height - 1)) == 255) && - (*(IMP + image_width + 1) == 255) && (*(IMP + image_width - 1) == 255) && - (*(IMP + image_width * (image_height - 1) - 1) == 255) && (*(IMP + image_width * (image_height - 1) + 1) == 255) ) - { - *EMP = 255; - } - EMP++; - IMP++; - } - - //extend the mask for the bottom border of the image - IMP = input_mask + image_width * (image_height - 1) + 1; - EMP = extended_mask + image_width * (image_height - 1) + 1; - for (i=1; i < image_width - 1; ++i) - { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP - image_width) == 255) && (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && - (*(IMP - image_width * (image_height - 1) ) == 255) && - (*(IMP - image_width * (image_height - 1) - 1) == 255) && - (*(IMP - image_width * (image_height - 1) + 1) == 255) ) - { - *EMP = 255; - } - EMP++; - IMP++; - } - } -} - -void calculate_reliability(float *wrappedImage, PIXELM *pixel, int image_width, int image_height) -{ - int image_width_plus_one = image_width + 1; - int image_width_minus_one = image_width - 1; - PIXELM *pixel_pointer = pixel + image_width_plus_one; - float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer - float H, V, D1, D2; - int i, j; - - for (i = 1; i < image_height -1; ++i) - { - for (j = 1; j < image_width - 1; ++j) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - pixel_pointer += 2; - WIP += 2; - } - - if (x_connectivity == 1) - { - //calculating the reliability for the left border of the image - PIXELM *pixel_pointer = pixel + image_width; - float *WIP = wrappedImage + image_width; - - for (i = 1; i < image_height - 1; ++i) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer += image_width; - WIP += image_width; - } - - //calculating the reliability for the right border of the image - pixel_pointer = pixel + 2 * image_width - 1; - WIP = wrappedImage + 2 * image_width - 1; - - for (i = 1; i < image_height - 1; ++i) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); - D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer += image_width; - WIP += image_width; - } - } - - if (y_connectivity == 1) - { - //calculating the reliability for the top border of the image - PIXELM *pixel_pointer = pixel + 1; - float *WIP = wrappedImage + 1; - - for (i = 1; i < image_width - 1; ++i) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - - //calculating the reliability for the bottom border of the image - pixel_pointer = pixel + (image_height - 1) * image_width + 1; - WIP = wrappedImage + (image_height - 1) * image_width + 1; - - for (i = 1; i < image_width - 1; ++i) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - } -} - -//calculate the reliability of the horizontal edges of the image -//it is calculated by adding the reliability of pixel and the relibility of -//its right-hand neighbour -//edge is calculated between a pixel and its next neighbour -void horizontalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height) -{ - int i, j; - EDGE *edge_pointer = edge; - PIXELM *pixel_pointer = pixel; - - for (i = 0; i < image_height; i++) - { - for (j = 0; j < image_width - 1; j++) - { - if (pixel_pointer->input_mask == 255 && (pixel_pointer + 1)->input_mask == 255) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer+1); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } - pixel_pointer++; - } - //construct edges at the right border of the image - if (x_connectivity == 1) - { - pixel_pointer = pixel + image_width - 1; - for (i = 0; i < image_height; i++) - { - if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width + 1)->input_mask == 255) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer+=image_width; - } - } -} - -//calculate the reliability of the vertical edges of the image -//it is calculated by adding the reliability of pixel and the relibility of -//its lower neighbour in the image. -void verticalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height) -{ - int i, j; - PIXELM *pixel_pointer = pixel; - EDGE *edge_pointer = edge + No_of_edges; - - for (i=0; i < image_height - 1; i++) - { - for (j=0; j < image_width; j++) - { - if (pixel_pointer->input_mask == 255 && (pixel_pointer + image_width)->input_mask == 255) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer + image_width); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } //j loop - } // i loop - - //construct edges that connect at the bottom border of the image - if (y_connectivity == 1) - { - pixel_pointer = pixel + image_width *(image_height - 1); - for (i = 0; i < image_width; i++) - { - if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width *(image_height - 1))->input_mask == 255) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } - } -} - -//gather the pixels of the image into groups -void gatherPIXELs(EDGE *edge, int image_width, int image_height) -{ - int k; - PIXELM *PIXEL1; - PIXELM *PIXEL2; - PIXELM *group1; - PIXELM *group2; - EDGE *pointer_edge = edge; - int incremento; - - for (k = 0; k < No_of_edges; k++) - { - PIXEL1 = pointer_edge->pointer_1; - PIXEL2 = pointer_edge->pointer_2; - - //PIXELM 1 and PIXELM 2 belong to different groups - //initially each pixel is a group by it self and one pixel can construct a group - //no else or else if to this if - if (PIXEL2->head != PIXEL1->head) - { - //PIXELM 2 is alone in its group - //merge this pixel with PIXELM 1 group and find the number of 2 pi to add - //to or subtract to unwrap it - if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) - { - PIXEL1->head->last->next = PIXEL2; - PIXEL1->head->last = PIXEL2; - (PIXEL1->head->number_of_pixels_in_group)++; - PIXEL2->head=PIXEL1->head; - PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; - } - - //PIXELM 1 is alone in its group - //merge this pixel with PIXELM 2 group and find the number of 2 pi to add - //to or subtract to unwrap it - else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) - { - PIXEL2->head->last->next = PIXEL1; - PIXEL2->head->last = PIXEL1; - (PIXEL2->head->number_of_pixels_in_group)++; - PIXEL1->head = PIXEL2->head; - PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; - } - - //PIXELM 1 and PIXELM 2 both have groups - else - { - group1 = PIXEL1->head; - group2 = PIXEL2->head; - //if the no. of pixels in PIXELM 1 group is larger than the no. of pixels - //in PIXELM 2 group. Merge PIXELM 2 group to PIXELM 1 group - //and find the number of wraps between PIXELM 2 group and PIXELM 1 group - //to unwrap PIXELM 2 group with respect to PIXELM 1 group. - //the no. of wraps will be added to PIXELM 2 grop in the future - if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) - { - //merge PIXELM 2 with PIXELM 1 group - group1->last->next = group2; - group1->last = group2->last; - group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; - incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; - //merge the other pixels in PIXELM 2 group to PIXELM 1 group - while (group2 != NULL) - { - group2->head = group1; - group2->increment += incremento; - group2 = group2->next; - } - } - - //if the no. of pixels in PIXELM 2 group is larger than the no. of pixels - //in PIXELM 1 group. Merge PIXELM 1 group to PIXELM 2 group - //and find the number of wraps between PIXELM 2 group and PIXELM 1 group - //to unwrap PIXELM 1 group with respect to PIXELM 2 group. - //the no. of wraps will be added to PIXELM 1 grop in the future - else - { - //merge PIXELM 1 with PIXELM 2 group - group2->last->next = group1; - group2->last = group1->last; - group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; - incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; - //merge the other pixels in PIXELM 2 group to PIXELM 1 group - while (group1 != NULL) - { - group1->head = group2; - group1->increment += incremento; - group1 = group1->next; - } // while - - } // else - } //else - } //if - pointer_edge++; - } -} - -//unwrap the image -void unwrapImage(PIXELM *pixel, int image_width, int image_height) -{ - int i; - int image_size = image_width * image_height; - PIXELM *pixel_pointer=pixel; - - for (i = 0; i < image_size; i++) - { - pixel_pointer->value += TWOPI * (float)(pixel_pointer->increment); - pixel_pointer++; - } -} - -//set the masked pixels (mask = 0) to the minimum of the unwrapper phase -void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int image_height) -{ - int image_width_plus_one = image_width + 1; - int image_height_plus_one = image_height + 1; - int image_width_minus_one = image_width - 1; - int image_height_minus_one = image_height - 1; - - PIXELM *pointer_pixel = pixel; - unsigned char *IMP = input_mask; //input mask pointer - float min=99999999.; - int i, j; - int image_size = image_width * image_height; - - //find the minimum of the unwrapped phase - for (i = 0; i < image_size; i++) - { - if ((pointer_pixel->value < min) && (*IMP == 255)) - min = pointer_pixel->value; - - pointer_pixel++; - IMP++; - } - - pointer_pixel = pixel; - IMP = input_mask; - - //set the masked pixels to minimum - for (i = 0; i < image_size; i++) - { - if ((*IMP) == 0) - { - pointer_pixel->value = min; - } - pointer_pixel++; - IMP++; - } -} - -//the input to this unwrapper is an array that contains the wrapped phase map. -//copy the image on the buffer passed to this unwrapper to over-write the unwrapped -//phase map on the buffer of the wrapped phase map. -void returnImage(PIXELM *pixel, float *unwrappedImage, int image_width, int image_height) -{ - int i; - int image_size = image_width * image_height; - float *unwrappedImage_pointer = unwrappedImage; - PIXELM *pixel_pointer = pixel; - - for (i=0; i < image_size; i++) - { - *unwrappedImage_pointer = pixel_pointer->value; - pixel_pointer++; - unwrappedImage_pointer++; - } -} - -//the main function of the unwrapper -int main() -{ - float *WrappedImage, *UnwrappedImage; - unsigned char *input_mask, *extended_mask; - int image_width = 64; - int image_height = 64; - int i, j; - int image_size = image_height * image_width; - int No_of_Edges_initially = (image_width)*(image_height) + (image_width)*(image_height); - - WrappedImage = (float *) calloc(image_size, sizeof(float)); - read_data("wrapped phase slice 64X64.dat", WrappedImage, image_size); - - input_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); - extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); - read_mask("mask 64X64.dat", input_mask, image_size); - - UnwrappedImage = (float *) calloc(image_size, sizeof(float)); - PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); - EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; - - extend_mask(input_mask, extended_mask, image_width, image_height); - - initialisePIXELs(WrappedImage, input_mask, extended_mask, pixel, image_width, image_height); - - calculate_reliability(WrappedImage, pixel, image_width, image_height); - - horizontalEDGEs(pixel, edge, image_width, image_height); - - verticalEDGEs(pixel, edge, image_width, image_height); - - //sort the EDGEs depending on their reiability. The PIXELs with higher relibility (small value) first - quicker_sort(edge, edge + No_of_edges - 1); - - //gather PIXELs into groups - gatherPIXELs(edge, image_width, image_height); - - unwrapImage(pixel, image_width, image_height); - - maskImage(pixel, input_mask, image_width, image_height); - - //copy the image from PIXELM structure to the unwrapped phase array passed to this function - returnImage(pixel, UnwrappedImage, image_width, image_height); - - free(edge); - free(pixel); - - write_data("unwrapped.dat", UnwrappedImage, image_size); - free(UnwrappedImage); - free(WrappedImage); - free(input_mask); - free(extended_mask); - - return 1; -} From a660ccc727ae43120fb57030b98365a9e648cb79 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sat, 12 May 2012 20:03:56 +0200 Subject: [PATCH 04/84] unwrap: compiles ok --- .../Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index a77fb98a..99dd9cce 100644 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -53,8 +53,8 @@ typedef struct pixelm PIXELM; struct edge { float reliab; //reliabilty of the edge and it depends on the two pixels - struct PIXELM *pointer_1; //pointer to the first pixel - struct PIXELM *pointer_2; //pointer to the second pixel + PIXELM *pointer_1; //pointer to the first pixel + PIXELM *pointer_2; //pointer to the second pixel int increment; //No. of 2*pi to add to one of the pixels to unwrap it with respect to the second }; @@ -698,6 +698,7 @@ int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask free(pixel); free(extended_mask); - return 1; No_of_edges = 0; + return 1; + } From 6f40c95c083464d45205523f6ea75b5197f26a55 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sat, 12 May 2012 21:15:55 +0200 Subject: [PATCH 05/84] unwrap: moved global variables (wrap_around) to params struct --- ...wrapper_with_mask_and_wrap_around_option.c | 1418 +++++++++-------- unwrap2D/test_unwrap.py | 9 +- 2 files changed, 724 insertions(+), 703 deletions(-) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index 99dd9cce..d8411c81 100644 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -1,704 +1,722 @@ -// 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer - -//This program was written by Munther Gdeisat and Miguel Arevallilo Herra´ez to program the two-dimensional unwrapper -//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by -//reliability following a noncontinuous path" -//by Miguel Arevallilo Herra´ez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat -//published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. -//This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. -//Date 26th August 2007 -//The wrapped phase map is assumed to be of floating point data type. The resultant unwrapped phase map is also of floating point type. -//The mask is of byte data type. -//When the mask is 255 this means that the pixel is valid -//When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) -//This program takes into consideration the image wrap around problem encountered in MRI imaging. - -//TODO stdlib instead of malloc.h ? (calloc?) -#include -#include -#include - -//TODO: remove global variables -//TODO: make thresholds independent - -static float PI = 3.141592654; -static float TWOPI = 6.283185307; - - -int x_connectivity = 1; -int y_connectivity = 1; -int No_of_edges = 0; - -//PIXELM information -struct pixelm -{ - int increment; //No. of 2*pi to add to the pixel to unwrap it - int number_of_pixels_in_group; //No. of pixel in the pixel group - float value; //value of the pixel - float reliability; - unsigned char input_mask; //0 pixel is masked. 255 pixel is not masked - unsigned char extended_mask; //0 pixel is masked. 255 pixel is not masked - int group; //group No. - int new_group; - struct pixelm *head; //pointer to the first pixel in the group in the linked list - struct pixelm *last; //pointer to the last pixel in the group - struct pixelm *next; //pointer to the next pixel in the group -}; - -typedef struct pixelm PIXELM; - - -//the EDGE is the line that connects two pixels. -//if we have S pixels, then we have S horizontal edges and S vertical edges -struct edge -{ - float reliab; //reliabilty of the edge and it depends on the two pixels +// 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer + +//This program was written by Munther Gdeisat and Miguel Arevallilo Herra´ez to program the two-dimensional unwrapper +//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by +//reliability following a noncontinuous path" +//by Miguel Arevallilo Herra´ez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat +//published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. +//This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. +//Date 26th August 2007 +//The wrapped phase map is assumed to be of floating point data type. The resultant unwrapped phase map is also of floating point type. +//The mask is of byte data type. +//When the mask is 255 this means that the pixel is valid +//When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) +//This program takes into consideration the image wrap around problem encountered in MRI imaging. + +//TODO stdlib instead of malloc.h ? (calloc?) +#include +#include +#include + +//TODO: remove global variables +//TODO: make thresholds independent + +static float PI = 3.141592654; +static float TWOPI = 6.283185307; + +typedef struct +{ + float mod; + int x_connectivity; + int y_connectivity; + int no_of_edges; +} params_t; + + +//int x_connectivity = 1; +//int y_connectivity = 1; +int No_of_edges = 0; + +//PIXELM information +struct pixelm +{ + int increment; //No. of 2*pi to add to the pixel to unwrap it + int number_of_pixels_in_group; //No. of pixel in the pixel group + float value; //value of the pixel + float reliability; + unsigned char input_mask; //0 pixel is masked. 255 pixel is not masked + unsigned char extended_mask; //0 pixel is masked. 255 pixel is not masked + int group; //group No. + int new_group; + struct pixelm *head; //pointer to the first pixel in the group in the linked list + struct pixelm *last; //pointer to the last pixel in the group + struct pixelm *next; //pointer to the next pixel in the group +}; + +typedef struct pixelm PIXELM; + +//the EDGE is the line that connects two pixels. +//if we have S pixels, then we have S horizontal edges and S vertical edges +struct edge +{ + float reliab; //reliabilty of the edge and it depends on the two pixels PIXELM *pointer_1; //pointer to the first pixel PIXELM *pointer_2; //pointer to the second pixel - int increment; //No. of 2*pi to add to one of the pixels to unwrap it with respect to the second -}; - -typedef struct edge EDGE; - -//---------------start quicker_sort algorithm -------------------------------- -#define swap(x,y) {EDGE t; t=x; x=y; y=t;} -#define order(x,y) if (x.reliab > y.reliab) swap(x,y) -#define o2(x,y) order(x,y) -#define o3(x,y,z) o2(x,y); o2(x,z); o2(y,z) - -typedef enum {yes, no} yes_no; - -yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) -{ - EDGE a, b, c, *p; - - a = *left; - b = *(left + (right - left) /2 ); - c = *right; - o3(a,b,c); - - if (a.reliab < b.reliab) - { - *pivot_ptr = b.reliab; - return yes; - } - - if (b.reliab < c.reliab) - { - *pivot_ptr = c.reliab; - return yes; - } - - for (p = left + 1; p <= right; ++p) - { - if (p->reliab != left->reliab) - { - *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; - return yes; - } - return no; - } -} - -EDGE *partition(EDGE *left, EDGE *right, float pivot) -{ - while (left <= right) - { - while (left->reliab < pivot) - ++left; - while (right->reliab >= pivot) - --right; - if (left < right) - { - swap (*left, *right); - ++left; - --right; - } - } - return left; -} - -void quicker_sort(EDGE *left, EDGE *right) -{ - EDGE *p; - float pivot; - - if (find_pivot(left, right, &pivot) == yes) - { - p = partition(left, right, pivot); - quicker_sort(left, p - 1); - quicker_sort(p, right); - } -} - -//--------------end quicker_sort algorithm ----------------------------------- - -//--------------------start initialse pixels ---------------------------------- -//initialse pixels. See the explination of the pixel class above. -//initially every pixel is assumed to belong to a group consisting of only itself -void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) -{ - PIXELM *pixel_pointer = pixel; - float *wrapped_image_pointer = WrappedImage; - unsigned char *input_mask_pointer = input_mask; - unsigned char *extended_mask_pointer = extended_mask; - int i, j; - - for (i=0; i < image_height; i++) - { - for (j=0; j < image_width; j++) - { - //pixel_pointer->x = j; - //pixel_pointer->y = i; - pixel_pointer->increment = 0; - pixel_pointer->number_of_pixels_in_group = 1; - pixel_pointer->value = *wrapped_image_pointer; - pixel_pointer->reliability = 9999999 + rand(); - pixel_pointer->input_mask = *input_mask_pointer; - pixel_pointer->extended_mask = *extended_mask_pointer; - pixel_pointer->head = pixel_pointer; - pixel_pointer->last = pixel_pointer; - pixel_pointer->next = NULL; - pixel_pointer->new_group = 0; - pixel_pointer->group = -1; - pixel_pointer++; - wrapped_image_pointer++; - input_mask_pointer++; - extended_mask_pointer++; - } - } -} -//-------------------end initialise pixels ----------- - -//gamma function in the paper -float wrap(float pixel_value) -{ - float wrapped_pixel_value; - if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; - else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; - else wrapped_pixel_value = pixel_value; - return wrapped_pixel_value; -} - -// pixelL_value is the left pixel, pixelR_value is the right pixel -int find_wrap(float pixelL_value, float pixelR_value) -{ - float difference; - int wrap_value; - difference = pixelL_value - pixelR_value; - - if (difference > PI) wrap_value = -1; - else if (difference < -PI) wrap_value = 1; - else wrap_value = 0; - - return wrap_value; -} - -void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int image_width, int image_height) -{ - int i,j; - int image_width_plus_one = image_width + 1; - int image_width_minus_one = image_width - 1; - unsigned char *IMP = input_mask + image_width + 1; //input mask pointer - unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer - - //extend the mask for the image except borders - for (i=1; i < image_height - 1; ++i) - { - for (j=1; j < image_width - 1; ++j) - { - if ( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width_minus_one) == 255) && (*(IMP - image_width_plus_one) == 255) && - (*(IMP + image_width_minus_one) == 255) && (*(IMP + image_width_plus_one) == 255) ) - { - *EMP = 255; - } - ++EMP; - ++IMP; - } - EMP += 2; - IMP += 2; - } - - if (x_connectivity == 1) - { - //extend the mask for the right border of the image - IMP = input_mask + 2 * image_width - 1; - EMP = extended_mask + 2 * image_width -1; - for (i=1; i < image_height - 1; ++ i) - { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && - (*(IMP + image_width - 1) == 255) && (*(IMP - 2 * image_width + 1) == 255) ) - { - *EMP = 255; - } - EMP += image_width; - IMP += image_width; - } - - //extend the mask for the left border of the image - IMP = input_mask + image_width; - EMP = extended_mask + image_width; - for (i=1; i < image_height - 1; ++i) - { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width + 1) == 255) && (*(IMP + image_width + 1) == 255) && - (*(IMP + image_width - 1) == 255) && (*(IMP + 2 * image_width - 1) == 255) ) - { - *EMP = 255; - } - EMP += image_width; - IMP += image_width; - } - } - - if (y_connectivity == 1) - { - //extend the mask for the top border of the image - IMP = input_mask + 1; - EMP = extended_mask + 1; - for (i=1; i < image_width - 1; ++i) - { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP + image_width * (image_height - 1)) == 255) && - (*(IMP + image_width + 1) == 255) && (*(IMP + image_width - 1) == 255) && - (*(IMP + image_width * (image_height - 1) - 1) == 255) && (*(IMP + image_width * (image_height - 1) + 1) == 255) ) - { - *EMP = 255; - } - EMP++; - IMP++; - } - - //extend the mask for the bottom border of the image - IMP = input_mask + image_width * (image_height - 1) + 1; - EMP = extended_mask + image_width * (image_height - 1) + 1; - for (i=1; i < image_width - 1; ++i) - { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP - image_width) == 255) && (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && - (*(IMP - image_width * (image_height - 1) ) == 255) && - (*(IMP - image_width * (image_height - 1) - 1) == 255) && - (*(IMP - image_width * (image_height - 1) + 1) == 255) ) - { - *EMP = 255; - } - EMP++; - IMP++; - } - } -} - -void calculate_reliability(float *wrappedImage, PIXELM *pixel, int image_width, int image_height) -{ - int image_width_plus_one = image_width + 1; - int image_width_minus_one = image_width - 1; - PIXELM *pixel_pointer = pixel + image_width_plus_one; - float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer - float H, V, D1, D2; - int i, j; - - for (i = 1; i < image_height -1; ++i) - { - for (j = 1; j < image_width - 1; ++j) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - pixel_pointer += 2; - WIP += 2; - } - - if (x_connectivity == 1) - { - //calculating the reliability for the left border of the image - PIXELM *pixel_pointer = pixel + image_width; - float *WIP = wrappedImage + image_width; - - for (i = 1; i < image_height - 1; ++i) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer += image_width; - WIP += image_width; - } - - //calculating the reliability for the right border of the image - pixel_pointer = pixel + 2 * image_width - 1; - WIP = wrappedImage + 2 * image_width - 1; - - for (i = 1; i < image_height - 1; ++i) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); - D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer += image_width; - WIP += image_width; - } - } - - if (y_connectivity == 1) - { - //calculating the reliability for the top border of the image - PIXELM *pixel_pointer = pixel + 1; - float *WIP = wrappedImage + 1; - - for (i = 1; i < image_width - 1; ++i) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - - //calculating the reliability for the bottom border of the image - pixel_pointer = pixel + (image_height - 1) * image_width + 1; - WIP = wrappedImage + (image_height - 1) * image_width + 1; - - for (i = 1; i < image_width - 1; ++i) - { - if (pixel_pointer->extended_mask == 255) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - } -} - -//calculate the reliability of the horizontal edges of the image -//it is calculated by adding the reliability of pixel and the relibility of -//its right-hand neighbour -//edge is calculated between a pixel and its next neighbour -void horizontalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height) -{ - int i, j; - EDGE *edge_pointer = edge; - PIXELM *pixel_pointer = pixel; - - for (i = 0; i < image_height; i++) - { - for (j = 0; j < image_width - 1; j++) - { - if (pixel_pointer->input_mask == 255 && (pixel_pointer + 1)->input_mask == 255) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer+1); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } - pixel_pointer++; - } - //construct edges at the right border of the image - if (x_connectivity == 1) - { - pixel_pointer = pixel + image_width - 1; - for (i = 0; i < image_height; i++) - { - if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width + 1)->input_mask == 255) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer+=image_width; - } - } -} - -//calculate the reliability of the vertical edges of the image -//it is calculated by adding the reliability of pixel and the relibility of -//its lower neighbour in the image. -void verticalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height) -{ - int i, j; - PIXELM *pixel_pointer = pixel; - EDGE *edge_pointer = edge + No_of_edges; - - for (i=0; i < image_height - 1; i++) - { - for (j=0; j < image_width; j++) - { - if (pixel_pointer->input_mask == 255 && (pixel_pointer + image_width)->input_mask == 255) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer + image_width); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } //j loop - } // i loop - - //construct edges that connect at the bottom border of the image - if (y_connectivity == 1) - { - pixel_pointer = pixel + image_width *(image_height - 1); - for (i = 0; i < image_width; i++) - { - if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width *(image_height - 1))->input_mask == 255) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } - } -} - -//gather the pixels of the image into groups -void gatherPIXELs(EDGE *edge, int image_width, int image_height) -{ - int k; - PIXELM *PIXEL1; - PIXELM *PIXEL2; - PIXELM *group1; - PIXELM *group2; - EDGE *pointer_edge = edge; - int incremento; - - for (k = 0; k < No_of_edges; k++) - { - PIXEL1 = pointer_edge->pointer_1; - PIXEL2 = pointer_edge->pointer_2; - - //PIXELM 1 and PIXELM 2 belong to different groups - //initially each pixel is a group by it self and one pixel can construct a group - //no else or else if to this if - if (PIXEL2->head != PIXEL1->head) - { - //PIXELM 2 is alone in its group - //merge this pixel with PIXELM 1 group and find the number of 2 pi to add - //to or subtract to unwrap it - if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) - { - PIXEL1->head->last->next = PIXEL2; - PIXEL1->head->last = PIXEL2; - (PIXEL1->head->number_of_pixels_in_group)++; - PIXEL2->head=PIXEL1->head; - PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; - } - - //PIXELM 1 is alone in its group - //merge this pixel with PIXELM 2 group and find the number of 2 pi to add - //to or subtract to unwrap it - else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) - { - PIXEL2->head->last->next = PIXEL1; - PIXEL2->head->last = PIXEL1; - (PIXEL2->head->number_of_pixels_in_group)++; - PIXEL1->head = PIXEL2->head; - PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; - } - - //PIXELM 1 and PIXELM 2 both have groups - else - { - group1 = PIXEL1->head; - group2 = PIXEL2->head; - //if the no. of pixels in PIXELM 1 group is larger than the no. of pixels - //in PIXELM 2 group. Merge PIXELM 2 group to PIXELM 1 group - //and find the number of wraps between PIXELM 2 group and PIXELM 1 group - //to unwrap PIXELM 2 group with respect to PIXELM 1 group. - //the no. of wraps will be added to PIXELM 2 grop in the future - if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) - { - //merge PIXELM 2 with PIXELM 1 group - group1->last->next = group2; - group1->last = group2->last; - group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; - incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; - //merge the other pixels in PIXELM 2 group to PIXELM 1 group - while (group2 != NULL) - { - group2->head = group1; - group2->increment += incremento; - group2 = group2->next; - } - } - - //if the no. of pixels in PIXELM 2 group is larger than the no. of pixels - //in PIXELM 1 group. Merge PIXELM 1 group to PIXELM 2 group - //and find the number of wraps between PIXELM 2 group and PIXELM 1 group - //to unwrap PIXELM 1 group with respect to PIXELM 2 group. - //the no. of wraps will be added to PIXELM 1 grop in the future - else - { - //merge PIXELM 1 with PIXELM 2 group - group2->last->next = group1; - group2->last = group1->last; - group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; - incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; - //merge the other pixels in PIXELM 2 group to PIXELM 1 group - while (group1 != NULL) - { - group1->head = group2; - group1->increment += incremento; - group1 = group1->next; - } // while - - } // else - } //else - } //if - pointer_edge++; - } -} - -//unwrap the image -void unwrapImage(PIXELM *pixel, int image_width, int image_height) -{ - int i; - int image_size = image_width * image_height; - PIXELM *pixel_pointer=pixel; - - for (i = 0; i < image_size; i++) - { - pixel_pointer->value += TWOPI * (float)(pixel_pointer->increment); - pixel_pointer++; - } -} - -//set the masked pixels (mask = 0) to the minimum of the unwrapper phase -void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int image_height) -{ - int image_width_plus_one = image_width + 1; - int image_height_plus_one = image_height + 1; - int image_width_minus_one = image_width - 1; - int image_height_minus_one = image_height - 1; - - PIXELM *pointer_pixel = pixel; - unsigned char *IMP = input_mask; //input mask pointer - float min=99999999.; - int i, j; - int image_size = image_width * image_height; - - //find the minimum of the unwrapped phase - for (i = 0; i < image_size; i++) - { - if ((pointer_pixel->value < min) && (*IMP == 255)) - min = pointer_pixel->value; - - pointer_pixel++; - IMP++; - } - - pointer_pixel = pixel; - IMP = input_mask; - - //set the masked pixels to minimum - for (i = 0; i < image_size; i++) - { - if ((*IMP) == 0) - { - pointer_pixel->value = min; - } - pointer_pixel++; - IMP++; - } -} - -//the input to this unwrapper is an array that contains the wrapped phase map. -//copy the image on the buffer passed to this unwrapper to over-write the unwrapped -//phase map on the buffer of the wrapped phase map. -void returnImage(PIXELM *pixel, float *unwrappedImage, int image_width, int image_height) -{ - int i; - int image_size = image_width * image_height; - float *unwrappedImage_pointer = unwrappedImage; - PIXELM *pixel_pointer = pixel; - - for (i=0; i < image_size; i++) - { - *unwrappedImage_pointer = pixel_pointer->value; - pixel_pointer++; - unwrappedImage_pointer++; - } -} - -//the main function of the unwrapper -int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask, - int image_width, int image_height) -{ - unsigned char *extended_mask; - int image_size = image_height * image_width; - int No_of_Edges_initially = 2 * image_width * image_height; - - extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); - PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); - EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; - - extend_mask(input_mask, extended_mask, image_width, image_height); - initialisePIXELs(WrappedImage, input_mask, extended_mask, pixel, image_width, image_height); - calculate_reliability(WrappedImage, pixel, image_width, image_height); - horizontalEDGEs(pixel, edge, image_width, image_height); - verticalEDGEs(pixel, edge, image_width, image_height); - - //sort the EDGEs depending on their reiability. The PIXELs with higher - //relibility (small value) first - quicker_sort(edge, edge + No_of_edges - 1); - - //gather PIXELs into groups - gatherPIXELs(edge, image_width, image_height); - - unwrapImage(pixel, image_width, image_height); - maskImage(pixel, input_mask, image_width, image_height); - - //copy the image from PIXELM structure to the unwrapped phase array - //passed to this function - returnImage(pixel, UnwrappedImage, image_width, image_height); - - free(edge); - free(pixel); - free(extended_mask); - - No_of_edges = 0; + int increment; //No. of 2*pi to add to one of the pixels to unwrap it with respect to the second +}; + +typedef struct edge EDGE; + + +//---------------start quicker_sort algorithm -------------------------------- +#define swap(x,y) {EDGE t; t=x; x=y; y=t;} +#define order(x,y) if (x.reliab > y.reliab) swap(x,y) +#define o2(x,y) order(x,y) +#define o3(x,y,z) o2(x,y); o2(x,z); o2(y,z) + +typedef enum {yes, no} yes_no; + +yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) +{ + EDGE a, b, c, *p; + + a = *left; + b = *(left + (right - left) /2 ); + c = *right; + o3(a,b,c); + + if (a.reliab < b.reliab) + { + *pivot_ptr = b.reliab; + return yes; + } + + if (b.reliab < c.reliab) + { + *pivot_ptr = c.reliab; + return yes; + } + + for (p = left + 1; p <= right; ++p) + { + if (p->reliab != left->reliab) + { + *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; + return yes; + } + return no; + } +} + +EDGE *partition(EDGE *left, EDGE *right, float pivot) +{ + while (left <= right) + { + while (left->reliab < pivot) + ++left; + while (right->reliab >= pivot) + --right; + if (left < right) + { + swap (*left, *right); + ++left; + --right; + } + } + return left; +} + +void quicker_sort(EDGE *left, EDGE *right) +{ + EDGE *p; + float pivot; + + if (find_pivot(left, right, &pivot) == yes) + { + p = partition(left, right, pivot); + quicker_sort(left, p - 1); + quicker_sort(p, right); + } +} + +//--------------end quicker_sort algorithm ----------------------------------- + +//--------------------start initialse pixels ---------------------------------- +//initialse pixels. See the explination of the pixel class above. +//initially every pixel is assumed to belong to a group consisting of only itself +void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) +{ + PIXELM *pixel_pointer = pixel; + float *wrapped_image_pointer = WrappedImage; + unsigned char *input_mask_pointer = input_mask; + unsigned char *extended_mask_pointer = extended_mask; + int i, j; + + for (i=0; i < image_height; i++) + { + for (j=0; j < image_width; j++) + { + //pixel_pointer->x = j; + //pixel_pointer->y = i; + pixel_pointer->increment = 0; + pixel_pointer->number_of_pixels_in_group = 1; + pixel_pointer->value = *wrapped_image_pointer; + pixel_pointer->reliability = 9999999 + rand(); + pixel_pointer->input_mask = *input_mask_pointer; + pixel_pointer->extended_mask = *extended_mask_pointer; + pixel_pointer->head = pixel_pointer; + pixel_pointer->last = pixel_pointer; + pixel_pointer->next = NULL; + pixel_pointer->new_group = 0; + pixel_pointer->group = -1; + pixel_pointer++; + wrapped_image_pointer++; + input_mask_pointer++; + extended_mask_pointer++; + } + } +} +//-------------------end initialise pixels ----------- + +//gamma function in the paper +float wrap(float pixel_value) +{ + float wrapped_pixel_value; + if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; + else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; + else wrapped_pixel_value = pixel_value; + return wrapped_pixel_value; +} + +// pixelL_value is the left pixel, pixelR_value is the right pixel +int find_wrap(float pixelL_value, float pixelR_value) +{ + float difference; + int wrap_value; + difference = pixelL_value - pixelR_value; + + if (difference > PI) wrap_value = -1; + else if (difference < -PI) wrap_value = 1; + else wrap_value = 0; + + return wrap_value; +} + +void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, + int image_width, int image_height, + params_t *params) +{ + int i,j; + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + unsigned char *IMP = input_mask + image_width + 1; //input mask pointer + unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer + + //extend the mask for the image except borders + for (i=1; i < image_height - 1; ++i) + { + for (j=1; j < image_width - 1; ++j) + { + if ( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width_minus_one) == 255) && (*(IMP - image_width_plus_one) == 255) && + (*(IMP + image_width_minus_one) == 255) && (*(IMP + image_width_plus_one) == 255) ) + { + *EMP = 255; + } + ++EMP; + ++IMP; + } + EMP += 2; + IMP += 2; + } + + if (params->x_connectivity == 1) + { + //extend the mask for the right border of the image + IMP = input_mask + 2 * image_width - 1; + EMP = extended_mask + 2 * image_width -1; + for (i=1; i < image_height - 1; ++ i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && + (*(IMP + image_width - 1) == 255) && (*(IMP - 2 * image_width + 1) == 255) ) + { + *EMP = 255; + } + EMP += image_width; + IMP += image_width; + } + + //extend the mask for the left border of the image + IMP = input_mask + image_width; + EMP = extended_mask + image_width; + for (i=1; i < image_height - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && + (*(IMP - image_width + 1) == 255) && (*(IMP + image_width + 1) == 255) && + (*(IMP + image_width - 1) == 255) && (*(IMP + 2 * image_width - 1) == 255) ) + { + *EMP = 255; + } + EMP += image_width; + IMP += image_width; + } + } + + if (params->y_connectivity == 1) + { + //extend the mask for the top border of the image + IMP = input_mask + 1; + EMP = extended_mask + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + image_width) == 255) && (*(IMP + image_width * (image_height - 1)) == 255) && + (*(IMP + image_width + 1) == 255) && (*(IMP + image_width - 1) == 255) && + (*(IMP + image_width * (image_height - 1) - 1) == 255) && (*(IMP + image_width * (image_height - 1) + 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + + //extend the mask for the bottom border of the image + IMP = input_mask + image_width * (image_height - 1) + 1; + EMP = extended_mask + image_width * (image_height - 1) + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP - image_width) == 255) && (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && + (*(IMP - image_width * (image_height - 1) ) == 255) && + (*(IMP - image_width * (image_height - 1) - 1) == 255) && + (*(IMP - image_width * (image_height - 1) + 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + } +} + +void calculate_reliability(float *wrappedImage, PIXELM *pixel, + int image_width, int image_height, + params_t *params) +{ + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + PIXELM *pixel_pointer = pixel + image_width_plus_one; + float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer + float H, V, D1, D2; + int i, j; + + for (i = 1; i < image_height -1; ++i) + { + for (j = 1; j < image_width - 1; ++j) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + pixel_pointer += 2; + WIP += 2; + } + + if (params->x_connectivity == 1) + { + //calculating the reliability for the left border of the image + PIXELM *pixel_pointer = pixel + image_width; + float *WIP = wrappedImage + image_width; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + + //calculating the reliability for the right border of the image + pixel_pointer = pixel + 2 * image_width - 1; + WIP = wrappedImage + 2 * image_width - 1; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); + D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + } + + if (params->y_connectivity == 1) + { + //calculating the reliability for the top border of the image + PIXELM *pixel_pointer = pixel + 1; + float *WIP = wrappedImage + 1; + + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + + //calculating the reliability for the bottom border of the image + pixel_pointer = pixel + (image_height - 1) * image_width + 1; + WIP = wrappedImage + (image_height - 1) * image_width + 1; + + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == 255) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + } +} + +//calculate the reliability of the horizontal edges of the image +//it is calculated by adding the reliability of pixel and the relibility of +//its right-hand neighbour +//edge is calculated between a pixel and its next neighbour +void horizontalEDGEs(PIXELM *pixel, EDGE *edge, + int image_width, int image_height, + params_t *params) +{ + int i, j; + EDGE *edge_pointer = edge; + PIXELM *pixel_pointer = pixel; + + for (i = 0; i < image_height; i++) + { + for (j = 0; j < image_width - 1; j++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer + 1)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer+1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } + pixel_pointer++; + } + //construct edges at the right border of the image + if (params->x_connectivity == 1) + { + pixel_pointer = pixel + image_width - 1; + for (i = 0; i < image_height; i++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width + 1)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer+=image_width; + } + } +} + +//calculate the reliability of the vertical edges of the image +//it is calculated by adding the reliability of pixel and the relibility of +//its lower neighbour in the image. +void verticalEDGEs(PIXELM *pixel, EDGE *edge, + int image_width, int image_height, + params_t *params) +{ + int i, j; + PIXELM *pixel_pointer = pixel; + EDGE *edge_pointer = edge + No_of_edges; + + for (i=0; i < image_height - 1; i++) + { + for (j=0; j < image_width; j++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer + image_width)->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer + image_width); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } //j loop + } // i loop + + //construct edges that connect at the bottom border of the image + if (params->y_connectivity == 1) + { + pixel_pointer = pixel + image_width *(image_height - 1); + for (i = 0; i < image_width; i++) + { + if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width *(image_height - 1))->input_mask == 255) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } + } +} + +//gather the pixels of the image into groups +void gatherPIXELs(EDGE *edge, int image_width, int image_height) +{ + int k; + PIXELM *PIXEL1; + PIXELM *PIXEL2; + PIXELM *group1; + PIXELM *group2; + EDGE *pointer_edge = edge; + int incremento; + + for (k = 0; k < No_of_edges; k++) + { + PIXEL1 = pointer_edge->pointer_1; + PIXEL2 = pointer_edge->pointer_2; + + //PIXELM 1 and PIXELM 2 belong to different groups + //initially each pixel is a group by it self and one pixel can construct a group + //no else or else if to this if + if (PIXEL2->head != PIXEL1->head) + { + //PIXELM 2 is alone in its group + //merge this pixel with PIXELM 1 group and find the number of 2 pi to add + //to or subtract to unwrap it + if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) + { + PIXEL1->head->last->next = PIXEL2; + PIXEL1->head->last = PIXEL2; + (PIXEL1->head->number_of_pixels_in_group)++; + PIXEL2->head=PIXEL1->head; + PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; + } + + //PIXELM 1 is alone in its group + //merge this pixel with PIXELM 2 group and find the number of 2 pi to add + //to or subtract to unwrap it + else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) + { + PIXEL2->head->last->next = PIXEL1; + PIXEL2->head->last = PIXEL1; + (PIXEL2->head->number_of_pixels_in_group)++; + PIXEL1->head = PIXEL2->head; + PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; + } + + //PIXELM 1 and PIXELM 2 both have groups + else + { + group1 = PIXEL1->head; + group2 = PIXEL2->head; + //if the no. of pixels in PIXELM 1 group is larger than the no. of pixels + //in PIXELM 2 group. Merge PIXELM 2 group to PIXELM 1 group + //and find the number of wraps between PIXELM 2 group and PIXELM 1 group + //to unwrap PIXELM 2 group with respect to PIXELM 1 group. + //the no. of wraps will be added to PIXELM 2 grop in the future + if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) + { + //merge PIXELM 2 with PIXELM 1 group + group1->last->next = group2; + group1->last = group2->last; + group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; + incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group2 != NULL) + { + group2->head = group1; + group2->increment += incremento; + group2 = group2->next; + } + } + + //if the no. of pixels in PIXELM 2 group is larger than the no. of pixels + //in PIXELM 1 group. Merge PIXELM 1 group to PIXELM 2 group + //and find the number of wraps between PIXELM 2 group and PIXELM 1 group + //to unwrap PIXELM 1 group with respect to PIXELM 2 group. + //the no. of wraps will be added to PIXELM 1 grop in the future + else + { + //merge PIXELM 1 with PIXELM 2 group + group2->last->next = group1; + group2->last = group1->last; + group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; + incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group1 != NULL) + { + group1->head = group2; + group1->increment += incremento; + group1 = group1->next; + } // while + + } // else + } //else + } //if + pointer_edge++; + } +} + +//unwrap the image +void unwrapImage(PIXELM *pixel, int image_width, int image_height) +{ + int i; + int image_size = image_width * image_height; + PIXELM *pixel_pointer=pixel; + + for (i = 0; i < image_size; i++) + { + pixel_pointer->value += TWOPI * (float)(pixel_pointer->increment); + pixel_pointer++; + } +} + +//set the masked pixels (mask = 0) to the minimum of the unwrapper phase +void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int image_height) +{ + int image_width_plus_one = image_width + 1; + int image_height_plus_one = image_height + 1; + int image_width_minus_one = image_width - 1; + int image_height_minus_one = image_height - 1; + + PIXELM *pointer_pixel = pixel; + unsigned char *IMP = input_mask; //input mask pointer + float min=99999999.; + int i, j; + int image_size = image_width * image_height; + + //find the minimum of the unwrapped phase + for (i = 0; i < image_size; i++) + { + if ((pointer_pixel->value < min) && (*IMP == 255)) + min = pointer_pixel->value; + + pointer_pixel++; + IMP++; + } + + pointer_pixel = pixel; + IMP = input_mask; + + //set the masked pixels to minimum + for (i = 0; i < image_size; i++) + { + if ((*IMP) == 0) + { + pointer_pixel->value = min; + } + pointer_pixel++; + IMP++; + } +} + +//the input to this unwrapper is an array that contains the wrapped +//phase map. copy the image on the buffer passed to this unwrapper to +//over-write the unwrapped phase map on the buffer of the wrapped +//phase map. +void returnImage(PIXELM *pixel, float *unwrappedImage, int image_width, int image_height) +{ + int i; + int image_size = image_width * image_height; + float *unwrappedImage_pointer = unwrappedImage; + PIXELM *pixel_pointer = pixel; + + for (i=0; i < image_size; i++) + { + *unwrappedImage_pointer = pixel_pointer->value; + pixel_pointer++; + unwrappedImage_pointer++; + } +} + +//the main function of the unwrapper +int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask, + int image_width, int image_height) +{ + unsigned char *extended_mask; + int image_size = image_height * image_width; + int No_of_Edges_initially = 2 * image_width * image_height; + params_t params = {TWOPI, 0, 0, 0}; + + extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); + PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); + EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; + + extend_mask(input_mask, extended_mask, image_width, image_height, ¶ms); + initialisePIXELs(WrappedImage, input_mask, extended_mask, pixel, image_width, image_height); + calculate_reliability(WrappedImage, pixel, image_width, image_height, ¶ms); + horizontalEDGEs(pixel, edge, image_width, image_height, ¶ms); + verticalEDGEs(pixel, edge, image_width, image_height, ¶ms); + + //sort the EDGEs depending on their reiability. The PIXELs with higher + //relibility (small value) first + quicker_sort(edge, edge + No_of_edges - 1); + + //gather PIXELs into groups + gatherPIXELs(edge, image_width, image_height); + + unwrapImage(pixel, image_width, image_height); + maskImage(pixel, input_mask, image_width, image_height); + + //copy the image from PIXELM structure to the unwrapped phase array + //passed to this function + returnImage(pixel, UnwrappedImage, image_width, image_height); + + free(edge); + free(pixel); + free(extended_mask); + + No_of_edges = 0; return 1; -} +} diff --git a/unwrap2D/test_unwrap.py b/unwrap2D/test_unwrap.py index cad968cf..c7e1aadd 100644 --- a/unwrap2D/test_unwrap.py +++ b/unwrap2D/test_unwrap.py @@ -6,17 +6,17 @@ from numpy import outer, arange, ones, abs, empty, power, indices def test_unwrap2D(): - nx, ny = 64, 64 + nx, ny = 10, 3 x = np.arange(nx) y = np.arange(ny) x.shape = (1,-1) y.shape = (-1,1) - z = np.exp(1j*x*0.5) * np.exp(1j*y*0.1) + z = np.exp(1j*x*0.2*np.pi) * np.exp(1j*y*0.1*np.pi) phi_w = np.angle(z) mask = 255*np.ones((nx, ny), dtype = np.uint8) phi = unwrap2D(phi_w.astype(np.float32), mask) - return phi_w, phi + return phi_w/(np.pi*2), np.asarray(phi)/(np.pi*2) # class test_unwrap(TestCase): @@ -44,4 +44,7 @@ def test_unwrap2D(): if __name__=="__main__": #NumpyTest().run() + import matplotlib.pyplot as plt p,p2 = test_unwrap2D() + plt.imshow(p2) + plt From c6c2d78b3b81aa00ccc6ed31126254db3d826355 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sat, 12 May 2012 21:26:40 +0200 Subject: [PATCH 06/84] unwrap: implemented wrap_around arguments --- ...l_2D_unwrapper_with_mask_and_wrap_around_option.c | 11 +++++------ unwrap2D/unwrap2D.pyx | 12 ++++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index d8411c81..4fe59109 100644 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -141,8 +141,8 @@ void quicker_sort(EDGE *left, EDGE *right) //--------------end quicker_sort algorithm ----------------------------------- -//--------------------start initialse pixels ---------------------------------- -//initialse pixels. See the explination of the pixel class above. +//--------------------start initialize pixels ---------------------------------- +//initialize pixels. See the explination of the pixel class above. //initially every pixel is assumed to belong to a group consisting of only itself void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) { @@ -156,8 +156,6 @@ void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned { for (j=0; j < image_width; j++) { - //pixel_pointer->x = j; - //pixel_pointer->y = i; pixel_pointer->increment = 0; pixel_pointer->number_of_pixels_in_group = 1; pixel_pointer->value = *wrapped_image_pointer; @@ -176,7 +174,7 @@ void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned } } } -//-------------------end initialise pixels ----------- +//-------------------end initialize pixels ----------- //gamma function in the paper float wrap(float pixel_value) @@ -681,7 +679,8 @@ void returnImage(PIXELM *pixel, float *unwrappedImage, int image_width, int ima //the main function of the unwrapper int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask, - int image_width, int image_height) + int image_width, int image_height, + int wrap_around_x, int wrap_around_y) { unsigned char *extended_mask; int image_size = image_height * image_width; diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx index d92032a4..ac4a3d33 100644 --- a/unwrap2D/unwrap2D.pyx +++ b/unwrap2D/unwrap2D.pyx @@ -2,16 +2,20 @@ import numpy as np cimport numpy as np cdef extern int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask, - int image_width, int image_height) + int image_width, int image_height, + int wrap_around_x, int wrap_around_y) -def unwrap2D(float[:,::1] array, unsigned char[:,::1] mask): +def unwrap2D(float[:,::1] array, unsigned char[:,::1] mask, + wrap_around_x = False, wrap_around_y = False): cdef float[:,::1] unwrapped_array = np.empty_like(array) cdef int h = array.shape[0] cdef int w = array.shape[1] unwrap(&array[0,0], &unwrapped_array[0,0], &mask[0,0], - array.shape[0], array.shape[1]) - return unwrapped_array + array.shape[0], array.shape[1], + wrap_around_x, wrap_around_y, + ) + return np.asarray(unwrapped_array) From adb9344828a1ef16956db658c89b6412d08e97d8 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sat, 12 May 2012 21:44:11 +0200 Subject: [PATCH 07/84] unwrap: changed mask values to numpy.ma convention --- ...wrapper_with_mask_and_wrap_around_option.c | 83 ++++++++++--------- unwrap2D/test_unwrap.py | 11 ++- 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index 4fe59109..28c7eaac 100644 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -24,6 +24,11 @@ static float PI = 3.141592654; static float TWOPI = 6.283185307; +//TODO: adjust to numpy.ma: NOMASK 0, MASK 1 +#define NOMASK 0 +#define MASK 1 +//#define NOMASK 0 + typedef struct { float mod; @@ -44,8 +49,8 @@ struct pixelm int number_of_pixels_in_group; //No. of pixel in the pixel group float value; //value of the pixel float reliability; - unsigned char input_mask; //0 pixel is masked. 255 pixel is not masked - unsigned char extended_mask; //0 pixel is masked. 255 pixel is not masked + unsigned char input_mask; //0 pixel is masked. NOMASK pixel is not masked + unsigned char extended_mask; //0 pixel is masked. NOMASK pixel is not masked int group; //group No. int new_group; struct pixelm *head; //pointer to the first pixel in the group in the linked list @@ -215,12 +220,12 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, { for (j=1; j < image_width - 1; ++j) { - if ( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width_minus_one) == 255) && (*(IMP - image_width_plus_one) == 255) && - (*(IMP + image_width_minus_one) == 255) && (*(IMP + image_width_plus_one) == 255) ) + if ( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width_minus_one) == NOMASK) && (*(IMP - image_width_plus_one) == NOMASK) && + (*(IMP + image_width_minus_one) == NOMASK) && (*(IMP + image_width_plus_one) == NOMASK) ) { - *EMP = 255; + *EMP = NOMASK; } ++EMP; ++IMP; @@ -236,12 +241,12 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, EMP = extended_mask + 2 * image_width -1; for (i=1; i < image_height - 1; ++ i) { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && - (*(IMP + image_width - 1) == 255) && (*(IMP - 2 * image_width + 1) == 255) ) + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && + (*(IMP + image_width - 1) == NOMASK) && (*(IMP - 2 * image_width + 1) == NOMASK) ) { - *EMP = 255; + *EMP = NOMASK; } EMP += image_width; IMP += image_width; @@ -252,12 +257,12 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, EMP = extended_mask + image_width; for (i=1; i < image_height - 1; ++i) { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP - image_width) == 255) && - (*(IMP - image_width + 1) == 255) && (*(IMP + image_width + 1) == 255) && - (*(IMP + image_width - 1) == 255) && (*(IMP + 2 * image_width - 1) == 255) ) + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width + 1) == NOMASK) && (*(IMP + image_width + 1) == NOMASK) && + (*(IMP + image_width - 1) == NOMASK) && (*(IMP + 2 * image_width - 1) == NOMASK) ) { - *EMP = 255; + *EMP = NOMASK; } EMP += image_width; IMP += image_width; @@ -271,12 +276,12 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, EMP = extended_mask + 1; for (i=1; i < image_width - 1; ++i) { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + image_width) == 255) && (*(IMP + image_width * (image_height - 1)) == 255) && - (*(IMP + image_width + 1) == 255) && (*(IMP + image_width - 1) == 255) && - (*(IMP + image_width * (image_height - 1) - 1) == 255) && (*(IMP + image_width * (image_height - 1) + 1) == 255) ) + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP + image_width * (image_height - 1)) == NOMASK) && + (*(IMP + image_width + 1) == NOMASK) && (*(IMP + image_width - 1) == NOMASK) && + (*(IMP + image_width * (image_height - 1) - 1) == NOMASK) && (*(IMP + image_width * (image_height - 1) + 1) == NOMASK) ) { - *EMP = 255; + *EMP = NOMASK; } EMP++; IMP++; @@ -287,13 +292,13 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, EMP = extended_mask + image_width * (image_height - 1) + 1; for (i=1; i < image_width - 1; ++i) { - if ( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP - image_width) == 255) && (*(IMP - image_width - 1) == 255) && (*(IMP - image_width + 1) == 255) && - (*(IMP - image_width * (image_height - 1) ) == 255) && - (*(IMP - image_width * (image_height - 1) - 1) == 255) && - (*(IMP - image_width * (image_height - 1) + 1) == 255) ) + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP - image_width) == NOMASK) && (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && + (*(IMP - image_width * (image_height - 1) ) == NOMASK) && + (*(IMP - image_width * (image_height - 1) - 1) == NOMASK) && + (*(IMP - image_width * (image_height - 1) + 1) == NOMASK) ) { - *EMP = 255; + *EMP = NOMASK; } EMP++; IMP++; @@ -316,7 +321,7 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, { for (j = 1; j < image_width - 1; ++j) { - if (pixel_pointer->extended_mask == 255) + if (pixel_pointer->extended_mask == NOMASK) { H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); @@ -339,7 +344,7 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, for (i = 1; i < image_height - 1; ++i) { - if (pixel_pointer->extended_mask == 255) + if (pixel_pointer->extended_mask == NOMASK) { H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); @@ -357,7 +362,7 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, for (i = 1; i < image_height - 1; ++i) { - if (pixel_pointer->extended_mask == 255) + if (pixel_pointer->extended_mask == NOMASK) { H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); @@ -378,7 +383,7 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, for (i = 1; i < image_width - 1; ++i) { - if (pixel_pointer->extended_mask == 255) + if (pixel_pointer->extended_mask == NOMASK) { H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); @@ -396,7 +401,7 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, for (i = 1; i < image_width - 1; ++i) { - if (pixel_pointer->extended_mask == 255) + if (pixel_pointer->extended_mask == NOMASK) { H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); @@ -426,7 +431,7 @@ void horizontalEDGEs(PIXELM *pixel, EDGE *edge, { for (j = 0; j < image_width - 1; j++) { - if (pixel_pointer->input_mask == 255 && (pixel_pointer + 1)->input_mask == 255) + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + 1)->input_mask == NOMASK) { edge_pointer->pointer_1 = pixel_pointer; edge_pointer->pointer_2 = (pixel_pointer+1); @@ -445,7 +450,7 @@ void horizontalEDGEs(PIXELM *pixel, EDGE *edge, pixel_pointer = pixel + image_width - 1; for (i = 0; i < image_height; i++) { - if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width + 1)->input_mask == 255) + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width + 1)->input_mask == NOMASK) { edge_pointer->pointer_1 = pixel_pointer; edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); @@ -474,7 +479,7 @@ void verticalEDGEs(PIXELM *pixel, EDGE *edge, { for (j=0; j < image_width; j++) { - if (pixel_pointer->input_mask == 255 && (pixel_pointer + image_width)->input_mask == 255) + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + image_width)->input_mask == NOMASK) { edge_pointer->pointer_1 = pixel_pointer; edge_pointer->pointer_2 = (pixel_pointer + image_width); @@ -493,7 +498,7 @@ void verticalEDGEs(PIXELM *pixel, EDGE *edge, pixel_pointer = pixel + image_width *(image_height - 1); for (i = 0; i < image_width; i++) { - if (pixel_pointer->input_mask == 255 && (pixel_pointer - image_width *(image_height - 1))->input_mask == 255) + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width *(image_height - 1))->input_mask == NOMASK) { edge_pointer->pointer_1 = pixel_pointer; edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); @@ -636,7 +641,7 @@ void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int i //find the minimum of the unwrapped phase for (i = 0; i < image_size; i++) { - if ((pointer_pixel->value < min) && (*IMP == 255)) + if ((pointer_pixel->value < min) && (*IMP == NOMASK)) min = pointer_pixel->value; pointer_pixel++; @@ -649,7 +654,7 @@ void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int i //set the masked pixels to minimum for (i = 0; i < image_size; i++) { - if ((*IMP) == 0) + if ((*IMP) == MASK) { pointer_pixel->value = min; } diff --git a/unwrap2D/test_unwrap.py b/unwrap2D/test_unwrap.py index c7e1aadd..b6cdd33c 100644 --- a/unwrap2D/test_unwrap.py +++ b/unwrap2D/test_unwrap.py @@ -6,7 +6,7 @@ from numpy import outer, arange, ones, abs, empty, power, indices def test_unwrap2D(): - nx, ny = 10, 3 + nx, ny = 10, 10 x = np.arange(nx) y = np.arange(ny) x.shape = (1,-1) @@ -14,7 +14,8 @@ def test_unwrap2D(): z = np.exp(1j*x*0.2*np.pi) * np.exp(1j*y*0.1*np.pi) phi_w = np.angle(z) - mask = 255*np.ones((nx, ny), dtype = np.uint8) + mask = 0*np.ones((nx, ny), dtype = np.uint8) + mask[4:6, 5:7] = 1 phi = unwrap2D(phi_w.astype(np.float32), mask) return phi_w/(np.pi*2), np.asarray(phi)/(np.pi*2) @@ -46,5 +47,7 @@ if __name__=="__main__": #NumpyTest().run() import matplotlib.pyplot as plt p,p2 = test_unwrap2D() - plt.imshow(p2) - plt + plt.clf() + plt.imshow(p2, interpolation = 'nearest') + plt.draw() + plt.show() From 91a621b6463a69f660e1663416e5d9cf838d6e22 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sat, 12 May 2012 22:35:25 +0200 Subject: [PATCH 08/84] unwrap: variable renaming --- ...wrapper_with_mask_and_wrap_around_option.c | 1000 ++++++++--------- unwrap2D/unwrap2D.pyx | 1 + 2 files changed, 501 insertions(+), 500 deletions(-) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index 28c7eaac..14fe65de 100644 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -24,17 +24,15 @@ static float PI = 3.141592654; static float TWOPI = 6.283185307; -//TODO: adjust to numpy.ma: NOMASK 0, MASK 1 #define NOMASK 0 #define MASK 1 -//#define NOMASK 0 typedef struct { - float mod; - int x_connectivity; - int y_connectivity; - int no_of_edges; + float mod; + int x_connectivity; + int y_connectivity; + int no_of_edges; } params_t; @@ -45,17 +43,17 @@ int No_of_edges = 0; //PIXELM information struct pixelm { - int increment; //No. of 2*pi to add to the pixel to unwrap it - int number_of_pixels_in_group; //No. of pixel in the pixel group - float value; //value of the pixel - float reliability; - unsigned char input_mask; //0 pixel is masked. NOMASK pixel is not masked - unsigned char extended_mask; //0 pixel is masked. NOMASK pixel is not masked - int group; //group No. - int new_group; - struct pixelm *head; //pointer to the first pixel in the group in the linked list - struct pixelm *last; //pointer to the last pixel in the group - struct pixelm *next; //pointer to the next pixel in the group + int increment; //No. of 2*pi to add to the pixel to unwrap it + int number_of_pixels_in_group;//No. of pixel in the pixel group + float value; //value of the pixel + float reliability; + unsigned char input_mask; //0 pixel is masked. NOMASK pixel is not masked + unsigned char extended_mask; //0 pixel is masked. NOMASK pixel is not masked + int group; //group No. + int new_group; + struct pixelm *head; //pointer to the first pixel in the group in the linked list + struct pixelm *last; //pointer to the last pixel in the group + struct pixelm *next; //pointer to the next pixel in the group }; typedef struct pixelm PIXELM; @@ -64,10 +62,11 @@ typedef struct pixelm PIXELM; //if we have S pixels, then we have S horizontal edges and S vertical edges struct edge { - float reliab; //reliabilty of the edge and it depends on the two pixels - PIXELM *pointer_1; //pointer to the first pixel - PIXELM *pointer_2; //pointer to the second pixel - int increment; //No. of 2*pi to add to one of the pixels to unwrap it with respect to the second + float reliab; //reliabilty of the edge and it depends on the two pixels + PIXELM *pointer_1; //pointer to the first pixel + PIXELM *pointer_2; //pointer to the second pixel + int increment; //No. of 2*pi to add to one of the pixels to + //unwrap it with respect to the second }; typedef struct edge EDGE; @@ -83,336 +82,335 @@ typedef enum {yes, no} yes_no; yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) { - EDGE a, b, c, *p; + EDGE a, b, c, *p; - a = *left; - b = *(left + (right - left) /2 ); - c = *right; - o3(a,b,c); + a = *left; + b = *(left + (right - left) /2 ); + c = *right; + o3(a,b,c); - if (a.reliab < b.reliab) + if (a.reliab < b.reliab) + { + *pivot_ptr = b.reliab; + return yes; + } + + if (b.reliab < c.reliab) + { + *pivot_ptr = c.reliab; + return yes; + } + + for (p = left + 1; p <= right; ++p) + { + if (p->reliab != left->reliab) { - *pivot_ptr = b.reliab; - return yes; - } - - if (b.reliab < c.reliab) - { - *pivot_ptr = c.reliab; - return yes; - } - - for (p = left + 1; p <= right; ++p) - { - if (p->reliab != left->reliab) - { - *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; - return yes; - } - return no; + *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; + return yes; } + return no; + } } EDGE *partition(EDGE *left, EDGE *right, float pivot) { - while (left <= right) + while (left <= right) + { + while (left->reliab < pivot) + ++left; + while (right->reliab >= pivot) + --right; + if (left < right) { - while (left->reliab < pivot) - ++left; - while (right->reliab >= pivot) - --right; - if (left < right) - { - swap (*left, *right); - ++left; - --right; - } + swap (*left, *right); + ++left; + --right; } - return left; + } + return left; } void quicker_sort(EDGE *left, EDGE *right) { - EDGE *p; - float pivot; + EDGE *p; + float pivot; - if (find_pivot(left, right, &pivot) == yes) - { - p = partition(left, right, pivot); - quicker_sort(left, p - 1); - quicker_sort(p, right); - } + if (find_pivot(left, right, &pivot) == yes) + { + p = partition(left, right, pivot); + quicker_sort(left, p - 1); + quicker_sort(p, right); + } } - //--------------end quicker_sort algorithm ----------------------------------- //--------------------start initialize pixels ---------------------------------- //initialize pixels. See the explination of the pixel class above. //initially every pixel is assumed to belong to a group consisting of only itself -void initialisePIXELs(float *WrappedImage, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) +void initialisePIXELs(float *wrapped_image, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) { - PIXELM *pixel_pointer = pixel; - float *wrapped_image_pointer = WrappedImage; - unsigned char *input_mask_pointer = input_mask; - unsigned char *extended_mask_pointer = extended_mask; - int i, j; + PIXELM *pixel_pointer = pixel; + float *wrapped_image_pointer = wrapped_image; + unsigned char *input_mask_pointer = input_mask; + unsigned char *extended_mask_pointer = extended_mask; + int i, j; - for (i=0; i < image_height; i++) + for (i=0; i < image_height; i++) + { + for (j=0; j < image_width; j++) { - for (j=0; j < image_width; j++) - { - pixel_pointer->increment = 0; - pixel_pointer->number_of_pixels_in_group = 1; - pixel_pointer->value = *wrapped_image_pointer; - pixel_pointer->reliability = 9999999 + rand(); - pixel_pointer->input_mask = *input_mask_pointer; - pixel_pointer->extended_mask = *extended_mask_pointer; - pixel_pointer->head = pixel_pointer; - pixel_pointer->last = pixel_pointer; - pixel_pointer->next = NULL; - pixel_pointer->new_group = 0; - pixel_pointer->group = -1; - pixel_pointer++; - wrapped_image_pointer++; - input_mask_pointer++; - extended_mask_pointer++; - } + pixel_pointer->increment = 0; + pixel_pointer->number_of_pixels_in_group = 1; + pixel_pointer->value = *wrapped_image_pointer; + pixel_pointer->reliability = 9999999 + rand(); + pixel_pointer->input_mask = *input_mask_pointer; + pixel_pointer->extended_mask = *extended_mask_pointer; + pixel_pointer->head = pixel_pointer; + pixel_pointer->last = pixel_pointer; + pixel_pointer->next = NULL; + pixel_pointer->new_group = 0; + pixel_pointer->group = -1; + pixel_pointer++; + wrapped_image_pointer++; + input_mask_pointer++; + extended_mask_pointer++; } + } } //-------------------end initialize pixels ----------- //gamma function in the paper float wrap(float pixel_value) { - float wrapped_pixel_value; - if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; - else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; - else wrapped_pixel_value = pixel_value; - return wrapped_pixel_value; + float wrapped_pixel_value; + if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; + else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; + else wrapped_pixel_value = pixel_value; + return wrapped_pixel_value; } // pixelL_value is the left pixel, pixelR_value is the right pixel int find_wrap(float pixelL_value, float pixelR_value) { - float difference; - int wrap_value; - difference = pixelL_value - pixelR_value; + float difference; + int wrap_value; + difference = pixelL_value - pixelR_value; - if (difference > PI) wrap_value = -1; - else if (difference < -PI) wrap_value = 1; - else wrap_value = 0; + if (difference > PI) wrap_value = -1; + else if (difference < -PI) wrap_value = 1; + else wrap_value = 0; - return wrap_value; + return wrap_value; } void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int image_width, int image_height, params_t *params) { - int i,j; - int image_width_plus_one = image_width + 1; - int image_width_minus_one = image_width - 1; - unsigned char *IMP = input_mask + image_width + 1; //input mask pointer - unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer + int i,j; + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + unsigned char *IMP = input_mask + image_width + 1; //input mask pointer + unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer - //extend the mask for the image except borders - for (i=1; i < image_height - 1; ++i) + //extend the mask for the image except borders + for (i=1; i < image_height - 1; ++i) + { + for (j=1; j < image_width - 1; ++j) { - for (j=1; j < image_width - 1; ++j) - { - if ( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && - (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && - (*(IMP - image_width_minus_one) == NOMASK) && (*(IMP - image_width_plus_one) == NOMASK) && - (*(IMP + image_width_minus_one) == NOMASK) && (*(IMP + image_width_plus_one) == NOMASK) ) - { - *EMP = NOMASK; - } - ++EMP; - ++IMP; - } - EMP += 2; - IMP += 2; + if ( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width_minus_one) == NOMASK) && (*(IMP - image_width_plus_one) == NOMASK) && + (*(IMP + image_width_minus_one) == NOMASK) && (*(IMP + image_width_plus_one) == NOMASK) ) + { + *EMP = NOMASK; + } + ++EMP; + ++IMP; } + EMP += 2; + IMP += 2; + } - if (params->x_connectivity == 1) + if (params->x_connectivity == 1) + { + //extend the mask for the right border of the image + IMP = input_mask + 2 * image_width - 1; + EMP = extended_mask + 2 * image_width -1; + for (i=1; i < image_height - 1; ++ i) { - //extend the mask for the right border of the image - IMP = input_mask + 2 * image_width - 1; - EMP = extended_mask + 2 * image_width -1; - for (i=1; i < image_height - 1; ++ i) - { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && - (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && - (*(IMP + image_width - 1) == NOMASK) && (*(IMP - 2 * image_width + 1) == NOMASK) ) - { - *EMP = NOMASK; - } - EMP += image_width; - IMP += image_width; - } - - //extend the mask for the left border of the image - IMP = input_mask + image_width; - EMP = extended_mask + image_width; - for (i=1; i < image_height - 1; ++i) - { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && - (*(IMP - image_width + 1) == NOMASK) && (*(IMP + image_width + 1) == NOMASK) && - (*(IMP + image_width - 1) == NOMASK) && (*(IMP + 2 * image_width - 1) == NOMASK) ) - { - *EMP = NOMASK; - } - EMP += image_width; - IMP += image_width; - } + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && + (*(IMP + image_width - 1) == NOMASK) && (*(IMP - 2 * image_width + 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP += image_width; + IMP += image_width; } - if (params->y_connectivity == 1) + //extend the mask for the left border of the image + IMP = input_mask + image_width; + EMP = extended_mask + image_width; + for (i=1; i < image_height - 1; ++i) { - //extend the mask for the top border of the image - IMP = input_mask + 1; - EMP = extended_mask + 1; - for (i=1; i < image_width - 1; ++i) - { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP + image_width) == NOMASK) && (*(IMP + image_width * (image_height - 1)) == NOMASK) && - (*(IMP + image_width + 1) == NOMASK) && (*(IMP + image_width - 1) == NOMASK) && - (*(IMP + image_width * (image_height - 1) - 1) == NOMASK) && (*(IMP + image_width * (image_height - 1) + 1) == NOMASK) ) - { - *EMP = NOMASK; - } - EMP++; - IMP++; - } + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width + 1) == NOMASK) && (*(IMP + image_width + 1) == NOMASK) && + (*(IMP + image_width - 1) == NOMASK) && (*(IMP + 2 * image_width - 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP += image_width; + IMP += image_width; + } + } - //extend the mask for the bottom border of the image - IMP = input_mask + image_width * (image_height - 1) + 1; - EMP = extended_mask + image_width * (image_height - 1) + 1; - for (i=1; i < image_width - 1; ++i) - { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP - image_width) == NOMASK) && (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && - (*(IMP - image_width * (image_height - 1) ) == NOMASK) && - (*(IMP - image_width * (image_height - 1) - 1) == NOMASK) && - (*(IMP - image_width * (image_height - 1) + 1) == NOMASK) ) - { - *EMP = NOMASK; - } - EMP++; - IMP++; - } - } + if (params->y_connectivity == 1) + { + //extend the mask for the top border of the image + IMP = input_mask + 1; + EMP = extended_mask + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP + image_width * (image_height - 1)) == NOMASK) && + (*(IMP + image_width + 1) == NOMASK) && (*(IMP + image_width - 1) == NOMASK) && + (*(IMP + image_width * (image_height - 1) - 1) == NOMASK) && (*(IMP + image_width * (image_height - 1) + 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP++; + IMP++; + } + + //extend the mask for the bottom border of the image + IMP = input_mask + image_width * (image_height - 1) + 1; + EMP = extended_mask + image_width * (image_height - 1) + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP - image_width) == NOMASK) && (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && + (*(IMP - image_width * (image_height - 1) ) == NOMASK) && + (*(IMP - image_width * (image_height - 1) - 1) == NOMASK) && + (*(IMP - image_width * (image_height - 1) + 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP++; + IMP++; + } + } } void calculate_reliability(float *wrappedImage, PIXELM *pixel, int image_width, int image_height, params_t *params) { - int image_width_plus_one = image_width + 1; - int image_width_minus_one = image_width - 1; - PIXELM *pixel_pointer = pixel + image_width_plus_one; - float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer - float H, V, D1, D2; - int i, j; + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + PIXELM *pixel_pointer = pixel + image_width_plus_one; + float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer + float H, V, D1, D2; + int i, j; - for (i = 1; i < image_height -1; ++i) + for (i = 1; i < image_height -1; ++i) + { + for (j = 1; j < image_width - 1; ++j) { - for (j = 1; j < image_width - 1; ++j) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - pixel_pointer += 2; - WIP += 2; + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + pixel_pointer += 2; + WIP += 2; + } + + if (params->x_connectivity == 1) + { + //calculating the reliability for the left border of the image + PIXELM *pixel_pointer = pixel + image_width; + float *WIP = wrappedImage + image_width; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; } - if (params->x_connectivity == 1) + //calculating the reliability for the right border of the image + pixel_pointer = pixel + 2 * image_width - 1; + WIP = wrappedImage + 2 * image_width - 1; + + for (i = 1; i < image_height - 1; ++i) { - //calculating the reliability for the left border of the image - PIXELM *pixel_pointer = pixel + image_width; - float *WIP = wrappedImage + image_width; - - for (i = 1; i < image_height - 1; ++i) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer += image_width; - WIP += image_width; - } + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); + D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + } - //calculating the reliability for the right border of the image - pixel_pointer = pixel + 2 * image_width - 1; - WIP = wrappedImage + 2 * image_width - 1; + if (params->y_connectivity == 1) + { + //calculating the reliability for the top border of the image + PIXELM *pixel_pointer = pixel + 1; + float *WIP = wrappedImage + 1; - for (i = 1; i < image_height - 1; ++i) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); - D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer += image_width; - WIP += image_width; - } + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; } - if (params->y_connectivity == 1) + //calculating the reliability for the bottom border of the image + pixel_pointer = pixel + (image_height - 1) * image_width + 1; + WIP = wrappedImage + (image_height - 1) * image_width + 1; + + for (i = 1; i < image_width - 1; ++i) { - //calculating the reliability for the top border of the image - PIXELM *pixel_pointer = pixel + 1; - float *WIP = wrappedImage + 1; - - for (i = 1; i < image_width - 1; ++i) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - - //calculating the reliability for the bottom border of the image - pixel_pointer = pixel + (image_height - 1) * image_width + 1; - WIP = wrappedImage + (image_height - 1) * image_width + 1; - - for (i = 1; i < image_width - 1; ++i) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; } + } } //calculate the reliability of the horizontal edges of the image @@ -423,45 +421,45 @@ void horizontalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height, params_t *params) { - int i, j; - EDGE *edge_pointer = edge; - PIXELM *pixel_pointer = pixel; + int i, j; + EDGE *edge_pointer = edge; + PIXELM *pixel_pointer = pixel; - for (i = 0; i < image_height; i++) + for (i = 0; i < image_height; i++) + { + for (j = 0; j < image_width - 1; j++) { - for (j = 0; j < image_width - 1; j++) - { - if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + 1)->input_mask == NOMASK) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer+1); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } - pixel_pointer++; + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + 1)->input_mask == NOMASK) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer+1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; } - //construct edges at the right border of the image - if (params->x_connectivity == 1) + pixel_pointer++; + } + //construct edges at the right border of the image + if (params->x_connectivity == 1) + { + pixel_pointer = pixel + image_width - 1; + for (i = 0; i < image_height; i++) { - pixel_pointer = pixel + image_width - 1; - for (i = 0; i < image_height; i++) - { - if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width + 1)->input_mask == NOMASK) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer+=image_width; - } + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width + 1)->input_mask == NOMASK) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer+=image_width; } + } } //calculate the reliability of the vertical edges of the image @@ -471,256 +469,258 @@ void verticalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height, params_t *params) { - int i, j; - PIXELM *pixel_pointer = pixel; - EDGE *edge_pointer = edge + No_of_edges; + int i, j; + PIXELM *pixel_pointer = pixel; + EDGE *edge_pointer = edge + No_of_edges; - for (i=0; i < image_height - 1; i++) + for (i=0; i < image_height - 1; i++) + { + for (j=0; j < image_width; j++) { - for (j=0; j < image_width; j++) - { - if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + image_width)->input_mask == NOMASK) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer + image_width); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } //j loop - } // i loop + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + image_width)->input_mask == NOMASK) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer + image_width); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; + } //j loop + } // i loop - //construct edges that connect at the bottom border of the image - if (params->y_connectivity == 1) + //construct edges that connect at the bottom border of the image + if (params->y_connectivity == 1) + { + pixel_pointer = pixel + image_width *(image_height - 1); + for (i = 0; i < image_width; i++) { - pixel_pointer = pixel + image_width *(image_height - 1); - for (i = 0; i < image_width; i++) - { - if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width *(image_height - 1))->input_mask == NOMASK) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); - edge_pointer++; - No_of_edges++; - } - pixel_pointer++; - } + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width *(image_height - 1))->input_mask == NOMASK) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); + edge_pointer++; + No_of_edges++; + } + pixel_pointer++; } + } } //gather the pixels of the image into groups void gatherPIXELs(EDGE *edge, int image_width, int image_height) { - int k; - PIXELM *PIXEL1; - PIXELM *PIXEL2; - PIXELM *group1; - PIXELM *group2; - EDGE *pointer_edge = edge; - int incremento; + int k; + PIXELM *PIXEL1; + PIXELM *PIXEL2; + PIXELM *group1; + PIXELM *group2; + EDGE *pointer_edge = edge; + int incremento; - for (k = 0; k < No_of_edges; k++) + for (k = 0; k < No_of_edges; k++) + { + PIXEL1 = pointer_edge->pointer_1; + PIXEL2 = pointer_edge->pointer_2; + + //PIXELM 1 and PIXELM 2 belong to different groups + //initially each pixel is a group by it self and one pixel can construct a group + //no else or else if to this if + if (PIXEL2->head != PIXEL1->head) { - PIXEL1 = pointer_edge->pointer_1; - PIXEL2 = pointer_edge->pointer_2; + //PIXELM 2 is alone in its group + //merge this pixel with PIXELM 1 group and find the number of 2 pi to add + //to or subtract to unwrap it + if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) + { + PIXEL1->head->last->next = PIXEL2; + PIXEL1->head->last = PIXEL2; + (PIXEL1->head->number_of_pixels_in_group)++; + PIXEL2->head=PIXEL1->head; + PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; + } - //PIXELM 1 and PIXELM 2 belong to different groups - //initially each pixel is a group by it self and one pixel can construct a group - //no else or else if to this if - if (PIXEL2->head != PIXEL1->head) - { - //PIXELM 2 is alone in its group - //merge this pixel with PIXELM 1 group and find the number of 2 pi to add - //to or subtract to unwrap it - if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) - { - PIXEL1->head->last->next = PIXEL2; - PIXEL1->head->last = PIXEL2; - (PIXEL1->head->number_of_pixels_in_group)++; - PIXEL2->head=PIXEL1->head; - PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; - } + //PIXELM 1 is alone in its group + //merge this pixel with PIXELM 2 group and find the number of 2 pi to add + //to or subtract to unwrap it + else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) + { + PIXEL2->head->last->next = PIXEL1; + PIXEL2->head->last = PIXEL1; + (PIXEL2->head->number_of_pixels_in_group)++; + PIXEL1->head = PIXEL2->head; + PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; + } - //PIXELM 1 is alone in its group - //merge this pixel with PIXELM 2 group and find the number of 2 pi to add - //to or subtract to unwrap it - else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) - { - PIXEL2->head->last->next = PIXEL1; - PIXEL2->head->last = PIXEL1; - (PIXEL2->head->number_of_pixels_in_group)++; - PIXEL1->head = PIXEL2->head; - PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; - } - - //PIXELM 1 and PIXELM 2 both have groups - else + //PIXELM 1 and PIXELM 2 both have groups + else { - group1 = PIXEL1->head; - group2 = PIXEL2->head; - //if the no. of pixels in PIXELM 1 group is larger than the no. of pixels - //in PIXELM 2 group. Merge PIXELM 2 group to PIXELM 1 group - //and find the number of wraps between PIXELM 2 group and PIXELM 1 group - //to unwrap PIXELM 2 group with respect to PIXELM 1 group. - //the no. of wraps will be added to PIXELM 2 grop in the future - if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) - { - //merge PIXELM 2 with PIXELM 1 group - group1->last->next = group2; - group1->last = group2->last; - group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; - incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; - //merge the other pixels in PIXELM 2 group to PIXELM 1 group - while (group2 != NULL) - { - group2->head = group1; - group2->increment += incremento; - group2 = group2->next; - } - } + group1 = PIXEL1->head; + group2 = PIXEL2->head; + //if the no. of pixels in PIXELM 1 group is larger than the + //no. of pixels in PIXELM 2 group. Merge PIXELM 2 group to + //PIXELM 1 group and find the number of wraps between PIXELM 2 + //group and PIXELM 1 group to unwrap PIXELM 2 group with respect + //to PIXELM 1 group. the no. of wraps will be added to PIXELM 2 + //group in the future + if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) + { + //merge PIXELM 2 with PIXELM 1 group + group1->last->next = group2; + group1->last = group2->last; + group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; + incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group2 != NULL) + { + group2->head = group1; + group2->increment += incremento; + group2 = group2->next; + } + } - //if the no. of pixels in PIXELM 2 group is larger than the no. of pixels - //in PIXELM 1 group. Merge PIXELM 1 group to PIXELM 2 group - //and find the number of wraps between PIXELM 2 group and PIXELM 1 group - //to unwrap PIXELM 1 group with respect to PIXELM 2 group. - //the no. of wraps will be added to PIXELM 1 grop in the future - else + //if the no. of pixels in PIXELM 2 group is larger than the + //no. of pixels in PIXELM 1 group. Merge PIXELM 1 group to + //PIXELM 2 group and find the number of wraps between PIXELM 2 + //group and PIXELM 1 group to unwrap PIXELM 1 group with respect + //to PIXELM 2 group. the no. of wraps will be added to PIXELM 1 + //group in the future + else { - //merge PIXELM 1 with PIXELM 2 group - group2->last->next = group1; - group2->last = group1->last; - group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; - incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; - //merge the other pixels in PIXELM 2 group to PIXELM 1 group - while (group1 != NULL) - { - group1->head = group2; - group1->increment += incremento; - group1 = group1->next; - } // while + //merge PIXELM 1 with PIXELM 2 group + group2->last->next = group1; + group2->last = group1->last; + group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; + incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group1 != NULL) + { + group1->head = group2; + group1->increment += incremento; + group1 = group1->next; + } // while } // else } //else } //if - pointer_edge++; - } + pointer_edge++; + } } //unwrap the image void unwrapImage(PIXELM *pixel, int image_width, int image_height) { - int i; - int image_size = image_width * image_height; - PIXELM *pixel_pointer=pixel; + int i; + int image_size = image_width * image_height; + PIXELM *pixel_pointer=pixel; - for (i = 0; i < image_size; i++) - { - pixel_pointer->value += TWOPI * (float)(pixel_pointer->increment); - pixel_pointer++; + for (i = 0; i < image_size; i++) + { + pixel_pointer->value += TWOPI * (float)(pixel_pointer->increment); + pixel_pointer++; } } //set the masked pixels (mask = 0) to the minimum of the unwrapper phase void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int image_height) { - int image_width_plus_one = image_width + 1; - int image_height_plus_one = image_height + 1; - int image_width_minus_one = image_width - 1; - int image_height_minus_one = image_height - 1; + int image_width_plus_one = image_width + 1; + int image_height_plus_one = image_height + 1; + int image_width_minus_one = image_width - 1; + int image_height_minus_one = image_height - 1; - PIXELM *pointer_pixel = pixel; - unsigned char *IMP = input_mask; //input mask pointer - float min=99999999.; - int i, j; - int image_size = image_width * image_height; + PIXELM *pointer_pixel = pixel; + unsigned char *IMP = input_mask; //input mask pointer + float min=99999999.; + int i, j; + int image_size = image_width * image_height; - //find the minimum of the unwrapped phase - for (i = 0; i < image_size; i++) + //find the minimum of the unwrapped phase + for (i = 0; i < image_size; i++) + { + if ((pointer_pixel->value < min) && (*IMP == NOMASK)) + min = pointer_pixel->value; + + pointer_pixel++; + IMP++; + } + + pointer_pixel = pixel; + IMP = input_mask; + + //set the masked pixels to minimum + for (i = 0; i < image_size; i++) + { + if ((*IMP) == MASK) { - if ((pointer_pixel->value < min) && (*IMP == NOMASK)) - min = pointer_pixel->value; - - pointer_pixel++; - IMP++; - } - - pointer_pixel = pixel; - IMP = input_mask; - - //set the masked pixels to minimum - for (i = 0; i < image_size; i++) - { - if ((*IMP) == MASK) - { - pointer_pixel->value = min; - } - pointer_pixel++; - IMP++; + pointer_pixel->value = min; } + pointer_pixel++; + IMP++; + } } //the input to this unwrapper is an array that contains the wrapped //phase map. copy the image on the buffer passed to this unwrapper to //over-write the unwrapped phase map on the buffer of the wrapped //phase map. -void returnImage(PIXELM *pixel, float *unwrappedImage, int image_width, int image_height) +void returnImage(PIXELM *pixel, float *unwrapped_image, int image_width, int image_height) { int i; int image_size = image_width * image_height; - float *unwrappedImage_pointer = unwrappedImage; + float *unwrapped_image_pointer = unwrapped_image; PIXELM *pixel_pointer = pixel; for (i=0; i < image_size; i++) { - *unwrappedImage_pointer = pixel_pointer->value; + *unwrapped_image_pointer = pixel_pointer->value; pixel_pointer++; - unwrappedImage_pointer++; + unwrapped_image_pointer++; } } //the main function of the unwrapper -int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask, +int unwrap(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, int image_width, int image_height, int wrap_around_x, int wrap_around_y) { - unsigned char *extended_mask; - int image_size = image_height * image_width; - int No_of_Edges_initially = 2 * image_width * image_height; - params_t params = {TWOPI, 0, 0, 0}; + unsigned char *extended_mask; + int image_size = image_height * image_width; + int No_of_Edges_initially = 2 * image_width * image_height; + params_t params = {TWOPI, 0, 0, 0}; - extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); - PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); - EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; + extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); + PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); + EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; - extend_mask(input_mask, extended_mask, image_width, image_height, ¶ms); - initialisePIXELs(WrappedImage, input_mask, extended_mask, pixel, image_width, image_height); - calculate_reliability(WrappedImage, pixel, image_width, image_height, ¶ms); - horizontalEDGEs(pixel, edge, image_width, image_height, ¶ms); - verticalEDGEs(pixel, edge, image_width, image_height, ¶ms); + extend_mask(input_mask, extended_mask, image_width, image_height, ¶ms); + initialisePIXELs(wrapped_image, input_mask, extended_mask, pixel, image_width, image_height); + calculate_reliability(wrapped_image, pixel, image_width, image_height, ¶ms); + horizontalEDGEs(pixel, edge, image_width, image_height, ¶ms); + verticalEDGEs(pixel, edge, image_width, image_height, ¶ms); - //sort the EDGEs depending on their reiability. The PIXELs with higher - //relibility (small value) first - quicker_sort(edge, edge + No_of_edges - 1); + //sort the EDGEs depending on their reiability. The PIXELs with higher + //relibility (small value) first + quicker_sort(edge, edge + No_of_edges - 1); - //gather PIXELs into groups - gatherPIXELs(edge, image_width, image_height); + //gather PIXELs into groups + gatherPIXELs(edge, image_width, image_height); - unwrapImage(pixel, image_width, image_height); - maskImage(pixel, input_mask, image_width, image_height); + unwrapImage(pixel, image_width, image_height); + maskImage(pixel, input_mask, image_width, image_height); - //copy the image from PIXELM structure to the unwrapped phase array - //passed to this function - returnImage(pixel, UnwrappedImage, image_width, image_height); + //copy the image from PIXELM structure to the unwrapped phase array + //passed to this function + returnImage(pixel, UnwrappedImage, image_width, image_height); - free(edge); - free(pixel); - free(extended_mask); + free(edge); + free(pixel); + free(extended_mask); - No_of_edges = 0; - return 1; + No_of_edges = 0; + return 1; } diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx index ac4a3d33..d49eaf1f 100644 --- a/unwrap2D/unwrap2D.pyx +++ b/unwrap2D/unwrap2D.pyx @@ -10,6 +10,7 @@ def unwrap2D(float[:,::1] array, unsigned char[:,::1] mask, cdef float[:,::1] unwrapped_array = np.empty_like(array) cdef int h = array.shape[0] cdef int w = array.shape[1] + #TODO: check for masked array/ unwrap(&array[0,0], &unwrapped_array[0,0], &mask[0,0], From 0682b0ed5271b0b06d660435520f3af1fafeac5c Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sun, 13 May 2012 00:12:24 +0200 Subject: [PATCH 09/84] unwrap: accept (and return if given) an masked array as input argument --- unwrap2D/test_unwrap.py | 23 ++++++++++++++++++----- unwrap2D/unwrap2D.pyx | 25 ++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/unwrap2D/test_unwrap.py b/unwrap2D/test_unwrap.py index b6cdd33c..930cf18b 100644 --- a/unwrap2D/test_unwrap.py +++ b/unwrap2D/test_unwrap.py @@ -4,9 +4,10 @@ from unwrap2D import unwrap2D import numpy as np from numpy import outer, arange, ones, abs, empty, power, indices +import numpy.ma as ma def test_unwrap2D(): - nx, ny = 10, 10 + nx, ny = 32, 32 x = np.arange(nx) y = np.arange(ny) x.shape = (1,-1) @@ -14,10 +15,15 @@ def test_unwrap2D(): z = np.exp(1j*x*0.2*np.pi) * np.exp(1j*y*0.1*np.pi) phi_w = np.angle(z) + phi = unwrap2D(phi_w) + mask = 0*np.ones((nx, ny), dtype = np.uint8) - mask[4:6, 5:7] = 1 - phi = unwrap2D(phi_w.astype(np.float32), mask) - return phi_w/(np.pi*2), np.asarray(phi)/(np.pi*2) + mask[4:16, 4:16] = 1 + phi_w_ma = ma.array(phi_w, dtype = np.float32, mask = mask) + phi_ma = unwrap2D(phi_w_ma) + + return (phi_w/(np.pi*2), phi/(np.pi*2), + phi_w_ma/(np.pi*2), phi_ma/(np.pi*2),) # class test_unwrap(TestCase): @@ -46,8 +52,15 @@ def test_unwrap2D(): if __name__=="__main__": #NumpyTest().run() import matplotlib.pyplot as plt - p,p2 = test_unwrap2D() + p1,p2,p3,p4 = test_unwrap2D() plt.clf() + plt.subplot(221) + plt.imshow(p1,interpolation = 'nearest') + plt.subplot(222) plt.imshow(p2, interpolation = 'nearest') + plt.subplot(223) + plt.imshow(p3, interpolation = 'nearest') + plt.subplot(224) + plt.imshow(p4, interpolation = 'nearest') plt.draw() plt.show() diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx index d49eaf1f..9d734dec 100644 --- a/unwrap2D/unwrap2D.pyx +++ b/unwrap2D/unwrap2D.pyx @@ -1,12 +1,31 @@ import numpy as np cimport numpy as np -cdef extern int unwrap(float* WrappedImage, float* UnwrappedImage, unsigned char* input_mask, +import numpy.ma + +cdef extern int unwrap(float* wrapped_image, + float* unwrapped_image, + unsigned char* input_mask, int image_width, int image_height, int wrap_around_x, int wrap_around_y) -def unwrap2D(float[:,::1] array, unsigned char[:,::1] mask, - wrap_around_x = False, wrap_around_y = False): +def unwrap2D(input, wrap_around_x = False, wrap_around_y = False): + + masked_array = numpy.ma.asarray(input, dtype = np.float32) + unwrapped_array = _unwrap2D(masked_array.data, + numpy.ma.getmaskarray(masked_array).astype(np.uint8), + wrap_around_x, wrap_around_y) + if numpy.ma.isarray(input): + return numpy.ma.array(unwrapped_array, mask = input.mask) + else: + return unwrapped_array + + #TODO: set_fill to minimum value + + +cdef _unwrap2D(float[:,::1] array, + unsigned char[:,::1] mask, + wrap_around_x, wrap_around_y): cdef float[:,::1] unwrapped_array = np.empty_like(array) cdef int h = array.shape[0] cdef int w = array.shape[1] From c61ae90a4dc12a3779cc443ada970370724c5432 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sun, 13 May 2012 18:04:06 +0200 Subject: [PATCH 10/84] unwrap: added original 3D unwrapped code --- ...apper_with_mask_and_wrap_around_option.cpp | 1088 +++++++++++++++++ 1 file changed, 1088 insertions(+) create mode 100644 unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp diff --git a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp new file mode 100644 index 00000000..6a4c8308 --- /dev/null +++ b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp @@ -0,0 +1,1088 @@ +//This program was written by Hussein Abdul-Rahman and Munther Gdeisat to program the three-dimensional phase unwrapper +//entitled "Fast three-dimensional phase-unwrapping algorithm based on sorting by +//reliability following a noncontinuous path" +//by Hussein Abdul-Rahman, Munther A. Gdeisat, David R. Burton, and Michael J. Lalor, +//published in the Proceedings of SPIE - +//The International Society for Optical Engineering, Vol. 5856, No. 1, 2005, pp. 32-40 +//This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. +//Date 31st August 2007 +//The wrapped phase volume is assumed to be of floating point data type. The resultant unwrapped phase volume is also of floating point type. +//Read the data from the file frame by frame +//The mask is of byte data type. +//When the mask is 255 this means that the voxel is valid +//When the mask is 0 this means that the voxel is invalid (noisy or corrupted voxel) +//This program takes into consideration the image wrap around problem encountered in MRI imaging. + +#include +//#include "stdafx.h" +#include +#include +#include + +static float PI = 3.141592654; +static float TWOPI = 6.283185307; +int x_connectivity = 1; +int y_connectivity = 1; +int z_connectivity = 1 +; +int No_of_edges = 0; + +//VOXELM information +struct VOXELM +{ + //int x; //x coordinate of the voxel + //int y; //y coordinate + //int z; //z coordinate + int increment; //No. of 2*pi to add to the voxel to unwrap it + int number_of_voxels_in_group; //No. of voxel in the voxel group + float value; //value of the voxel + float reliability; + unsigned char input_mask; //0 voxel is masked. 255 voxel is not masked + unsigned char extended_mask; //0 voxel is masked. 255 voxel is not masked + int group; //group No. + int new_group; + struct VOXELM *head; //pointer to the first voxel in the group in the linked list + struct VOXELM *last; //pointer to the last voxel in the group + struct VOXELM *next; //pointer to the next voxel in the group +}; + + +//the EDGE is the line that connects two voxels. +//if we have S voxels, then we have S horizontal edges and S vertical edges +struct EDGE +{ + float reliab; //reliabilty of the edge and it depends on the two voxels + VOXELM *pointer_1; //pointer to the first voxel + VOXELM *pointer_2; //pointer to the second voxel + int increment; //No. of 2*pi to add to one of the voxels to unwrap it with respect to the second +}; + +void read_data(char *inputfile,float *Data, int length) +{ + printf("Reading the Wrapped Values from Binary File.............>"); + FILE *ifptr; + ifptr = fopen(inputfile,"rb"); + if(ifptr == NULL) printf("Error opening the file\n"); + fread(Data,sizeof(float),length,ifptr); + fclose(ifptr); + printf(" Done.\n"); +} + +void write_data(char *outputfile,float *Data,int length) +{ + printf("Writing the Wrapped Values to Binary File.............>"); + FILE *ifptr; + ifptr = fopen(outputfile,"wb"); + if(ifptr == NULL) printf("Error opening the file\n"); + fwrite(Data,sizeof(float),length,ifptr); + fclose(ifptr); + printf(" Done.\n"); +} + +void read_mask(char *inputfile,unsigned char *Data, int length) +{ + printf("Reading the mask from Binary File.............>"); + FILE *ifptr; + ifptr = fopen(inputfile,"rb"); + if(ifptr == NULL) printf("Error opening the file\n"); + fread(Data,sizeof(char),length,ifptr); + fclose(ifptr); + printf(" Done.\n"); +} +//---------------start quicker_sort algorithm -------------------------------- +#define swap(x,y) {EDGE t; t=x; x=y; y=t;} +#define order(x,y) if (x.reliab > y.reliab) swap(x,y) +#define o2(x,y) order(x,y) +#define o3(x,y,z) o2(x,y); o2(x,z); o2(y,z) + +typedef enum {yes, no} yes_no; + +yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) +{ + EDGE a, b, c, *p; + + a = *left; + b = *(left + (right - left) /2 ); + c = *right; + o3(a,b,c); + + if (a.reliab < b.reliab) + { + *pivot_ptr = b.reliab; + return yes; + } + + if (b.reliab < c.reliab) + { + *pivot_ptr = c.reliab; + return yes; + } + + for (p = left + 1; p <= right; ++p) + { + if (p->reliab != left->reliab) + { + *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; + return yes; + } + return no; + } +} + +EDGE *partition(EDGE *left, EDGE *right, float pivot) +{ + while (left <= right) + { + while (left->reliab < pivot) + ++left; + while (right->reliab >= pivot) + --right; + if (left < right) + { + swap (*left, *right); + ++left; + --right; + } + } + return left; +} + +void quicker_sort(EDGE *left, EDGE *right) +{ + EDGE *p; + float pivot; + + if (find_pivot(left, right, &pivot) == yes) + { + p = partition(left, right, pivot); + quicker_sort(left, p - 1); + quicker_sort(p, right); + } +} + +//--------------end quicker_sort algorithm ----------------------------------- + +//--------------------start initialse voxels ---------------------------------- +//initialse voxels. See the explanation of the voxel class above. +//initially every voxel is assumed to belong to a group consisting of only itself +void initialiseVOXELs(float *WrappedVolume, unsigned char *input_mask, unsigned char *extended_mask, VOXELM *voxel, int volume_width, int volume_height, int volume_depth) +{ + VOXELM *voxel_pointer = voxel; + float *wrapped_volume_pointer = WrappedVolume; + unsigned char *input_mask_pointer = input_mask; + unsigned char *extended_mask_pointer = extended_mask; + int n, i, j; + + for (n=0; n < volume_depth; n++) + { + for (i=0; i < volume_height; i++) + { + for (j=0; j < volume_width; j++) + { + //voxel_pointer->x = j; + //voxel_pointer->y = i; + //voxel_pointer->z = n; + voxel_pointer->increment = 0; + voxel_pointer->number_of_voxels_in_group = 1; + voxel_pointer->value = *wrapped_volume_pointer; + voxel_pointer->reliability = 9999999 + rand(); + voxel_pointer->input_mask = *input_mask_pointer; + voxel_pointer->extended_mask = *extended_mask_pointer; + voxel_pointer->head = voxel_pointer; + voxel_pointer->last = voxel_pointer; + voxel_pointer->next = NULL; + voxel_pointer->new_group = 0; + voxel_pointer->group = -1; + voxel_pointer++; + wrapped_volume_pointer++; + input_mask_pointer++; + extended_mask_pointer++; + } + } + } +} +//-------------------end initialise voxels ----------- + +//gamma function in the paper +float wrap(float voxel_value) +{ + float wrapped_voxel_value; + if (voxel_value > PI) wrapped_voxel_value = voxel_value - TWOPI; + else if (voxel_value < -PI) wrapped_voxel_value = voxel_value + TWOPI; + else wrapped_voxel_value = voxel_value; + return wrapped_voxel_value; +} + +// voxelL_value is the left voxel, voxelR_value is the right voxel +int find_wrap(float voxelL_value, float voxelR_value) +{ + float difference; + int wrap_value; + difference = voxelL_value - voxelR_value; + + if (difference > PI) wrap_value = -1; + else if (difference < -PI) wrap_value = 1; + else wrap_value = 0; + + return wrap_value; +} + +void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int volume_width, int volume_height, int volume_depth) +{ + int n, i, j; + int vw = volume_width, vh = volume_height, vd = volume_depth; + int fs = volume_width * volume_height; //frame size + int frame_size = volume_width * volume_height; + int volume_size = volume_width * volume_height * volume_depth; //volume size + int vs = volume_size; + unsigned char *IMP = input_mask + frame_size + volume_width + 1; //input mask pointer + unsigned char *EMP = extended_mask + frame_size + volume_width + 1; //extended mask pointer + + //extend the mask for the volume except borders + for (n=1; n < volume_depth - 1; n++) + { + for (i=1; i < volume_height - 1; i++) + { + for (j=1; j < volume_width - 1; j++) + { + if( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + vw) == 255) && (*(IMP + vw - 1) == 255) && (*(IMP + vw + 1) == 255) && + (*(IMP - vw) == 255) && (*(IMP - vw - 1) == 255) && (*(IMP - vw + 1) == 255) && + (*(IMP + fs) == 255) && (*(IMP + fs - 1) == 255) && (*(IMP + fs + 1) == 255) && + (*(IMP + fs - vw) == 255) && (*(IMP + fs - vw - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && + (*(IMP + fs + vw) == 255) && (*(IMP + fs + vw - 1) == 255) && (*(IMP + fs + vw + 1) == 255) && + (*(IMP - fs) == 255) && (*(IMP - fs - 1) == 255) && (*(IMP - fs + 1) == 255) && + (*(IMP - fs - vw) == 255) && (*(IMP - fs - vw - 1) == 255) && (*(IMP - fs - vw + 1) == 255) && + (*(IMP - fs + vw) == 255) && (*(IMP - fs + vw - 1) == 255) && (*(IMP - fs + vw + 1) == 255)) + { + *EMP = 255; + } + ++EMP; + ++IMP; + } + EMP += 2; + IMP += 2; + } + EMP += 2 * volume_width; + IMP += 2 * volume_width; + } + + if (x_connectivity == 1) + { + //extend the mask to the front side of the phase volume + IMP = input_mask + frame_size + volume_width; //input mask pointer + EMP = extended_mask + frame_size + volume_width; //extended mask pointer + for (n=1; n < volume_depth - 1; n++) + { + for (i=1; i < volume_height - 1; i++) + { + if( (*IMP) == 255 && (*(IMP + vw - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP - vw) == 255) && (*(IMP + vw) == 255) && + (*(IMP - fs) == 255) && (*(IMP + fs) == 255) && + (*(IMP - 1) == 255) && (*(IMP + vw + 1) == 255) && + (*(IMP - vw + 1) == 255) && (*(IMP + 2 * vw - 1) == 255) && + (*(IMP - fs - 1) == 255) && (*(IMP + fs + vw + 1) == 255) && + (*(IMP - fs - vw) == 255) && (*(IMP + fs + vw) == 255) && + (*(IMP - fs - vw + 1) == 255) && (*(IMP + fs + 2 * vw - 1) == 255) && + (*(IMP - fs + vw - 1) == 255) && (*(IMP + fs + 1) == 255) && + (*(IMP - fs + 1) == 255) && (*(IMP + fs + vw - 1) == 255) && + (*(IMP - fs + 2 * vw - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && + (*(IMP - fs + vw) == 255) && (*(IMP + fs - vw) == 255) && + (*(IMP - fs + vw + 1) == 255) && (*(IMP + fs - 1) == 255) ) + { + *EMP = 255; + } + EMP += vw; + IMP += vw; + } + EMP += 2 * vw; + IMP += 2 *vw; + } + + //extend the mask to the rear side of the phase volume + IMP = input_mask + frame_size + 2 * volume_width - 1; //input mask pointer + EMP = extended_mask + frame_size + 2 * volume_width - 1; //extended mask pointer + for (n=1; n < volume_depth - 1; n++) + { + for (i=1; i < volume_height - 1; i++) + { + if( (*IMP) == 255 && (*(IMP - vw + 1) == 255) && (*(IMP - 1) == 255) && + (*(IMP - vw) == 255) && (*(IMP + vw) == 255) && + (*(IMP - fs) == 255) && (*(IMP + fs) == 255) && + (*(IMP - vw - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + vw - 1) == 255) && (*(IMP - 2 * vw + 1) == 255) && + (*(IMP - fs - vw - 1) == 255) && (*(IMP + fs + 1) == 255) && + (*(IMP - fs - 2 * vw + 1) == 255) && (*(IMP + fs + vw - 1) == 255) && + (*(IMP - fs - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && + (*(IMP - fs - vw + 1) == 255) && (*(IMP + fs - 1) == 255) && + (*(IMP - fs - vw) == 255) && (*(IMP + fs + vw) == 255) && + (*(IMP - fs + vw - 1) == 255) && (*(IMP + fs - 2 * vw + 1) == 255) && + (*(IMP - fs + vw) == 255) && (*(IMP + fs - vw) == 255) && + (*(IMP - fs + 1) == 255) && (*(IMP + fs - vw - 1) == 255) ) + { + *EMP = 255; + } + EMP += vw; + IMP += vw; + } + EMP += 2 * vw; + IMP += 2 *vw; + } + } + + if (y_connectivity == 1) + { + //extend the mask to the left side of the phase volume + IMP = input_mask + frame_size + 1; + EMP = extended_mask + frame_size + 1; + for (n=1; n < volume_depth - 1; n++) + { + for (j=1; j < volume_width - 1; j++) + { + if( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP + fs - vw) == 255) && (*(IMP + vw) == 255) && + (*(IMP - fs) == 255) && (*(IMP + fs) == 255) && + (*(IMP + fs - vw - 1) == 255) && (*(IMP + vw + 1) == 255) && + (*(IMP + fs - vw + 1) == 255) && (*(IMP + vw - 1) == 255) && + (*(IMP - vw - 1) == 255) && (*(IMP + fs + vw + 1) == 255) && + (*(IMP - vw) == 255) && (*(IMP + fs + vw) == 255) && + (*(IMP - vw + 1) == 255) && (*(IMP + fs + vw - 1) == 255) && + (*(IMP - fs - 1) == 255) && (*(IMP + fs + 1) == 255) && + (*(IMP - fs + 1) == 255) && (*(IMP + fs - 1) == 255) && + (*(IMP - fs + vw - 1) == 255) && (*(IMP + 2 * fs - vw + 1) == 255) && + (*(IMP - fs + vw) == 255) && (*(IMP + 2 * fs - vw) == 255) && + (*(IMP - fs + vw + 1) == 255) && (*(IMP + 2 * fs - vw - 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + EMP += fs - vw + 2; + IMP += fs - vw + 2; + } + + //extend the mask to the right side of the phase volume + IMP = input_mask + 2 * frame_size - volume_width + 1; + EMP = extended_mask + 2 * frame_size - volume_width + 1; + for (n=1; n < volume_depth - 1; n++) + { + for (j=1; j < volume_width - 1; j++) + { + if( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && + (*(IMP - vw) == 255) && (*(IMP - fs + vw) == 255) && + (*(IMP - fs) == 255) && (*(IMP + fs) == 255) && + (*(IMP - vw - 1) == 255) && (*(IMP - fs + vw + 1) == 255) && + (*(IMP - vw + 1) == 255) && (*(IMP - fs + vw - 1) == 255) && + (*(IMP - fs - vw - 1) == 255) && (*(IMP + vw + 1) == 255) && + (*(IMP - fs - vw + 1) == 255) && (*(IMP + vw - 1) == 255) && + (*(IMP - fs - vw) == 255) && (*(IMP + vw) == 255) && + (*(IMP - fs - 1) == 255) && (*(IMP + fs + 1) == 255) && + (*(IMP - fs + 1) == 255) && (*(IMP + fs - 1) == 255) && + (*(IMP - 2 * fs + vw - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && + (*(IMP - 2 * fs + vw) == 255) && (*(IMP + fs - vw) == 255) && + (*(IMP - 2 * fs + vw + 1) == 255) && (*(IMP + fs - vw - 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + EMP += fs - vw + 2; + IMP += fs - vw + 2; + } + } + + if (z_connectivity == 1) + { + //extend the mask to the bottom side of the phase volume + IMP = input_mask + volume_width + 1; + EMP = extended_mask + volume_width + 1; + for (i=1; i < volume_height - 1; ++i) + { + for (j=1; j < volume_width - 1; ++j) + { + if( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && + (*(IMP - vw) == 255) && (*(IMP + vw) == 255) && + (*(IMP + fs) == 255) && (*(IMP + vs - fs) == 255) && + (*(IMP - vw - 1) == 255) && (*(IMP + vw + 1) == 255) && + (*(IMP - vw + 1) == 255) && (*(IMP + vw - 1) == 255) && + (*(IMP + vs - fs - vw - 1) == 255) && (*(IMP + fs + vw + 1) == 255) && + (*(IMP + vs - fs - vw) == 255) && (*(IMP + fs + vw) == 255) && + (*(IMP + vs - fs - vw + 1) == 255) && (*(IMP + fs + vw - 1) == 255) && + (*(IMP + vs - fs - 1) == 255) && (*(IMP + fs + 1) == 255) && + (*(IMP + vs - fs + 1) == 255) && (*(IMP + fs - 1) == 255) && + (*(IMP + vs - fs + vw - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && + (*(IMP + vs - fs + vw) == 255) && (*(IMP + fs - vw) == 255) && + (*(IMP + vs - fs + vw + 1) == 255) && (*(IMP + fs - vw - 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + EMP += 2; + IMP += 2; + } + + //extend the mask to the top side of the phase volume + IMP = input_mask + volume_size - frame_size + volume_width + 1; + EMP = extended_mask + volume_size - frame_size + volume_width + 1; + for (i=1; i < volume_height - 1; ++i) + { + for (j=1; j < volume_width - 1; ++j) + { + if( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && + (*(IMP - vw) == 255) && (*(IMP - fs + vw) == 255) && + (*(IMP - fs) == 255) && (*(IMP - vs + fs) == 255) && + (*(IMP - vw - 1) == 255) && (*(IMP + vw + 1) == 255) && + (*(IMP - vw + 1) == 255) && (*(IMP + vw - 1) == 255) && + (*(IMP - fs - vw - 1) == 255) && (*(IMP - vs + fs + vw + 1) == 255) && + (*(IMP - fs - vw + 1) == 255) && (*(IMP - vs + fs + vw - 1) == 255) && + (*(IMP - fs - vw) == 255) && (*(IMP - vs + fs + vw) == 255) && + (*(IMP - fs - 1) == 255) && (*(IMP - vs + fs + 1) == 255) && + (*(IMP - fs + 1) == 255) && (*(IMP - vs + fs - 1) == 255) && + (*(IMP - fs + vw - 1) == 255) && (*(IMP - vs + fs - vw + 1) == 255) && + (*(IMP - fs + vw) == 255) && (*(IMP - vs + fs - vw) == 255) && + (*(IMP - fs + vw + 1) == 255) && (*(IMP - vs + fs - vw - 1) == 255) ) + { + *EMP = 255; + } + EMP++; + IMP++; + } + EMP += 2; + IMP += 2; + } + } +} + +void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width, int volume_height, int volume_depth) +{ + int frame_size = volume_width * volume_height; + int volume_size = volume_width * volume_height * volume_depth; + VOXELM *voxel_pointer; + float H, V, N, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10; + float *WVP; + int n, i, j; + + WVP = wrappedVolume + frame_size + volume_width + 1; + voxel_pointer = voxel + frame_size + volume_width + 1; + for (n=1; n < volume_depth - 1; n++) + { + for (i=1; i < volume_height - 1; i++) + { + for (j=1; j < volume_width - 1; j++) + { + if (voxel_pointer->extended_mask == 255) + { + H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); + D4 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D5 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += 2; + WVP += 2; + } + voxel_pointer += 2 * volume_width; + WVP += 2 * volume_width; + } + + if (x_connectivity == 1) + { + //calculating reliability for the front side of the phase volume...add volume_width + WVP = wrappedVolume + frame_size + volume_width; + voxel_pointer = voxel + frame_size + volume_width; + for (n=1; n < volume_depth - 1; ++n) + { + for (i=1; i < volume_height - 1; ++i) + { + if (voxel_pointer->extended_mask == 255) + { + H = wrap(*(WVP + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + 2 * volume_width - 1)); + D3 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); + D4 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D5 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 2 * volume_width - 1)); + D6 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D8 = wrap(*(WVP - frame_size + 2 * volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer += volume_width; + WVP += volume_width; + } + voxel_pointer += 2 * volume_width; + WVP += 2 * volume_width; + } + + //calculating reliability for the rear side of the phase volume..... subtract volume_width + WVP = wrappedVolume + frame_size + 2 * volume_width - 1; + voxel_pointer = voxel + frame_size + 2 * volume_width - 1; + for (n=1; n < volume_depth - 1; ++n) + { + for (i=1; i < volume_height - 1; ++i) + { + if (voxel_pointer->extended_mask == 255) + { + H = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + D2 = wrap(*(WVP + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - 2 * volume_width + 1)); + D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D4 = wrap(*(WVP - frame_size - 2 * volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D5 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D6 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D7 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 2 * volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer += volume_width; + WVP += volume_width; + } + voxel_pointer += 2 * volume_width; + WVP += 2 * volume_width; + } + } + + if (y_connectivity == 1) + { + //calculating reliability for the left side of the phase volume...add frame_size + WVP = wrappedVolume + frame_size + 1; + voxel_pointer = voxel + frame_size + 1; + for (n=1; n < volume_depth - 1; ++n) + { + for (j=1; j < volume_width - 1; ++j) + { + if (voxel_pointer->extended_mask == 255) + { + H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + V = wrap(*(WVP + frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP + frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP + frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D3 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); + D4 = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D5 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += frame_size - volume_width + 2; + WVP += frame_size - volume_width + 2; + } + + //calculating reliability for the right side of the phase volume...subtract frame_size + WVP = wrappedVolume + 2 * frame_size - volume_width + 1; + voxel_pointer = voxel + 2 * frame_size - volume_width + 1; + for (n=1; n < volume_depth - 1; ++n) + { + for (j=1; j < volume_width - 1; ++j) + { + if (voxel_pointer->extended_mask == 255) + { + H = wrap(*(WVP + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width - 1)); + D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1) ); + D4 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D5 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D8 = wrap(*(WVP - 2 * frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D9 = wrap(*(WVP - 2 * frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP - 2 * frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += frame_size - volume_width + 2; + WVP += frame_size - volume_width + 2; + } + } + + if (z_connectivity == 1) + { + //calculating reliability for the bottom side of the phase volume...add volume_size + WVP = wrappedVolume + volume_width + 1; + voxel_pointer = voxel + volume_width + 1; + for (i=1; i < volume_height - 1; ++i) + { + for (j=1; j < volume_width - 1; ++j) + { + if (voxel_pointer->extended_mask == 255) + { + H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP + frame_size) - *WVP) - wrap(*WVP - *(WVP + volume_size - frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D3 = wrap(*(WVP + volume_size - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); + D4 = wrap(*(WVP + volume_size - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D5 = wrap(*(WVP + volume_size - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D6 = wrap(*(WVP + volume_size - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP + volume_size - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D8 = wrap(*(WVP + volume_size - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D9 = wrap(*(WVP + volume_size - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP + volume_size - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += 2; + WVP += 2; + } + + //calculating reliability for the top side of the phase volume...subtract volume_size + WVP = wrappedVolume + volume_size - frame_size + volume_width + 1; + voxel_pointer = voxel + volume_size - frame_size + volume_width + 1; + for (i=1; i < volume_height - 1; ++i) + { + for (j=1; j < volume_width - 1; ++j) + { + if (voxel_pointer->extended_mask == 255) + { + H = wrap(*(WVP + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width + 1)); + D4 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width - 1)); + D5 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width)); + D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - 1)); + D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += 2; + WVP += 2; + } + } +} + +//calculate the reliability of the horizontal edges of the volume +//it is calculated by adding the reliability of voxel and the relibility of +//its right neighbour +//edge is calculated between a voxel and its next neighbour +void horizontalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth) +{ + int n, i, j; + EDGE *edge_pointer = edge; + VOXELM *voxel_pointer = voxel; + + for (n=0; n < volume_depth; n++) + { + for (i = 0; i < volume_height; i++) + { + for (j = 0; j < volume_width - 1; j++) + { + if (voxel_pointer->input_mask == 255 && (voxel_pointer + 1)->input_mask == 255 ) + { + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer+1); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + 1)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + 1)->value); + edge_pointer++; + No_of_edges++; + } + voxel_pointer++; + } + voxel_pointer++; + } + } + if (x_connectivity == 1) + { + voxel_pointer = voxel + volume_width - 1; + for (n=0; n < volume_depth; n++) + { + for (i = 0; i < volume_height; i++) + { + if (voxel_pointer->input_mask == 255 && (voxel_pointer - volume_width + 1)->input_mask == 255 ) + { + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer - volume_width + 1); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - volume_width + 1)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - volume_width + 1)->value); + edge_pointer++; + No_of_edges++; + } + voxel_pointer += volume_width; + } + } + } +} + +void verticalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth) +{ + int n, i, j; + VOXELM *voxel_pointer = voxel; + EDGE *edge_pointer = edge + No_of_edges; + + for (n=0; n < volume_depth; n++) + { + for (i=0; iinput_mask == 255 && (voxel_pointer + volume_width)->input_mask == 255 ) + { + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer + volume_width); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + volume_width)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + volume_width)->value); + edge_pointer++; + No_of_edges++; + } + voxel_pointer++; + } + } + voxel_pointer += volume_width; + } + + int frame_size = volume_width * volume_height; + int next_voxel = frame_size - volume_width; + if (y_connectivity == 1) + { + voxel_pointer = voxel + frame_size - volume_width; + for (n=0; n < volume_depth; n++) + { + for (i = 0; i < volume_width; i++) + { + if (voxel_pointer->input_mask == 255 && (voxel_pointer - next_voxel)->input_mask == 255 ) + { + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer - next_voxel); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - next_voxel)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - next_voxel)->value); + edge_pointer++; + No_of_edges++; + } + voxel_pointer++; + } + voxel_pointer += next_voxel + 1; + } + } +} + +void normalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth) +{ + int n, i, j; + int frame_size = volume_width * volume_height; + int volume_size = volume_width * volume_height * volume_depth; + VOXELM *voxel_pointer = voxel; + EDGE *edge_pointer = edge + No_of_edges; + + for (n=0; n < volume_depth - 1; n++) + { + for (i=0; iinput_mask == 255 && (voxel_pointer + frame_size)->input_mask == 255 ) + { + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer + frame_size); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + frame_size)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + frame_size)->value); + edge_pointer++; + No_of_edges++; + } + voxel_pointer++; + } + } + } + + + int next_voxel = volume_size - frame_size; + if (z_connectivity == 1) + { + voxel_pointer = voxel + next_voxel; + for (i=0; i < volume_height; i++) + { + for (j = 0; j < volume_width; j++) + { + if (voxel_pointer->input_mask == 255 && (voxel_pointer - next_voxel)->input_mask == 255 ) + { + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer - next_voxel); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - next_voxel)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - next_voxel)->value); + edge_pointer++; + No_of_edges++; + } + voxel_pointer++; + } + } + } +} + +//gather the voxels of the volume into groups +void gatherVOXELs(EDGE *edge) +{ + int k; + VOXELM *VOXEL1; + VOXELM *VOXEL2; + VOXELM *group1; + VOXELM *group2; + EDGE *pointer_edge = edge; + int incremento; + + for (k = 0; k < No_of_edges; k++) + { + VOXEL1 = pointer_edge->pointer_1; + VOXEL2 = pointer_edge->pointer_2; + + //VOXELM 1 and VOXELM 2 belong to different groups + //initially each voxel is in a group by itself and one voxel can construct a group + //no else or else if to this if + if (VOXEL2->head != VOXEL1->head) + { + //VOXELM 2 is alone in its group + //merge this voxel with VOXELM 1 group and find the number of 2 pi to add + //to or subtract to unwrap it + if ((VOXEL2->next == NULL) && (VOXEL2->head == VOXEL2)) + { + VOXEL1->head->last->next = VOXEL2; + VOXEL1->head->last = VOXEL2; + (VOXEL1->head->number_of_voxels_in_group)++; + VOXEL2->head=VOXEL1->head; + VOXEL2->increment = VOXEL1->increment-pointer_edge->increment; + } + + //VOXELM 1 is alone in its group + //merge this voxel with VOXELM 2 group and find the number of 2 pi to add + //to or subtract to unwrap it + else if ((VOXEL1->next == NULL) && (VOXEL1->head == VOXEL1)) + { + VOXEL2->head->last->next = VOXEL1; + VOXEL2->head->last = VOXEL1; + (VOXEL2->head->number_of_voxels_in_group)++; + VOXEL1->head = VOXEL2->head; + VOXEL1->increment = VOXEL2->increment+pointer_edge->increment; + } + + //VOXELM 1 and VOXELM 2 both have groups + else + { + group1 = VOXEL1->head; + group2 = VOXEL2->head; + //if the no. of voxels in VOXELM 1 group is larger than the no. of voxels + //in VOXELM 2 group. Merge VOXELM 2 group to VOXELM 1 group + //and find the number of wraps between VOXELM 2 group and VOXELM 1 group + //to unwrap VOXELM 2 group with respect to VOXELM 1 group. + //the no. of wraps will be added to VOXELM 2 grop in the future + if (group1->number_of_voxels_in_group > group2->number_of_voxels_in_group) + { + //merge VOXELM 2 with VOXELM 1 group + group1->last->next = group2; + group1->last = group2->last; + group1->number_of_voxels_in_group = group1->number_of_voxels_in_group + group2->number_of_voxels_in_group; + incremento = VOXEL1->increment-pointer_edge->increment - VOXEL2->increment; + //merge the other voxels in VOXELM 2 group to VOXELM 1 group + while (group2 != NULL) + { + group2->head = group1; + group2->increment += incremento; + group2 = group2->next; + } + } + + //if the no. of voxels in VOXELM 2 group is larger than the no. of voxels + //in VOXELM 1 group. Merge VOXELM 1 group to VOXELM 2 group + //and find the number of wraps between VOXELM 2 group and VOXELM 1 group + //to unwrap VOXELM 1 group with respect to VOXELM 2 group. + //the no. of wraps will be added to VOXELM 1 grop in the future + else + { + //merge VOXELM 1 with VOXELM 2 group + group2->last->next = group1; + group2->last = group1->last; + group2->number_of_voxels_in_group = group2->number_of_voxels_in_group + group1->number_of_voxels_in_group; + incremento = VOXEL2->increment + pointer_edge->increment - VOXEL1->increment; + //merge the other voxels in VOXELM 2 group to VOXELM 1 group + while (group1 != NULL) + { + group1->head = group2; + group1->increment += incremento; + group1 = group1->next; + } // while + + } // else + } //else + } //if + pointer_edge++; + } +} + +//unwrap the volume +void unwrapVolume(VOXELM *voxel, int volume_width, int volume_height, int volume_depth) +{ + int i; + int volume_size = volume_width * volume_height * volume_depth; + VOXELM *voxel_pointer=voxel; + + for (i = 0; i < volume_size; i++) + { + voxel_pointer->value += TWOPI * (float)(voxel_pointer->increment); + voxel_pointer++; + } +} + +//set the masked voxels (mask = 0) to the minimum of the unwrapper phase +void maskVolume(VOXELM *voxel, unsigned char *input_mask, int volume_width, int volume_height, int volume_depth) +{ + int volume_width_plus_one = volume_width + 1; + int volume_height_plus_one = volume_height + 1; + int volume_width_minus_one = volume_width - 1; + int volume_height_minus_one = volume_height - 1; + + VOXELM *pointer_voxel = voxel; + unsigned char *IMP = input_mask; //input mask pointer + float min=99999999.; + int i, j; + int volume_size = volume_width * volume_height * volume_depth; + + //find the minimum of the unwrapped phase + for (i = 0; i < volume_size; i++) + { + if ((pointer_voxel->value < min) && (*IMP == 255)) + min = pointer_voxel->value; + + pointer_voxel++; + IMP++; + } + + pointer_voxel = voxel; + IMP = input_mask; + + //set the masked voxels to minimum + for (i = 0; i < volume_size; i++) + { + if ((*IMP) == 0) + { + pointer_voxel->value = min; + } + pointer_voxel++; + IMP++; + } +} + +//the input to this unwrapper is an array that contains the wrapped phase map. +//copy the volume on the buffer passed to this unwrapper to over-write the unwrapped +//phase map on the buffer of the wrapped phase map. +void returnVolume(VOXELM *voxel, float *unwrappedVolume, int volume_width, int volume_height, int volume_depth) +{ + int i; + int volume_size = volume_width * volume_height * volume_depth; + float *unwrappedVolume_pointer = unwrappedVolume; + VOXELM *voxel_pointer = voxel; + + for (i=0; i < volume_size; i++) + { + *unwrappedVolume_pointer = voxel_pointer->value; + voxel_pointer++; + unwrappedVolume_pointer++; + } +} + +//the main function of the unwrapper +int main() +{ + float *WrappedVolume, *UnwrappedVolume; + unsigned char *input_mask, *extended_mask; + int volume_width = 64; + int volume_height = 64; + int volume_depth = 46; + int volume_size = volume_height * volume_width * volume_depth; + int No_of_Edges_initially = 3 * volume_width * volume_height * volume_depth; + + WrappedVolume = (float *) calloc(volume_size, sizeof(float)); + read_data("MRI wrapped phase volume 64X64X46.dat", WrappedVolume, volume_size); + + input_mask = (unsigned char *) calloc(volume_size, sizeof(unsigned char)); + extended_mask = (unsigned char *) calloc(volume_size, sizeof(unsigned char)); + read_mask("mask3d.dat", input_mask, volume_size); + + UnwrappedVolume = (float *) calloc(volume_size, sizeof(float)); + VOXELM *voxel = (VOXELM *) calloc(volume_size, sizeof(VOXELM)); + EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; + + extend_mask(input_mask, extended_mask, volume_width, volume_height, volume_depth); + + initialiseVOXELs(WrappedVolume, input_mask, extended_mask, voxel, volume_width, volume_height, volume_depth); + + calculate_reliability(WrappedVolume, voxel, volume_width, volume_height, volume_depth); + + horizontalEDGEs(voxel, edge, volume_width, volume_height, volume_depth); + + verticalEDGEs(voxel, edge, volume_width, volume_height, volume_depth); + + normalEDGEs(voxel, edge, volume_width, volume_height, volume_depth); + + //sort the EDGEs depending on their reiability. The VOXELs with higher relibility (small value) first + quicker_sort(edge, edge + No_of_edges - 1); + + //gather VOXELs into groups + gatherVOXELs(edge); + + unwrapVolume(voxel, volume_width, volume_height, volume_depth); + + maskVolume(voxel, input_mask, volume_width, volume_height, volume_depth); + + //copy the volume from VOXELM structure to the unwrapped phase array passed to this function + returnVolume(voxel, UnwrappedVolume, volume_width, volume_height, volume_depth); + + free(edge); + free(voxel); + + write_data("unwrapped.dat", UnwrappedVolume, volume_size); + free(UnwrappedVolume); + free(WrappedVolume); + free(input_mask); + + return 1; +} From 3d4fb9559c8bf068d6b24aabe20bc79a9683cb26 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sun, 13 May 2012 18:44:53 +0200 Subject: [PATCH 11/84] unwrap: moved pure python code from unwrap2D.pyx to unwrap.py, allocate output array in pure python --- unwrap2D/setup.py | 1 - unwrap2D/test_unwrap.py | 2 +- unwrap2D/unwrap.py | 20 ++++++++++++++++++++ unwrap2D/unwrap2D.pyx | 27 ++++----------------------- 4 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 unwrap2D/unwrap.py diff --git a/unwrap2D/setup.py b/unwrap2D/setup.py index 284d8374..a8be8565 100644 --- a/unwrap2D/setup.py +++ b/unwrap2D/setup.py @@ -7,7 +7,6 @@ import numpy as np ext_modules = [ Extension('unwrap2D', ['unwrap2D.pyx', - #'Miguel_2D_unwrapper_with_mask_and_wrap_around_option.cpp', 'Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c', ], include_dirs = [np.get_include(),], diff --git a/unwrap2D/test_unwrap.py b/unwrap2D/test_unwrap.py index 930cf18b..af94c934 100644 --- a/unwrap2D/test_unwrap.py +++ b/unwrap2D/test_unwrap.py @@ -1,5 +1,5 @@ from numpy.testing import * -from unwrap2D import unwrap2D +from unwrap import unwrap2D import numpy as np from numpy import outer, arange, ones, abs, empty, power, indices diff --git a/unwrap2D/unwrap.py b/unwrap2D/unwrap.py new file mode 100644 index 00000000..8a61a779 --- /dev/null +++ b/unwrap2D/unwrap.py @@ -0,0 +1,20 @@ +import numpy as np +from unwrap2D import _unwrap2D + +def unwrap2D(wrapped_array, wrap_around_x = False, wrap_around_y = False): + wrapped_array = np.require(wrapped_array, np.float32, ['C']) + wrapped_array_masked = np.ma.asarray(wrapped_array) + unwrapped_array = np.empty_like(wrapped_array_masked.data) + + _unwrap2D(wrapped_array_masked.data, + np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), + unwrapped_array, + wrap_around_x, wrap_around_y) + if np.ma.isMaskedArray(wrapped_array): + return np.ma.array(unwrapped_array, mask = wrapped_array_masked.mask) + else: + return unwrapped_array + + #TODO: set_fill to minimum value + #TODO: check for empty mask, not a single contiguous pixel + diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx index 9d734dec..4d2a7be0 100644 --- a/unwrap2D/unwrap2D.pyx +++ b/unwrap2D/unwrap2D.pyx @@ -1,41 +1,22 @@ -import numpy as np -cimport numpy as np - -import numpy.ma - +#import numpy as np +#cimport numpy as np cdef extern int unwrap(float* wrapped_image, float* unwrapped_image, unsigned char* input_mask, int image_width, int image_height, int wrap_around_x, int wrap_around_y) -def unwrap2D(input, wrap_around_x = False, wrap_around_y = False): - - masked_array = numpy.ma.asarray(input, dtype = np.float32) - unwrapped_array = _unwrap2D(masked_array.data, - numpy.ma.getmaskarray(masked_array).astype(np.uint8), - wrap_around_x, wrap_around_y) - if numpy.ma.isarray(input): - return numpy.ma.array(unwrapped_array, mask = input.mask) - else: - return unwrapped_array - - #TODO: set_fill to minimum value - - -cdef _unwrap2D(float[:,::1] array, +def _unwrap2D(float[:,::1] array, unsigned char[:,::1] mask, + float[:,::1] unwrapped_array, wrap_around_x, wrap_around_y): - cdef float[:,::1] unwrapped_array = np.empty_like(array) cdef int h = array.shape[0] cdef int w = array.shape[1] - #TODO: check for masked array/ unwrap(&array[0,0], &unwrapped_array[0,0], &mask[0,0], array.shape[0], array.shape[1], wrap_around_x, wrap_around_y, ) - return np.asarray(unwrapped_array) From cf04965d21bf3d67eec29f1aa6ecea57eb6c595a Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sun, 13 May 2012 22:00:51 +0200 Subject: [PATCH 12/84] unwrap: removed use of global variables --- ...wrapper_with_mask_and_wrap_around_option.c | 42 ++++++++----------- unwrap2D/unwrap2D.pyx | 30 +++++++------ 2 files changed, 32 insertions(+), 40 deletions(-) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index 14fe65de..131ec517 100644 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -13,7 +13,6 @@ //When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) //This program takes into consideration the image wrap around problem encountered in MRI imaging. -//TODO stdlib instead of malloc.h ? (calloc?) #include #include #include @@ -35,11 +34,6 @@ typedef struct int no_of_edges; } params_t; - -//int x_connectivity = 1; -//int y_connectivity = 1; -int No_of_edges = 0; - //PIXELM information struct pixelm { @@ -71,7 +65,6 @@ struct edge typedef struct edge EDGE; - //---------------start quicker_sort algorithm -------------------------------- #define swap(x,y) {EDGE t; t=x; x=y; y=t;} #define order(x,y) if (x.reliab > y.reliab) swap(x,y) @@ -424,6 +417,7 @@ void horizontalEDGEs(PIXELM *pixel, EDGE *edge, int i, j; EDGE *edge_pointer = edge; PIXELM *pixel_pointer = pixel; + int no_of_edges = params->no_of_edges; for (i = 0; i < image_height; i++) { @@ -436,7 +430,7 @@ void horizontalEDGEs(PIXELM *pixel, EDGE *edge, edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); edge_pointer++; - No_of_edges++; + no_of_edges++; } pixel_pointer++; } @@ -455,11 +449,12 @@ void horizontalEDGEs(PIXELM *pixel, EDGE *edge, edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); edge_pointer++; - No_of_edges++; + no_of_edges++; } pixel_pointer+=image_width; } } + params->no_of_edges = no_of_edges; } //calculate the reliability of the vertical edges of the image @@ -470,8 +465,9 @@ void verticalEDGEs(PIXELM *pixel, EDGE *edge, params_t *params) { int i, j; + int no_of_edges = params->no_of_edges; PIXELM *pixel_pointer = pixel; - EDGE *edge_pointer = edge + No_of_edges; + EDGE *edge_pointer = edge + no_of_edges; for (i=0; i < image_height - 1; i++) { @@ -484,7 +480,7 @@ void verticalEDGEs(PIXELM *pixel, EDGE *edge, edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); edge_pointer++; - No_of_edges++; + no_of_edges++; } pixel_pointer++; } //j loop @@ -503,15 +499,16 @@ void verticalEDGEs(PIXELM *pixel, EDGE *edge, edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); edge_pointer++; - No_of_edges++; + no_of_edges++; } pixel_pointer++; } } + params->no_of_edges = no_of_edges; } //gather the pixels of the image into groups -void gatherPIXELs(EDGE *edge, int image_width, int image_height) +void gatherPIXELs(EDGE *edge, params_t *params) { int k; PIXELM *PIXEL1; @@ -521,7 +518,7 @@ void gatherPIXELs(EDGE *edge, int image_width, int image_height) EDGE *pointer_edge = edge; int incremento; - for (k = 0; k < No_of_edges; k++) + for (k = 0; k < params->no_of_edges; k++) { PIXEL1 = pointer_edge->pointer_1; PIXEL2 = pointer_edge->pointer_2; @@ -683,14 +680,14 @@ void returnImage(PIXELM *pixel, float *unwrapped_image, int image_width, int im } //the main function of the unwrapper -int unwrap(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, - int image_width, int image_height, - int wrap_around_x, int wrap_around_y) +unwrap2D(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, + int image_width, int image_height, + int wrap_around_x, int wrap_around_y) { + params_t params = {TWOPI, 0, 0, 0}; unsigned char *extended_mask; int image_size = image_height * image_width; int No_of_Edges_initially = 2 * image_width * image_height; - params_t params = {TWOPI, 0, 0, 0}; extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); @@ -704,23 +701,20 @@ int unwrap(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mas //sort the EDGEs depending on their reiability. The PIXELs with higher //relibility (small value) first - quicker_sort(edge, edge + No_of_edges - 1); + quicker_sort(edge, edge + params.no_of_edges - 1); //gather PIXELs into groups - gatherPIXELs(edge, image_width, image_height); + gatherPIXELs(edge, ¶ms); unwrapImage(pixel, image_width, image_height); maskImage(pixel, input_mask, image_width, image_height); //copy the image from PIXELM structure to the unwrapped phase array //passed to this function + //TODO: replace by (cython?) function to directly write into numpy array ? returnImage(pixel, UnwrappedImage, image_width, image_height); free(edge); free(pixel); free(extended_mask); - - No_of_edges = 0; - return 1; - } diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx index 4d2a7be0..2dd0b33c 100644 --- a/unwrap2D/unwrap2D.pyx +++ b/unwrap2D/unwrap2D.pyx @@ -1,22 +1,20 @@ -#import numpy as np -#cimport numpy as np -cdef extern int unwrap(float* wrapped_image, - float* unwrapped_image, - unsigned char* input_mask, - int image_width, int image_height, - int wrap_around_x, int wrap_around_y) +cdef extern unwrap2D(float* wrapped_image, + float* unwrapped_image, + unsigned char* input_mask, + int image_width, int image_height, + int wrap_around_x, int wrap_around_y) def _unwrap2D(float[:,::1] array, - unsigned char[:,::1] mask, - float[:,::1] unwrapped_array, - wrap_around_x, wrap_around_y): + unsigned char[:,::1] mask, + float[:,::1] unwrapped_array, + wrap_around_x, wrap_around_y): cdef int h = array.shape[0] cdef int w = array.shape[1] - unwrap(&array[0,0], - &unwrapped_array[0,0], - &mask[0,0], - array.shape[0], array.shape[1], - wrap_around_x, wrap_around_y, - ) + unwrap2D(&array[0,0], + &unwrapped_array[0,0], + &mask[0,0], + array.shape[0], array.shape[1], + wrap_around_x, wrap_around_y, + ) From 1b3b6985f1e06deb544c75aa88f79d5624bae0d8 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sun, 13 May 2012 22:01:57 +0200 Subject: [PATCH 13/84] unwrap: added 3D unwrapping (untested) --- ...apper_with_mask_and_wrap_around_option.cpp | 1673 ++++++++--------- unwrap2D/setup.py | 8 +- unwrap2D/unwrap3D.pyx | 18 + 3 files changed, 842 insertions(+), 857 deletions(-) create mode 100644 unwrap2D/unwrap3D.pyx diff --git a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp index 6a4c8308..84b0b4ab 100644 --- a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp +++ b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp @@ -1,3 +1,5 @@ +// 3D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer + //This program was written by Hussein Abdul-Rahman and Munther Gdeisat to program the three-dimensional phase unwrapper //entitled "Fast three-dimensional phase-unwrapping algorithm based on sorting by //reliability following a noncontinuous path" @@ -13,82 +15,57 @@ //When the mask is 0 this means that the voxel is invalid (noisy or corrupted voxel) //This program takes into consideration the image wrap around problem encountered in MRI imaging. -#include -//#include "stdafx.h" #include #include #include static float PI = 3.141592654; static float TWOPI = 6.283185307; -int x_connectivity = 1; -int y_connectivity = 1; -int z_connectivity = 1 -; -int No_of_edges = 0; + +#define NOMASK 0 +#define MASK 1 + +typedef struct +{ + float mod; + int x_connectivity; + int y_connectivity; + int z_connectivity; + int no_of_edges; +} params_t; //VOXELM information -struct VOXELM +struct voxelm { - //int x; //x coordinate of the voxel - //int y; //y coordinate - //int z; //z coordinate - int increment; //No. of 2*pi to add to the voxel to unwrap it - int number_of_voxels_in_group; //No. of voxel in the voxel group - float value; //value of the voxel - float reliability; - unsigned char input_mask; //0 voxel is masked. 255 voxel is not masked - unsigned char extended_mask; //0 voxel is masked. 255 voxel is not masked - int group; //group No. - int new_group; - struct VOXELM *head; //pointer to the first voxel in the group in the linked list - struct VOXELM *last; //pointer to the last voxel in the group - struct VOXELM *next; //pointer to the next voxel in the group + int increment; //No. of 2*pi to add to the voxel to unwrap it + int number_of_voxels_in_group;//No. of voxel in the voxel group + float value; //value of the voxel + float reliability; + unsigned char input_mask; //MASK voxel is masked. NOMASK voxel is not masked + unsigned char extended_mask; //MASK voxel is masked. NOMASK voxel is not masked + int group; //group No. + int new_group; + struct voxelm *head; //pointer to the first voxel in the group in the linked list + struct voxelm *last; //pointer to the last voxel in the group + struct voxelm *next; //pointer to the next voxel in the group }; +typedef struct voxelm VOXELM; //the EDGE is the line that connects two voxels. //if we have S voxels, then we have S horizontal edges and S vertical edges -struct EDGE +struct edge { - float reliab; //reliabilty of the edge and it depends on the two voxels - VOXELM *pointer_1; //pointer to the first voxel - VOXELM *pointer_2; //pointer to the second voxel - int increment; //No. of 2*pi to add to one of the voxels to unwrap it with respect to the second -}; + float reliab; //reliabilty of the edge and it depends on the two voxels + VOXELM *pointer_1; //pointer to the first voxel + VOXELM *pointer_2; //pointer to the second voxel + int increment; //No. of 2*pi to add to one of the + //voxels to unwrap it with respect to + //the second +}; -void read_data(char *inputfile,float *Data, int length) -{ - printf("Reading the Wrapped Values from Binary File.............>"); - FILE *ifptr; - ifptr = fopen(inputfile,"rb"); - if(ifptr == NULL) printf("Error opening the file\n"); - fread(Data,sizeof(float),length,ifptr); - fclose(ifptr); - printf(" Done.\n"); -} +typedef struct edge EDGE; -void write_data(char *outputfile,float *Data,int length) -{ - printf("Writing the Wrapped Values to Binary File.............>"); - FILE *ifptr; - ifptr = fopen(outputfile,"wb"); - if(ifptr == NULL) printf("Error opening the file\n"); - fwrite(Data,sizeof(float),length,ifptr); - fclose(ifptr); - printf(" Done.\n"); -} - -void read_mask(char *inputfile,unsigned char *Data, int length) -{ - printf("Reading the mask from Binary File.............>"); - FILE *ifptr; - ifptr = fopen(inputfile,"rb"); - if(ifptr == NULL) printf("Error opening the file\n"); - fread(Data,sizeof(char),length,ifptr); - fclose(ifptr); - printf(" Done.\n"); -} //---------------start quicker_sort algorithm -------------------------------- #define swap(x,y) {EDGE t; t=x; x=y; y=t;} #define order(x,y) if (x.reliab > y.reliab) swap(x,y) @@ -162,927 +139,911 @@ void quicker_sort(EDGE *left, EDGE *right) //--------------end quicker_sort algorithm ----------------------------------- -//--------------------start initialse voxels ---------------------------------- -//initialse voxels. See the explanation of the voxel class above. +//--------------------start initialize voxels ---------------------------------- +//initiale voxels. See the explanation of the voxel class above. //initially every voxel is assumed to belong to a group consisting of only itself void initialiseVOXELs(float *WrappedVolume, unsigned char *input_mask, unsigned char *extended_mask, VOXELM *voxel, int volume_width, int volume_height, int volume_depth) { - VOXELM *voxel_pointer = voxel; - float *wrapped_volume_pointer = WrappedVolume; - unsigned char *input_mask_pointer = input_mask; - unsigned char *extended_mask_pointer = extended_mask; - int n, i, j; + VOXELM *voxel_pointer = voxel; + float *wrapped_volume_pointer = WrappedVolume; + unsigned char *input_mask_pointer = input_mask; + unsigned char *extended_mask_pointer = extended_mask; + int n, i, j; - for (n=0; n < volume_depth; n++) - { - for (i=0; i < volume_height; i++) + for (n=0; n < volume_depth; n++) + { + for (i=0; i < volume_height; i++) { - for (j=0; j < volume_width; j++) - { - //voxel_pointer->x = j; - //voxel_pointer->y = i; - //voxel_pointer->z = n; - voxel_pointer->increment = 0; - voxel_pointer->number_of_voxels_in_group = 1; - voxel_pointer->value = *wrapped_volume_pointer; - voxel_pointer->reliability = 9999999 + rand(); - voxel_pointer->input_mask = *input_mask_pointer; - voxel_pointer->extended_mask = *extended_mask_pointer; - voxel_pointer->head = voxel_pointer; - voxel_pointer->last = voxel_pointer; - voxel_pointer->next = NULL; - voxel_pointer->new_group = 0; - voxel_pointer->group = -1; - voxel_pointer++; - wrapped_volume_pointer++; - input_mask_pointer++; - extended_mask_pointer++; - } + for (j=0; j < volume_width; j++) + { + voxel_pointer->increment = 0; + voxel_pointer->number_of_voxels_in_group = 1; + voxel_pointer->value = *wrapped_volume_pointer; + voxel_pointer->reliability = 9999999 + rand(); + voxel_pointer->input_mask = *input_mask_pointer; + voxel_pointer->extended_mask = *extended_mask_pointer; + voxel_pointer->head = voxel_pointer; + voxel_pointer->last = voxel_pointer; + voxel_pointer->next = NULL; + voxel_pointer->new_group = 0; + voxel_pointer->group = -1; + voxel_pointer++; + wrapped_volume_pointer++; + input_mask_pointer++; + extended_mask_pointer++; + } } - } + } } -//-------------------end initialise voxels ----------- +//-------------------end initialize voxels ----------- //gamma function in the paper float wrap(float voxel_value) { - float wrapped_voxel_value; - if (voxel_value > PI) wrapped_voxel_value = voxel_value - TWOPI; - else if (voxel_value < -PI) wrapped_voxel_value = voxel_value + TWOPI; - else wrapped_voxel_value = voxel_value; - return wrapped_voxel_value; + float wrapped_voxel_value; + if (voxel_value > PI) wrapped_voxel_value = voxel_value - TWOPI; + else if (voxel_value < -PI) wrapped_voxel_value = voxel_value + TWOPI; + else wrapped_voxel_value = voxel_value; + return wrapped_voxel_value; } // voxelL_value is the left voxel, voxelR_value is the right voxel int find_wrap(float voxelL_value, float voxelR_value) { - float difference; - int wrap_value; - difference = voxelL_value - voxelR_value; + float difference; + int wrap_value; + difference = voxelL_value - voxelR_value; - if (difference > PI) wrap_value = -1; - else if (difference < -PI) wrap_value = 1; - else wrap_value = 0; + if (difference > PI) wrap_value = -1; + else if (difference < -PI) wrap_value = 1; + else wrap_value = 0; - return wrap_value; + return wrap_value; } -void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int volume_width, int volume_height, int volume_depth) +void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int volume_width, int volume_height, int volume_depth, params_t *params) { - int n, i, j; - int vw = volume_width, vh = volume_height, vd = volume_depth; - int fs = volume_width * volume_height; //frame size - int frame_size = volume_width * volume_height; - int volume_size = volume_width * volume_height * volume_depth; //volume size - int vs = volume_size; - unsigned char *IMP = input_mask + frame_size + volume_width + 1; //input mask pointer - unsigned char *EMP = extended_mask + frame_size + volume_width + 1; //extended mask pointer + int n, i, j; + int vw = volume_width, vh = volume_height, vd = volume_depth; + int fs = volume_width * volume_height; //frame size + int frame_size = volume_width * volume_height; + int volume_size = volume_width * volume_height * volume_depth; //volume size + int vs = volume_size; + unsigned char *IMP = input_mask + frame_size + volume_width + 1; //input mask pointer + unsigned char *EMP = extended_mask + frame_size + volume_width + 1; //extended mask pointer - //extend the mask for the volume except borders - for (n=1; n < volume_depth - 1; n++) - { - for (i=1; i < volume_height - 1; i++) + //extend the mask for the volume except borders + for (n=1; n < volume_depth - 1; n++) + { + for (i=1; i < volume_height - 1; i++) { - for (j=1; j < volume_width - 1; j++) - { - if( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + vw) == 255) && (*(IMP + vw - 1) == 255) && (*(IMP + vw + 1) == 255) && - (*(IMP - vw) == 255) && (*(IMP - vw - 1) == 255) && (*(IMP - vw + 1) == 255) && - (*(IMP + fs) == 255) && (*(IMP + fs - 1) == 255) && (*(IMP + fs + 1) == 255) && - (*(IMP + fs - vw) == 255) && (*(IMP + fs - vw - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && - (*(IMP + fs + vw) == 255) && (*(IMP + fs + vw - 1) == 255) && (*(IMP + fs + vw + 1) == 255) && - (*(IMP - fs) == 255) && (*(IMP - fs - 1) == 255) && (*(IMP - fs + 1) == 255) && - (*(IMP - fs - vw) == 255) && (*(IMP - fs - vw - 1) == 255) && (*(IMP - fs - vw + 1) == 255) && - (*(IMP - fs + vw) == 255) && (*(IMP - fs + vw - 1) == 255) && (*(IMP - fs + vw + 1) == 255)) - { - *EMP = 255; - } - ++EMP; - ++IMP; - } - EMP += 2; - IMP += 2; + for (j=1; j < volume_width - 1; j++) + { + if( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + vw) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP - vw - 1) == NOMASK) && (*(IMP - vw + 1) == NOMASK) && + (*(IMP + fs) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP + fs - vw) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && + (*(IMP + fs + vw) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && + (*(IMP - fs) == NOMASK) && (*(IMP - fs - 1) == NOMASK) && (*(IMP - fs + 1) == NOMASK) && + (*(IMP - fs - vw) == NOMASK) && (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP - fs - vw + 1) == NOMASK) && + (*(IMP - fs + vw) == NOMASK) && (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP - fs + vw + 1) == NOMASK)) + { + *EMP = NOMASK; } - EMP += 2 * volume_width; - IMP += 2 * volume_width; - } + ++EMP; + ++IMP; + } + EMP += 2; + IMP += 2; + } + EMP += 2 * volume_width; + IMP += 2 * volume_width; + } - if (x_connectivity == 1) + if (params->x_connectivity == 1) + { + //extend the mask to the front side of the phase volume + IMP = input_mask + frame_size + volume_width; //input mask pointer + EMP = extended_mask + frame_size + volume_width; //extended mask pointer + for (n=1; n < volume_depth - 1; n++) { - //extend the mask to the front side of the phase volume - IMP = input_mask + frame_size + volume_width; //input mask pointer - EMP = extended_mask + frame_size + volume_width; //extended mask pointer - for (n=1; n < volume_depth - 1; n++) - { - for (i=1; i < volume_height - 1; i++) - { - if( (*IMP) == 255 && (*(IMP + vw - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP - vw) == 255) && (*(IMP + vw) == 255) && - (*(IMP - fs) == 255) && (*(IMP + fs) == 255) && - (*(IMP - 1) == 255) && (*(IMP + vw + 1) == 255) && - (*(IMP - vw + 1) == 255) && (*(IMP + 2 * vw - 1) == 255) && - (*(IMP - fs - 1) == 255) && (*(IMP + fs + vw + 1) == 255) && - (*(IMP - fs - vw) == 255) && (*(IMP + fs + vw) == 255) && - (*(IMP - fs - vw + 1) == 255) && (*(IMP + fs + 2 * vw - 1) == 255) && - (*(IMP - fs + vw - 1) == 255) && (*(IMP + fs + 1) == 255) && - (*(IMP - fs + 1) == 255) && (*(IMP + fs + vw - 1) == 255) && - (*(IMP - fs + 2 * vw - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && - (*(IMP - fs + vw) == 255) && (*(IMP + fs - vw) == 255) && - (*(IMP - fs + vw + 1) == 255) && (*(IMP + fs - 1) == 255) ) - { - *EMP = 255; - } - EMP += vw; - IMP += vw; - } - EMP += 2 * vw; - IMP += 2 *vw; - } - - //extend the mask to the rear side of the phase volume - IMP = input_mask + frame_size + 2 * volume_width - 1; //input mask pointer - EMP = extended_mask + frame_size + 2 * volume_width - 1; //extended mask pointer - for (n=1; n < volume_depth - 1; n++) - { - for (i=1; i < volume_height - 1; i++) - { - if( (*IMP) == 255 && (*(IMP - vw + 1) == 255) && (*(IMP - 1) == 255) && - (*(IMP - vw) == 255) && (*(IMP + vw) == 255) && - (*(IMP - fs) == 255) && (*(IMP + fs) == 255) && - (*(IMP - vw - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + vw - 1) == 255) && (*(IMP - 2 * vw + 1) == 255) && - (*(IMP - fs - vw - 1) == 255) && (*(IMP + fs + 1) == 255) && - (*(IMP - fs - 2 * vw + 1) == 255) && (*(IMP + fs + vw - 1) == 255) && - (*(IMP - fs - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && - (*(IMP - fs - vw + 1) == 255) && (*(IMP + fs - 1) == 255) && - (*(IMP - fs - vw) == 255) && (*(IMP + fs + vw) == 255) && - (*(IMP - fs + vw - 1) == 255) && (*(IMP + fs - 2 * vw + 1) == 255) && - (*(IMP - fs + vw) == 255) && (*(IMP + fs - vw) == 255) && - (*(IMP - fs + 1) == 255) && (*(IMP + fs - vw - 1) == 255) ) - { - *EMP = 255; - } - EMP += vw; - IMP += vw; - } - EMP += 2 * vw; - IMP += 2 *vw; - } - } - - if (y_connectivity == 1) - { - //extend the mask to the left side of the phase volume - IMP = input_mask + frame_size + 1; - EMP = extended_mask + frame_size + 1; - for (n=1; n < volume_depth - 1; n++) - { - for (j=1; j < volume_width - 1; j++) - { - if( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP + fs - vw) == 255) && (*(IMP + vw) == 255) && - (*(IMP - fs) == 255) && (*(IMP + fs) == 255) && - (*(IMP + fs - vw - 1) == 255) && (*(IMP + vw + 1) == 255) && - (*(IMP + fs - vw + 1) == 255) && (*(IMP + vw - 1) == 255) && - (*(IMP - vw - 1) == 255) && (*(IMP + fs + vw + 1) == 255) && - (*(IMP - vw) == 255) && (*(IMP + fs + vw) == 255) && - (*(IMP - vw + 1) == 255) && (*(IMP + fs + vw - 1) == 255) && - (*(IMP - fs - 1) == 255) && (*(IMP + fs + 1) == 255) && - (*(IMP - fs + 1) == 255) && (*(IMP + fs - 1) == 255) && - (*(IMP - fs + vw - 1) == 255) && (*(IMP + 2 * fs - vw + 1) == 255) && - (*(IMP - fs + vw) == 255) && (*(IMP + 2 * fs - vw) == 255) && - (*(IMP - fs + vw + 1) == 255) && (*(IMP + 2 * fs - vw - 1) == 255) ) - { - *EMP = 255; - } - EMP++; - IMP++; - } - EMP += fs - vw + 2; - IMP += fs - vw + 2; - } - - //extend the mask to the right side of the phase volume - IMP = input_mask + 2 * frame_size - volume_width + 1; - EMP = extended_mask + 2 * frame_size - volume_width + 1; - for (n=1; n < volume_depth - 1; n++) - { - for (j=1; j < volume_width - 1; j++) - { - if( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && - (*(IMP - vw) == 255) && (*(IMP - fs + vw) == 255) && - (*(IMP - fs) == 255) && (*(IMP + fs) == 255) && - (*(IMP - vw - 1) == 255) && (*(IMP - fs + vw + 1) == 255) && - (*(IMP - vw + 1) == 255) && (*(IMP - fs + vw - 1) == 255) && - (*(IMP - fs - vw - 1) == 255) && (*(IMP + vw + 1) == 255) && - (*(IMP - fs - vw + 1) == 255) && (*(IMP + vw - 1) == 255) && - (*(IMP - fs - vw) == 255) && (*(IMP + vw) == 255) && - (*(IMP - fs - 1) == 255) && (*(IMP + fs + 1) == 255) && - (*(IMP - fs + 1) == 255) && (*(IMP + fs - 1) == 255) && - (*(IMP - 2 * fs + vw - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && - (*(IMP - 2 * fs + vw) == 255) && (*(IMP + fs - vw) == 255) && - (*(IMP - 2 * fs + vw + 1) == 255) && (*(IMP + fs - vw - 1) == 255) ) - { - *EMP = 255; - } - EMP++; - IMP++; - } - EMP += fs - vw + 2; - IMP += fs - vw + 2; + for (i=1; i < volume_height - 1; i++) + { + if( (*IMP) == NOMASK && (*(IMP + vw - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP - fs) == NOMASK) && (*(IMP + fs) == NOMASK) && + (*(IMP - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP + 2 * vw - 1) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && + (*(IMP - fs - vw) == NOMASK) && (*(IMP + fs + vw) == NOMASK) && + (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP + fs + 2 * vw - 1) == NOMASK) && + (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && + (*(IMP - fs + 2 * vw - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && + (*(IMP - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && + (*(IMP - fs + vw + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) ) + { + *EMP = NOMASK; } + EMP += vw; + IMP += vw; + } + EMP += 2 * vw; + IMP += 2 *vw; } - if (z_connectivity == 1) + //extend the mask to the rear side of the phase volume + IMP = input_mask + frame_size + 2 * volume_width - 1; //input mask pointer + EMP = extended_mask + frame_size + 2 * volume_width - 1; //extended mask pointer + for (n=1; n < volume_depth - 1; n++) { - //extend the mask to the bottom side of the phase volume - IMP = input_mask + volume_width + 1; - EMP = extended_mask + volume_width + 1; - for (i=1; i < volume_height - 1; ++i) - { - for (j=1; j < volume_width - 1; ++j) - { - if( (*IMP) == 255 && (*(IMP - 1) == 255) && (*(IMP + 1) == 255) && - (*(IMP - vw) == 255) && (*(IMP + vw) == 255) && - (*(IMP + fs) == 255) && (*(IMP + vs - fs) == 255) && - (*(IMP - vw - 1) == 255) && (*(IMP + vw + 1) == 255) && - (*(IMP - vw + 1) == 255) && (*(IMP + vw - 1) == 255) && - (*(IMP + vs - fs - vw - 1) == 255) && (*(IMP + fs + vw + 1) == 255) && - (*(IMP + vs - fs - vw) == 255) && (*(IMP + fs + vw) == 255) && - (*(IMP + vs - fs - vw + 1) == 255) && (*(IMP + fs + vw - 1) == 255) && - (*(IMP + vs - fs - 1) == 255) && (*(IMP + fs + 1) == 255) && - (*(IMP + vs - fs + 1) == 255) && (*(IMP + fs - 1) == 255) && - (*(IMP + vs - fs + vw - 1) == 255) && (*(IMP + fs - vw + 1) == 255) && - (*(IMP + vs - fs + vw) == 255) && (*(IMP + fs - vw) == 255) && - (*(IMP + vs - fs + vw + 1) == 255) && (*(IMP + fs - vw - 1) == 255) ) - { - *EMP = 255; - } - EMP++; - IMP++; - } - EMP += 2; - IMP += 2; - } - - //extend the mask to the top side of the phase volume - IMP = input_mask + volume_size - frame_size + volume_width + 1; - EMP = extended_mask + volume_size - frame_size + volume_width + 1; - for (i=1; i < volume_height - 1; ++i) - { - for (j=1; j < volume_width - 1; ++j) - { - if( (*IMP) == 255 && (*(IMP + 1) == 255) && (*(IMP - 1) == 255) && - (*(IMP - vw) == 255) && (*(IMP - fs + vw) == 255) && - (*(IMP - fs) == 255) && (*(IMP - vs + fs) == 255) && - (*(IMP - vw - 1) == 255) && (*(IMP + vw + 1) == 255) && - (*(IMP - vw + 1) == 255) && (*(IMP + vw - 1) == 255) && - (*(IMP - fs - vw - 1) == 255) && (*(IMP - vs + fs + vw + 1) == 255) && - (*(IMP - fs - vw + 1) == 255) && (*(IMP - vs + fs + vw - 1) == 255) && - (*(IMP - fs - vw) == 255) && (*(IMP - vs + fs + vw) == 255) && - (*(IMP - fs - 1) == 255) && (*(IMP - vs + fs + 1) == 255) && - (*(IMP - fs + 1) == 255) && (*(IMP - vs + fs - 1) == 255) && - (*(IMP - fs + vw - 1) == 255) && (*(IMP - vs + fs - vw + 1) == 255) && - (*(IMP - fs + vw) == 255) && (*(IMP - vs + fs - vw) == 255) && - (*(IMP - fs + vw + 1) == 255) && (*(IMP - vs + fs - vw - 1) == 255) ) - { - *EMP = 255; - } - EMP++; - IMP++; - } - EMP += 2; - IMP += 2; + for (i=1; i < volume_height - 1; i++) + { + if( (*IMP) == NOMASK && (*(IMP - vw + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP - fs) == NOMASK) && (*(IMP + fs) == NOMASK) && + (*(IMP - vw - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + vw - 1) == NOMASK) && (*(IMP - 2 * vw + 1) == NOMASK) && + (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP - fs - 2 * vw + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && + (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && + (*(IMP - fs - vw) == NOMASK) && (*(IMP + fs + vw) == NOMASK) && + (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP + fs - 2 * vw + 1) == NOMASK) && + (*(IMP - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && + (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) ) + { + *EMP = NOMASK; } + EMP += vw; + IMP += vw; + } + EMP += 2 * vw; + IMP += 2 *vw; } + } + + if (params->y_connectivity == 1) + { + //extend the mask to the left side of the phase volume + IMP = input_mask + frame_size + 1; + EMP = extended_mask + frame_size + 1; + for (n=1; n < volume_depth - 1; n++) + { + for (j=1; j < volume_width - 1; j++) + { + if( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + fs - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP - fs) == NOMASK) && (*(IMP + fs) == NOMASK) && + (*(IMP + fs - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && + (*(IMP + fs - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && + (*(IMP - vw - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP + fs + vw) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && + (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP + 2 * fs - vw + 1) == NOMASK) && + (*(IMP - fs + vw) == NOMASK) && (*(IMP + 2 * fs - vw) == NOMASK) && + (*(IMP - fs + vw + 1) == NOMASK) && (*(IMP + 2 * fs - vw - 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP++; + IMP++; + } + EMP += fs - vw + 2; + IMP += fs - vw + 2; + } + + //extend the mask to the right side of the phase volume + IMP = input_mask + 2 * frame_size - volume_width + 1; + EMP = extended_mask + 2 * frame_size - volume_width + 1; + for (n=1; n < volume_depth - 1; n++) + { + for (j=1; j < volume_width - 1; j++) + { + if( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP - fs + vw) == NOMASK) && + (*(IMP - fs) == NOMASK) && (*(IMP + fs) == NOMASK) && + (*(IMP - vw - 1) == NOMASK) && (*(IMP - fs + vw + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP - fs + vw - 1) == NOMASK) && + (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && + (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && + (*(IMP - fs - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && + (*(IMP - 2 * fs + vw - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && + (*(IMP - 2 * fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && + (*(IMP - 2 * fs + vw + 1) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP++; + IMP++; + } + EMP += fs - vw + 2; + IMP += fs - vw + 2; + } + } + + if (params->z_connectivity == 1) + { + //extend the mask to the bottom side of the phase volume + IMP = input_mask + volume_width + 1; + EMP = extended_mask + volume_width + 1; + for (i=1; i < volume_height - 1; ++i) + { + for (j=1; j < volume_width - 1; ++j) + { + if( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP + fs) == NOMASK) && (*(IMP + vs - fs) == NOMASK) && + (*(IMP - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && + (*(IMP + vs - fs - vw - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && + (*(IMP + vs - fs - vw) == NOMASK) && (*(IMP + fs + vw) == NOMASK) && + (*(IMP + vs - fs - vw + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && + (*(IMP + vs - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP + vs - fs + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && + (*(IMP + vs - fs + vw - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && + (*(IMP + vs - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && + (*(IMP + vs - fs + vw + 1) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP++; + IMP++; + } + EMP += 2; + IMP += 2; + } + + //extend the mask to the top side of the phase volume + IMP = input_mask + volume_size - frame_size + volume_width + 1; + EMP = extended_mask + volume_size - frame_size + volume_width + 1; + for (i=1; i < volume_height - 1; ++i) + { + for (j=1; j < volume_width - 1; ++j) + { + if( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP - fs + vw) == NOMASK) && + (*(IMP - fs) == NOMASK) && (*(IMP - vs + fs) == NOMASK) && + (*(IMP - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && + (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP - vs + fs + vw + 1) == NOMASK) && + (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP - vs + fs + vw - 1) == NOMASK) && + (*(IMP - fs - vw) == NOMASK) && (*(IMP - vs + fs + vw) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP - vs + fs + 1) == NOMASK) && + (*(IMP - fs + 1) == NOMASK) && (*(IMP - vs + fs - 1) == NOMASK) && + (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP - vs + fs - vw + 1) == NOMASK) && + (*(IMP - fs + vw) == NOMASK) && (*(IMP - vs + fs - vw) == NOMASK) && + (*(IMP - fs + vw + 1) == NOMASK) && (*(IMP - vs + fs - vw - 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP++; + IMP++; + } + EMP += 2; + IMP += 2; + } + } } -void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width, int volume_height, int volume_depth) +void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width, int volume_height, int volume_depth, params_t *params) { - int frame_size = volume_width * volume_height; - int volume_size = volume_width * volume_height * volume_depth; - VOXELM *voxel_pointer; - float H, V, N, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10; - float *WVP; - int n, i, j; + int frame_size = volume_width * volume_height; + int volume_size = volume_width * volume_height * volume_depth; + VOXELM *voxel_pointer; + float H, V, N, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10; + float *WVP; + int n, i, j; - WVP = wrappedVolume + frame_size + volume_width + 1; - voxel_pointer = voxel + frame_size + volume_width + 1; - for (n=1; n < volume_depth - 1; n++) - { - for (i=1; i < volume_height - 1; i++) + WVP = wrappedVolume + frame_size + volume_width + 1; + voxel_pointer = voxel + frame_size + volume_width + 1; + for (n=1; n < volume_depth - 1; n++) + { + for (i=1; i < volume_height - 1; i++) { - for (j=1; j < volume_width - 1; j++) - { - if (voxel_pointer->extended_mask == 255) - { - H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); - V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); - N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); - D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); - D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); - D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); - D4 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); - D5 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); - D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); - D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); - D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); - D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); - D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 - + D7*D7 + D8*D8 + D9*D9 + D10*D10; - } - voxel_pointer++; - WVP++; - } - voxel_pointer += 2; - WVP += 2; + for (j=1; j < volume_width - 1; j++) + { + if (voxel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); + D4 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D5 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; } - voxel_pointer += 2 * volume_width; - WVP += 2 * volume_width; + voxel_pointer++; + WVP++; + } + voxel_pointer += 2; + WVP += 2; } + voxel_pointer += 2 * volume_width; + WVP += 2 * volume_width; + } - if (x_connectivity == 1) + if (params->x_connectivity == 1) + { + //calculating reliability for the front side of the phase volume...add volume_width + WVP = wrappedVolume + frame_size + volume_width; + voxel_pointer = voxel + frame_size + volume_width; + for (n=1; n < volume_depth - 1; ++n) { - //calculating reliability for the front side of the phase volume...add volume_width - WVP = wrappedVolume + frame_size + volume_width; - voxel_pointer = voxel + frame_size + volume_width; - for (n=1; n < volume_depth - 1; ++n) - { - for (i=1; i < volume_height - 1; ++i) - { - if (voxel_pointer->extended_mask == 255) - { - H = wrap(*(WVP + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); - V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); - N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); - D1 = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); - D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + 2 * volume_width - 1)); - D3 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); - D4 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); - D5 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 2 * volume_width - 1)); - D6 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); - D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); - D8 = wrap(*(WVP - frame_size + 2 * volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); - D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); - D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 - + D7*D7 + D8*D8 + D9*D9 + D10*D10; - } - voxel_pointer += volume_width; - WVP += volume_width; - } - voxel_pointer += 2 * volume_width; - WVP += 2 * volume_width; + for (i=1; i < volume_height - 1; ++i) + { + if (voxel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WVP + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + 2 * volume_width - 1)); + D3 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); + D4 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D5 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 2 * volume_width - 1)); + D6 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D8 = wrap(*(WVP - frame_size + 2 * volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; } + voxel_pointer += volume_width; + WVP += volume_width; + } + voxel_pointer += 2 * volume_width; + WVP += 2 * volume_width; + } - //calculating reliability for the rear side of the phase volume..... subtract volume_width - WVP = wrappedVolume + frame_size + 2 * volume_width - 1; - voxel_pointer = voxel + frame_size + 2 * volume_width - 1; - for (n=1; n < volume_depth - 1; ++n) - { - for (i=1; i < volume_height - 1; ++i) - { - if (voxel_pointer->extended_mask == 255) - { - H = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); - V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); - N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); - D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); - D2 = wrap(*(WVP + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - 2 * volume_width + 1)); - D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); - D4 = wrap(*(WVP - frame_size - 2 * volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); - D5 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); - D6 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); - D7 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); - D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 2 * volume_width + 1)); - D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); - D10 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 - + D7*D7 + D8*D8 + D9*D9 + D10*D10; - } - voxel_pointer += volume_width; - WVP += volume_width; - } - voxel_pointer += 2 * volume_width; - WVP += 2 * volume_width; - } - } - - if (y_connectivity == 1) + //calculating reliability for the rear side of the phase volume..... subtract volume_width + WVP = wrappedVolume + frame_size + 2 * volume_width - 1; + voxel_pointer = voxel + frame_size + 2 * volume_width - 1; + for (n=1; n < volume_depth - 1; ++n) { - //calculating reliability for the left side of the phase volume...add frame_size - WVP = wrappedVolume + frame_size + 1; - voxel_pointer = voxel + frame_size + 1; - for (n=1; n < volume_depth - 1; ++n) - { - for (j=1; j < volume_width - 1; ++j) - { - if (voxel_pointer->extended_mask == 255) - { - H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); - V = wrap(*(WVP + frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); - N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); - D1 = wrap(*(WVP + frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); - D2 = wrap(*(WVP + frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); - D3 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); - D4 = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); - D5 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); - D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); - D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); - D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width + 1)); - D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width)); - D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 - + D7*D7 + D8*D8 + D9*D9 + D10*D10; - } - voxel_pointer++; - WVP++; - } - voxel_pointer += frame_size - volume_width + 2; - WVP += frame_size - volume_width + 2; - } + for (i=1; i < volume_height - 1; ++i) + { + if (voxel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + D2 = wrap(*(WVP + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - 2 * volume_width + 1)); + D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D4 = wrap(*(WVP - frame_size - 2 * volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D5 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D6 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D7 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 2 * volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer += volume_width; + WVP += volume_width; + } + voxel_pointer += 2 * volume_width; + WVP += 2 * volume_width; + } + } - //calculating reliability for the right side of the phase volume...subtract frame_size - WVP = wrappedVolume + 2 * frame_size - volume_width + 1; - voxel_pointer = voxel + 2 * frame_size - volume_width + 1; - for (n=1; n < volume_depth - 1; ++n) - { - for (j=1; j < volume_width - 1; ++j) - { - if (voxel_pointer->extended_mask == 255) - { - H = wrap(*(WVP + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); - V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width)); - N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); - D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width + 1)); - D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width - 1)); - D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1) ); - D4 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); - D5 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); - D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); - D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); - D8 = wrap(*(WVP - 2 * frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); - D9 = wrap(*(WVP - 2 * frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); - D10 = wrap(*(WVP - 2 * frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 - + D7*D7 + D8*D8 + D9*D9 + D10*D10; - } - voxel_pointer++; - WVP++; - } - voxel_pointer += frame_size - volume_width + 2; - WVP += frame_size - volume_width + 2; - } - } - - if (z_connectivity == 1) + if (params->y_connectivity == 1) + { + //calculating reliability for the left side of the phase volume...add frame_size + WVP = wrappedVolume + frame_size + 1; + voxel_pointer = voxel + frame_size + 1; + for (n=1; n < volume_depth - 1; ++n) { - //calculating reliability for the bottom side of the phase volume...add volume_size - WVP = wrappedVolume + volume_width + 1; - voxel_pointer = voxel + volume_width + 1; - for (i=1; i < volume_height - 1; ++i) - { - for (j=1; j < volume_width - 1; ++j) - { - if (voxel_pointer->extended_mask == 255) - { - H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); - V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); - N = wrap(*(WVP + frame_size) - *WVP) - wrap(*WVP - *(WVP + volume_size - frame_size)); - D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); - D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); - D3 = wrap(*(WVP + volume_size - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); - D4 = wrap(*(WVP + volume_size - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); - D5 = wrap(*(WVP + volume_size - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); - D6 = wrap(*(WVP + volume_size - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); - D7 = wrap(*(WVP + volume_size - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); - D8 = wrap(*(WVP + volume_size - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); - D9 = wrap(*(WVP + volume_size - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); - D10 = wrap(*(WVP + volume_size - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 - + D7*D7 + D8*D8 + D9*D9 + D10*D10; - } - voxel_pointer++; - WVP++; - } - voxel_pointer += 2; - WVP += 2; - } + for (j=1; j < volume_width - 1; ++j) + { + if (voxel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + V = wrap(*(WVP + frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP + frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP + frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D3 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); + D4 = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D5 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += frame_size - volume_width + 2; + WVP += frame_size - volume_width + 2; + } - //calculating reliability for the top side of the phase volume...subtract volume_size - WVP = wrappedVolume + volume_size - frame_size + volume_width + 1; - voxel_pointer = voxel + volume_size - frame_size + volume_width + 1; - for (i=1; i < volume_height - 1; ++i) - { - for (j=1; j < volume_width - 1; ++j) - { - if (voxel_pointer->extended_mask == 255) - { - H = wrap(*(WVP + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); - V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); - N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size)); - D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); - D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); - D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width + 1)); - D4 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width - 1)); - D5 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width)); - D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + 1)); - D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - 1)); - D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width + 1)); - D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width)); - D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 - + D7*D7 + D8*D8 + D9*D9 + D10*D10; - } - voxel_pointer++; - WVP++; - } - voxel_pointer += 2; - WVP += 2; - } - } + //calculating reliability for the right side of the phase volume...subtract frame_size + WVP = wrappedVolume + 2 * frame_size - volume_width + 1; + voxel_pointer = voxel + 2 * frame_size - volume_width + 1; + for (n=1; n < volume_depth - 1; ++n) + { + for (j=1; j < volume_width - 1; ++j) + { + if (voxel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WVP + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width - 1)); + D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1) ); + D4 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D5 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D8 = wrap(*(WVP - 2 * frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D9 = wrap(*(WVP - 2 * frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP - 2 * frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += frame_size - volume_width + 2; + WVP += frame_size - volume_width + 2; + } + } + + if (params->z_connectivity == 1) + { + //calculating reliability for the bottom side of the phase volume...add volume_size + WVP = wrappedVolume + volume_width + 1; + voxel_pointer = voxel + volume_width + 1; + for (i=1; i < volume_height - 1; ++i) + { + for (j=1; j < volume_width - 1; ++j) + { + if (voxel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP + frame_size) - *WVP) - wrap(*WVP - *(WVP + volume_size - frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D3 = wrap(*(WVP + volume_size - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width + 1)); + D4 = wrap(*(WVP + volume_size - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width)); + D5 = wrap(*(WVP + volume_size - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + volume_width - 1)); + D6 = wrap(*(WVP + volume_size - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size + 1)); + D7 = wrap(*(WVP + volume_size - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); + D8 = wrap(*(WVP + volume_size - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); + D9 = wrap(*(WVP + volume_size - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); + D10 = wrap(*(WVP + volume_size - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += 2; + WVP += 2; + } + + //calculating reliability for the top side of the phase volume...subtract volume_size + WVP = wrappedVolume + volume_size - frame_size + volume_width + 1; + voxel_pointer = voxel + volume_size - frame_size + volume_width + 1; + for (i=1; i < volume_height - 1; ++i) + { + for (j=1; j < volume_width - 1; ++j) + { + if (voxel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WVP + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); + V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); + N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size)); + D1 = wrap(*(WVP - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + volume_width + 1)); + D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); + D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width + 1)); + D4 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width - 1)); + D5 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width)); + D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + 1)); + D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - 1)); + D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width + 1)); + D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width)); + D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width - 1)); + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + + D7*D7 + D8*D8 + D9*D9 + D10*D10; + } + voxel_pointer++; + WVP++; + } + voxel_pointer += 2; + WVP += 2; + } + } } -//calculate the reliability of the horizontal edges of the volume -//it is calculated by adding the reliability of voxel and the relibility of -//its right neighbour -//edge is calculated between a voxel and its next neighbour -void horizontalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth) +//calculate the reliability of the horizontal edges of the volume. it +//is calculated by adding the reliability of voxel and the relibility +//of its right neighbour. edge is calculated between a voxel and its +//next neighbour +void horizontalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth, params_t *params) { - int n, i, j; - EDGE *edge_pointer = edge; - VOXELM *voxel_pointer = voxel; + int n, i, j; + EDGE *edge_pointer = edge; + VOXELM *voxel_pointer = voxel; + int no_of_edges = params->no_of_edges; - for (n=0; n < volume_depth; n++) + for (n=0; n < volume_depth; n++) + { + for (i = 0; i < volume_height; i++) { - for (i = 0; i < volume_height; i++) + for (j = 0; j < volume_width - 1; j++) + { + if (voxel_pointer->input_mask == NOMASK && (voxel_pointer + 1)->input_mask == NOMASK ) { - for (j = 0; j < volume_width - 1; j++) - { - if (voxel_pointer->input_mask == 255 && (voxel_pointer + 1)->input_mask == 255 ) - { - edge_pointer->pointer_1 = voxel_pointer; - edge_pointer->pointer_2 = (voxel_pointer+1); - edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + 1)->reliability; - edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + 1)->value); - edge_pointer++; - No_of_edges++; - } - voxel_pointer++; - } - voxel_pointer++; + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer+1); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + 1)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + 1)->value); + edge_pointer++; + no_of_edges++; } + voxel_pointer++; + } + voxel_pointer++; } - if (x_connectivity == 1) + } + if (params->x_connectivity == 1) + { + voxel_pointer = voxel + volume_width - 1; + for (n=0; n < volume_depth; n++) { - voxel_pointer = voxel + volume_width - 1; - for (n=0; n < volume_depth; n++) + for (i = 0; i < volume_height; i++) + { + if (voxel_pointer->input_mask == NOMASK && (voxel_pointer - volume_width + 1)->input_mask == NOMASK ) { - for (i = 0; i < volume_height; i++) - { - if (voxel_pointer->input_mask == 255 && (voxel_pointer - volume_width + 1)->input_mask == 255 ) - { - edge_pointer->pointer_1 = voxel_pointer; - edge_pointer->pointer_2 = (voxel_pointer - volume_width + 1); - edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - volume_width + 1)->reliability; - edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - volume_width + 1)->value); - edge_pointer++; - No_of_edges++; - } - voxel_pointer += volume_width; - } + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer - volume_width + 1); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - volume_width + 1)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - volume_width + 1)->value); + edge_pointer++; + no_of_edges++; } + voxel_pointer += volume_width; + } } + } + params->no_of_edges = no_of_edges; } -void verticalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth) +void verticalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth, params_t *params) { - int n, i, j; - VOXELM *voxel_pointer = voxel; - EDGE *edge_pointer = edge + No_of_edges; + int n, i, j; + int no_of_edges = params->no_of_edges; + VOXELM *voxel_pointer = voxel; + EDGE *edge_pointer = edge + no_of_edges; - for (n=0; n < volume_depth; n++) + for (n=0; n < volume_depth; n++) + { + for (i=0; iinput_mask == NOMASK && (voxel_pointer + volume_width)->input_mask == NOMASK ) { - for (j=0; j < volume_width; j++) - { - if (voxel_pointer->input_mask == 255 && (voxel_pointer + volume_width)->input_mask == 255 ) - { - edge_pointer->pointer_1 = voxel_pointer; - edge_pointer->pointer_2 = (voxel_pointer + volume_width); - edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + volume_width)->reliability; - edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + volume_width)->value); - edge_pointer++; - No_of_edges++; - } - voxel_pointer++; - } - } - voxel_pointer += volume_width; - } - - int frame_size = volume_width * volume_height; - int next_voxel = frame_size - volume_width; - if (y_connectivity == 1) - { - voxel_pointer = voxel + frame_size - volume_width; - for (n=0; n < volume_depth; n++) - { - for (i = 0; i < volume_width; i++) - { - if (voxel_pointer->input_mask == 255 && (voxel_pointer - next_voxel)->input_mask == 255 ) - { - edge_pointer->pointer_1 = voxel_pointer; - edge_pointer->pointer_2 = (voxel_pointer - next_voxel); - edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - next_voxel)->reliability; - edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - next_voxel)->value); - edge_pointer++; - No_of_edges++; - } - voxel_pointer++; - } - voxel_pointer += next_voxel + 1; + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer + volume_width); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + volume_width)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + volume_width)->value); + edge_pointer++; + no_of_edges++; } + voxel_pointer++; + } } + voxel_pointer += volume_width; + } + + int frame_size = volume_width * volume_height; + int next_voxel = frame_size - volume_width; + if (params->y_connectivity == 1) + { + voxel_pointer = voxel + frame_size - volume_width; + for (n=0; n < volume_depth; n++) + { + for (i = 0; i < volume_width; i++) + { + if (voxel_pointer->input_mask == NOMASK && (voxel_pointer - next_voxel)->input_mask == NOMASK ) + { + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer - next_voxel); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - next_voxel)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - next_voxel)->value); + edge_pointer++; + no_of_edges++; + } + voxel_pointer++; + } + voxel_pointer += next_voxel + 1; + } + } + params->no_of_edges = no_of_edges; } -void normalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth) +void normalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height, int volume_depth, params_t *params) { - int n, i, j; - int frame_size = volume_width * volume_height; - int volume_size = volume_width * volume_height * volume_depth; - VOXELM *voxel_pointer = voxel; - EDGE *edge_pointer = edge + No_of_edges; + int n, i, j; + int no_of_edges = params->no_of_edges; + int frame_size = volume_width * volume_height; + int volume_size = volume_width * volume_height * volume_depth; + VOXELM *voxel_pointer = voxel; + EDGE *edge_pointer = edge + no_of_edges; - for (n=0; n < volume_depth - 1; n++) + for (n=0; n < volume_depth - 1; n++) + { + for (i=0; iinput_mask == NOMASK && (voxel_pointer + frame_size)->input_mask == NOMASK ) { - for (j=0; j < volume_width; j++) - { - if (voxel_pointer->input_mask == 255 && (voxel_pointer + frame_size)->input_mask == 255 ) - { - edge_pointer->pointer_1 = voxel_pointer; - edge_pointer->pointer_2 = (voxel_pointer + frame_size); - edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + frame_size)->reliability; - edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + frame_size)->value); - edge_pointer++; - No_of_edges++; - } - voxel_pointer++; - } + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer + frame_size); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer + frame_size)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer + frame_size)->value); + edge_pointer++; + no_of_edges++; } + voxel_pointer++; + } } + } - int next_voxel = volume_size - frame_size; - if (z_connectivity == 1) + int next_voxel = volume_size - frame_size; + if (params->z_connectivity == 1) + { + voxel_pointer = voxel + next_voxel; + for (i=0; i < volume_height; i++) { - voxel_pointer = voxel + next_voxel; - for (i=0; i < volume_height; i++) + for (j = 0; j < volume_width; j++) + { + if (voxel_pointer->input_mask == NOMASK && (voxel_pointer - next_voxel)->input_mask == NOMASK ) { - for (j = 0; j < volume_width; j++) - { - if (voxel_pointer->input_mask == 255 && (voxel_pointer - next_voxel)->input_mask == 255 ) - { - edge_pointer->pointer_1 = voxel_pointer; - edge_pointer->pointer_2 = (voxel_pointer - next_voxel); - edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - next_voxel)->reliability; - edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - next_voxel)->value); - edge_pointer++; - No_of_edges++; - } - voxel_pointer++; - } + edge_pointer->pointer_1 = voxel_pointer; + edge_pointer->pointer_2 = (voxel_pointer - next_voxel); + edge_pointer->reliab = voxel_pointer->reliability + (voxel_pointer - next_voxel)->reliability; + edge_pointer->increment = find_wrap(voxel_pointer->value, (voxel_pointer - next_voxel)->value); + edge_pointer++; + no_of_edges++; } + voxel_pointer++; + } } + } + params->no_of_edges = no_of_edges; } //gather the voxels of the volume into groups -void gatherVOXELs(EDGE *edge) +void gatherVOXELs(EDGE *edge, params_t *params) { - int k; - VOXELM *VOXEL1; - VOXELM *VOXEL2; - VOXELM *group1; - VOXELM *group2; - EDGE *pointer_edge = edge; - int incremento; + int k; + VOXELM *VOXEL1; + VOXELM *VOXEL2; + VOXELM *group1; + VOXELM *group2; + EDGE *pointer_edge = edge; + int incremento; - for (k = 0; k < No_of_edges; k++) + for (k = 0; k < params->no_of_edges; k++) + { + VOXEL1 = pointer_edge->pointer_1; + VOXEL2 = pointer_edge->pointer_2; + + //VOXELM 1 and VOXELM 2 belong to different groups + //initially each voxel is in a group by itself and one voxel can construct a group + //no else or else if to this if + if (VOXEL2->head != VOXEL1->head) { - VOXEL1 = pointer_edge->pointer_1; - VOXEL2 = pointer_edge->pointer_2; + //VOXELM 2 is alone in its group + //merge this voxel with VOXELM 1 group and find the number of 2 pi to add + //to or subtract to unwrap it + if ((VOXEL2->next == NULL) && (VOXEL2->head == VOXEL2)) + { + VOXEL1->head->last->next = VOXEL2; + VOXEL1->head->last = VOXEL2; + (VOXEL1->head->number_of_voxels_in_group)++; + VOXEL2->head=VOXEL1->head; + VOXEL2->increment = VOXEL1->increment-pointer_edge->increment; + } - //VOXELM 1 and VOXELM 2 belong to different groups - //initially each voxel is in a group by itself and one voxel can construct a group - //no else or else if to this if - if (VOXEL2->head != VOXEL1->head) - { - //VOXELM 2 is alone in its group - //merge this voxel with VOXELM 1 group and find the number of 2 pi to add - //to or subtract to unwrap it - if ((VOXEL2->next == NULL) && (VOXEL2->head == VOXEL2)) - { - VOXEL1->head->last->next = VOXEL2; - VOXEL1->head->last = VOXEL2; - (VOXEL1->head->number_of_voxels_in_group)++; - VOXEL2->head=VOXEL1->head; - VOXEL2->increment = VOXEL1->increment-pointer_edge->increment; - } + //VOXELM 1 is alone in its group + //merge this voxel with VOXELM 2 group and find the number of 2 pi to add + //to or subtract to unwrap it + else if ((VOXEL1->next == NULL) && (VOXEL1->head == VOXEL1)) + { + VOXEL2->head->last->next = VOXEL1; + VOXEL2->head->last = VOXEL1; + (VOXEL2->head->number_of_voxels_in_group)++; + VOXEL1->head = VOXEL2->head; + VOXEL1->increment = VOXEL2->increment+pointer_edge->increment; + } - //VOXELM 1 is alone in its group - //merge this voxel with VOXELM 2 group and find the number of 2 pi to add - //to or subtract to unwrap it - else if ((VOXEL1->next == NULL) && (VOXEL1->head == VOXEL1)) - { - VOXEL2->head->last->next = VOXEL1; - VOXEL2->head->last = VOXEL1; - (VOXEL2->head->number_of_voxels_in_group)++; - VOXEL1->head = VOXEL2->head; - VOXEL1->increment = VOXEL2->increment+pointer_edge->increment; - } - - //VOXELM 1 and VOXELM 2 both have groups - else + //VOXELM 1 and VOXELM 2 both have groups + else { - group1 = VOXEL1->head; - group2 = VOXEL2->head; - //if the no. of voxels in VOXELM 1 group is larger than the no. of voxels - //in VOXELM 2 group. Merge VOXELM 2 group to VOXELM 1 group - //and find the number of wraps between VOXELM 2 group and VOXELM 1 group - //to unwrap VOXELM 2 group with respect to VOXELM 1 group. - //the no. of wraps will be added to VOXELM 2 grop in the future - if (group1->number_of_voxels_in_group > group2->number_of_voxels_in_group) - { - //merge VOXELM 2 with VOXELM 1 group - group1->last->next = group2; - group1->last = group2->last; - group1->number_of_voxels_in_group = group1->number_of_voxels_in_group + group2->number_of_voxels_in_group; - incremento = VOXEL1->increment-pointer_edge->increment - VOXEL2->increment; - //merge the other voxels in VOXELM 2 group to VOXELM 1 group - while (group2 != NULL) - { - group2->head = group1; - group2->increment += incremento; - group2 = group2->next; - } - } + group1 = VOXEL1->head; + group2 = VOXEL2->head; + //if the no. of voxels in VOXELM 1 group is larger than the no. of voxels + //in VOXELM 2 group. Merge VOXELM 2 group to VOXELM 1 group + //and find the number of wraps between VOXELM 2 group and VOXELM 1 group + //to unwrap VOXELM 2 group with respect to VOXELM 1 group. + //the no. of wraps will be added to VOXELM 2 grop in the future + if (group1->number_of_voxels_in_group > group2->number_of_voxels_in_group) + { + //merge VOXELM 2 with VOXELM 1 group + group1->last->next = group2; + group1->last = group2->last; + group1->number_of_voxels_in_group = group1->number_of_voxels_in_group + group2->number_of_voxels_in_group; + incremento = VOXEL1->increment-pointer_edge->increment - VOXEL2->increment; + //merge the other voxels in VOXELM 2 group to VOXELM 1 group + while (group2 != NULL) + { + group2->head = group1; + group2->increment += incremento; + group2 = group2->next; + } + } - //if the no. of voxels in VOXELM 2 group is larger than the no. of voxels - //in VOXELM 1 group. Merge VOXELM 1 group to VOXELM 2 group - //and find the number of wraps between VOXELM 2 group and VOXELM 1 group - //to unwrap VOXELM 1 group with respect to VOXELM 2 group. - //the no. of wraps will be added to VOXELM 1 grop in the future - else + //if the no. of voxels in VOXELM 2 group is larger than the no. of voxels + //in VOXELM 1 group. Merge VOXELM 1 group to VOXELM 2 group + //and find the number of wraps between VOXELM 2 group and VOXELM 1 group + //to unwrap VOXELM 1 group with respect to VOXELM 2 group. + //the no. of wraps will be added to VOXELM 1 grop in the future + else { - //merge VOXELM 1 with VOXELM 2 group - group2->last->next = group1; - group2->last = group1->last; - group2->number_of_voxels_in_group = group2->number_of_voxels_in_group + group1->number_of_voxels_in_group; - incremento = VOXEL2->increment + pointer_edge->increment - VOXEL1->increment; - //merge the other voxels in VOXELM 2 group to VOXELM 1 group - while (group1 != NULL) - { - group1->head = group2; - group1->increment += incremento; - group1 = group1->next; - } // while + //merge VOXELM 1 with VOXELM 2 group + group2->last->next = group1; + group2->last = group1->last; + group2->number_of_voxels_in_group = group2->number_of_voxels_in_group + group1->number_of_voxels_in_group; + incremento = VOXEL2->increment + pointer_edge->increment - VOXEL1->increment; + //merge the other voxels in VOXELM 2 group to VOXELM 1 group + while (group1 != NULL) + { + group1->head = group2; + group1->increment += incremento; + group1 = group1->next; + } // while } // else } //else } //if - pointer_edge++; - } + pointer_edge++; + } } //unwrap the volume -void unwrapVolume(VOXELM *voxel, int volume_width, int volume_height, int volume_depth) +void unwrapVolume(VOXELM *voxel, int volume_width, int volume_height, int volume_depth) { - int i; - int volume_size = volume_width * volume_height * volume_depth; - VOXELM *voxel_pointer=voxel; + int i; + int volume_size = volume_width * volume_height * volume_depth; + VOXELM *voxel_pointer=voxel; - for (i = 0; i < volume_size; i++) - { - voxel_pointer->value += TWOPI * (float)(voxel_pointer->increment); - voxel_pointer++; + for (i = 0; i < volume_size; i++) + { + voxel_pointer->value += TWOPI * (float)(voxel_pointer->increment); + voxel_pointer++; } } //set the masked voxels (mask = 0) to the minimum of the unwrapper phase void maskVolume(VOXELM *voxel, unsigned char *input_mask, int volume_width, int volume_height, int volume_depth) { - int volume_width_plus_one = volume_width + 1; - int volume_height_plus_one = volume_height + 1; - int volume_width_minus_one = volume_width - 1; - int volume_height_minus_one = volume_height - 1; + int volume_width_plus_one = volume_width + 1; + int volume_height_plus_one = volume_height + 1; + int volume_width_minus_one = volume_width - 1; + int volume_height_minus_one = volume_height - 1; - VOXELM *pointer_voxel = voxel; - unsigned char *IMP = input_mask; //input mask pointer - float min=99999999.; - int i, j; - int volume_size = volume_width * volume_height * volume_depth; + VOXELM *pointer_voxel = voxel; + unsigned char *IMP = input_mask; //input mask pointer + float min=99999999.; + int i, j; + int volume_size = volume_width * volume_height * volume_depth; - //find the minimum of the unwrapped phase - for (i = 0; i < volume_size; i++) + //find the minimum of the unwrapped phase + for (i = 0; i < volume_size; i++) + { + if ((pointer_voxel->value < min) && (*IMP == NOMASK)) + min = pointer_voxel->value; + + pointer_voxel++; + IMP++; + } + + pointer_voxel = voxel; + IMP = input_mask; + + //set the masked voxels to minimum + for (i = 0; i < volume_size; i++) + { + if ((*IMP) == MASK) { - if ((pointer_voxel->value < min) && (*IMP == 255)) - min = pointer_voxel->value; - - pointer_voxel++; - IMP++; - } - - pointer_voxel = voxel; - IMP = input_mask; - - //set the masked voxels to minimum - for (i = 0; i < volume_size; i++) - { - if ((*IMP) == 0) - { - pointer_voxel->value = min; - } - pointer_voxel++; - IMP++; + pointer_voxel->value = min; } + pointer_voxel++; + IMP++; + } } -//the input to this unwrapper is an array that contains the wrapped phase map. -//copy the volume on the buffer passed to this unwrapper to over-write the unwrapped -//phase map on the buffer of the wrapped phase map. +//the input to this unwrapper is an array that contains the wrapped +//phase map. copy the volume on the buffer passed to this unwrapper +//to over-write the unwrapped phase map on the buffer of the wrapped +//phase map. void returnVolume(VOXELM *voxel, float *unwrappedVolume, int volume_width, int volume_height, int volume_depth) { - int i; - int volume_size = volume_width * volume_height * volume_depth; - float *unwrappedVolume_pointer = unwrappedVolume; - VOXELM *voxel_pointer = voxel; + int i; + int volume_size = volume_width * volume_height * volume_depth; + float *unwrappedVolume_pointer = unwrappedVolume; + VOXELM *voxel_pointer = voxel; - for (i=0; i < volume_size; i++) - { - *unwrappedVolume_pointer = voxel_pointer->value; - voxel_pointer++; - unwrappedVolume_pointer++; - } + for (i=0; i < volume_size; i++) + { + *unwrappedVolume_pointer = voxel_pointer->value; + voxel_pointer++; + unwrappedVolume_pointer++; + } } //the main function of the unwrapper -int main() -{ - float *WrappedVolume, *UnwrappedVolume; - unsigned char *input_mask, *extended_mask; - int volume_width = 64; - int volume_height = 64; - int volume_depth = 46; - int volume_size = volume_height * volume_width * volume_depth; - int No_of_Edges_initially = 3 * volume_width * volume_height * volume_depth; +unwrap3D(float* wrapped_volume, float* unwrapped_volume, unsigned char* input_mask, + int volume_width, int volume_height, int volume_depth, + int wrap_around_x, int wrap_around_y, int wrap_around_z) +{ + params_t params = {TWOPI, 0, 0, 0, 0} + unsigned char *extended_mask; + int volume_size = volume_height * volume_width * volume_depth; + int No_of_Edges_initially = 3 * volume_width * volume_height * volume_depth; - WrappedVolume = (float *) calloc(volume_size, sizeof(float)); - read_data("MRI wrapped phase volume 64X64X46.dat", WrappedVolume, volume_size); + extended_mask = (unsigned char *) calloc(volume_size, sizeof(unsigned char)); + VOXELM *voxel = (VOXELM *) calloc(volume_size, sizeof(VOXELM)); + EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; - input_mask = (unsigned char *) calloc(volume_size, sizeof(unsigned char)); - extended_mask = (unsigned char *) calloc(volume_size, sizeof(unsigned char)); - read_mask("mask3d.dat", input_mask, volume_size); + extend_mask(input_mask, extended_mask, volume_width, volume_height, volume_depth, ¶ms); + initialiseVOXELs(WrappedVolume, input_mask, extended_mask, voxel, volume_width, volume_height, volume_depth); + calculate_reliability(WrappedVolume, voxel, volume_width, volume_height, volume_depth, ¶ms); + horizontalEDGEs(voxel, edge, volume_width, volume_height, volume_depth, ¶ms); + verticalEDGEs(voxel, edge, volume_width, volume_height, volume_depth, ¶ms); + normalEDGEs(voxel, edge, volume_width, volume_height, volume_depth, ¶ms); - UnwrappedVolume = (float *) calloc(volume_size, sizeof(float)); - VOXELM *voxel = (VOXELM *) calloc(volume_size, sizeof(VOXELM)); - EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; + //sort the EDGEs depending on their reiability. The VOXELs with higher relibility (small value) first + quicker_sort(edge, edge + params.no_of_edges - 1); - extend_mask(input_mask, extended_mask, volume_width, volume_height, volume_depth); - - initialiseVOXELs(WrappedVolume, input_mask, extended_mask, voxel, volume_width, volume_height, volume_depth); + //gather VOXELs into groups + gatherVOXELs(edge, ¶ms); - calculate_reliability(WrappedVolume, voxel, volume_width, volume_height, volume_depth); + unwrapVolume(voxel, volume_width, volume_height, volume_depth); + maskVolume(voxel, input_mask, volume_width, volume_height, volume_depth); - horizontalEDGEs(voxel, edge, volume_width, volume_height, volume_depth); + //copy the volume from VOXELM structure to the unwrapped phase array passed to this function + returnVolume(voxel, UnwrappedVolume, volume_width, volume_height, volume_depth); - verticalEDGEs(voxel, edge, volume_width, volume_height, volume_depth); - - normalEDGEs(voxel, edge, volume_width, volume_height, volume_depth); - - //sort the EDGEs depending on their reiability. The VOXELs with higher relibility (small value) first - quicker_sort(edge, edge + No_of_edges - 1); - - //gather VOXELs into groups - gatherVOXELs(edge); - - unwrapVolume(voxel, volume_width, volume_height, volume_depth); - - maskVolume(voxel, input_mask, volume_width, volume_height, volume_depth); - - //copy the volume from VOXELM structure to the unwrapped phase array passed to this function - returnVolume(voxel, UnwrappedVolume, volume_width, volume_height, volume_depth); - - free(edge); - free(voxel); - - write_data("unwrapped.dat", UnwrappedVolume, volume_size); - free(UnwrappedVolume); - free(WrappedVolume); - free(input_mask); - - return 1; + free(edge); + free(voxel); + free(extended_mask); } diff --git a/unwrap2D/setup.py b/unwrap2D/setup.py index a8be8565..cc780a48 100644 --- a/unwrap2D/setup.py +++ b/unwrap2D/setup.py @@ -11,12 +11,18 @@ ext_modules = [ ], include_dirs = [np.get_include(),], ), + Extension('unwrap3D', + ['unwrap3D.pyx', + 'Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c', + ], + include_dirs = [np.get_include(),], + ), ] import numpy as np setup( - name = 'unwrp2D', + name = 'unwrap', #ext_modules = cythonize(['cytransient.pyx',], # include_path = [np.get_include(),], # ), diff --git a/unwrap2D/unwrap3D.pyx b/unwrap2D/unwrap3D.pyx new file mode 100644 index 00000000..1df8a4d6 --- /dev/null +++ b/unwrap2D/unwrap3D.pyx @@ -0,0 +1,18 @@ +cdef extern unwrap3D(float* wrapped_volume, + float* unwrapped_volume, + unsigned char* input_mask, + int image_width, int image_height, int volume_depth, + int wrap_around_x, int wrap_around_y, int wrap_around_z) + +def _unwrap3D(float[:,:,::1] array, + unsigned char[:,:,::1] mask, + float[:,:,::1] unwrapped_array, + wrap_around_x, wrap_around_y, wrap_around_z): + unwrap3D(&array[0,0,0], + &unwrapped_array[0,0,0], + &mask[0,0,0], + array.shape[0], array.shape[1], array.shape[2], + wrap_around_x, wrap_around_y, wrap_around_z, + ) + + From 96c293ca85e026499dfaef96971ddddbd18541a2 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sun, 13 May 2012 23:38:38 +0200 Subject: [PATCH 14/84] unwrap: unified 2d-3d interface, 2d tested ok, --- ...rapper_with_mask_and_wrap_around_option.c} | 8 +- ...wrapper_with_mask_and_wrap_around_option.c | 2 +- unwrap2D/test_unwrap.py | 73 +++++++++++++++---- unwrap2D/unwrap.py | 28 +++++-- unwrap2D/unwrap2D.pyx | 2 +- unwrap2D/unwrap3D.pyx | 2 +- 6 files changed, 85 insertions(+), 30 deletions(-) rename unwrap2D/{Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp => Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c} (99%) diff --git a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c similarity index 99% rename from unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp rename to unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c index 84b0b4ab..d7524d7c 100644 --- a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.cpp +++ b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c @@ -1015,7 +1015,7 @@ unwrap3D(float* wrapped_volume, float* unwrapped_volume, unsigned char* input_ma int volume_width, int volume_height, int volume_depth, int wrap_around_x, int wrap_around_y, int wrap_around_z) { - params_t params = {TWOPI, 0, 0, 0, 0} + params_t params = {TWOPI, wrap_around_x, wrap_around_y, wrap_around_z, 0}; unsigned char *extended_mask; int volume_size = volume_height * volume_width * volume_depth; int No_of_Edges_initially = 3 * volume_width * volume_height * volume_depth; @@ -1025,8 +1025,8 @@ unwrap3D(float* wrapped_volume, float* unwrapped_volume, unsigned char* input_ma EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; extend_mask(input_mask, extended_mask, volume_width, volume_height, volume_depth, ¶ms); - initialiseVOXELs(WrappedVolume, input_mask, extended_mask, voxel, volume_width, volume_height, volume_depth); - calculate_reliability(WrappedVolume, voxel, volume_width, volume_height, volume_depth, ¶ms); + initialiseVOXELs(wrapped_volume, input_mask, extended_mask, voxel, volume_width, volume_height, volume_depth); + calculate_reliability(wrapped_volume, voxel, volume_width, volume_height, volume_depth, ¶ms); horizontalEDGEs(voxel, edge, volume_width, volume_height, volume_depth, ¶ms); verticalEDGEs(voxel, edge, volume_width, volume_height, volume_depth, ¶ms); normalEDGEs(voxel, edge, volume_width, volume_height, volume_depth, ¶ms); @@ -1041,7 +1041,7 @@ unwrap3D(float* wrapped_volume, float* unwrapped_volume, unsigned char* input_ma maskVolume(voxel, input_mask, volume_width, volume_height, volume_depth); //copy the volume from VOXELM structure to the unwrapped phase array passed to this function - returnVolume(voxel, UnwrappedVolume, volume_width, volume_height, volume_depth); + returnVolume(voxel, unwrapped_volume, volume_width, volume_height, volume_depth); free(edge); free(voxel); diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index 131ec517..67d61c51 100644 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -684,7 +684,7 @@ unwrap2D(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, int image_width, int image_height, int wrap_around_x, int wrap_around_y) { - params_t params = {TWOPI, 0, 0, 0}; + params_t params = {TWOPI, wrap_around_x, wrap_around_y, 0}; unsigned char *extended_mask; int image_size = image_height * image_width; int No_of_Edges_initially = 2 * image_width * image_height; diff --git a/unwrap2D/test_unwrap.py b/unwrap2D/test_unwrap.py index af94c934..e297f1ce 100644 --- a/unwrap2D/test_unwrap.py +++ b/unwrap2D/test_unwrap.py @@ -1,30 +1,51 @@ from numpy.testing import * -from unwrap import unwrap2D +from unwrap import unwrap import numpy as np -from numpy import outer, arange, ones, abs, empty, power, indices - -import numpy.ma as ma def test_unwrap2D(): - nx, ny = 32, 32 + nx, ny = 16, 32 x = np.arange(nx) y = np.arange(ny) - x.shape = (1,-1) - y.shape = (-1,1) + x.shape = (-1,1) + y.shape = (1,-1) z = np.exp(1j*x*0.2*np.pi) * np.exp(1j*y*0.1*np.pi) phi_w = np.angle(z) - phi = unwrap2D(phi_w) + phi = unwrap(phi_w, + wrap_around_axis_0 = False) mask = 0*np.ones((nx, ny), dtype = np.uint8) mask[4:16, 4:16] = 1 - phi_w_ma = ma.array(phi_w, dtype = np.float32, mask = mask) - phi_ma = unwrap2D(phi_w_ma) + phi_w_ma = np.ma.array(phi_w, dtype = np.float32, mask = mask) + phi_ma = unwrap(phi_w_ma) - return (phi_w/(np.pi*2), phi/(np.pi*2), + return (phi/(np.pi*2), + phi_w/(np.pi*2), phi/(np.pi*2), phi_w_ma/(np.pi*2), phi_ma/(np.pi*2),) +def test_unwrap3D(): + x, y, z = np.ogrid[:8, :8, :4] + + phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) + phi_wrapped = np.angle(np.exp(1j*phi)) + phi_unwrapped = unwrap(phi_wrapped) + + mask = np.zeros_like(phi, dtype = np.uint8) + mask[4:6, 4:6, 1:3] = 1 + phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) + phi_unwrapped_masked = unwrap(phi_wrapped_masked) + + s = np.round(phi_unwrapped[0,0,0]/(2*np.pi)) + assert_array_almost_equal(phi/(2*np.pi), phi_unwrapped/(2*np.pi) - s, decimal = 5) + + assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked, decimal = 5) + + return (phi/(np.pi*2), + phi_wrapped/(np.pi*2), phi_unwrapped/(np.pi*2), + phi_wrapped_masked/(np.pi*2), phi_unwrapped_masked/(np.pi*2),) + + # class test_unwrap(TestCase): # def test_simple2d(self, level=1): @@ -52,15 +73,35 @@ def test_unwrap2D(): if __name__=="__main__": #NumpyTest().run() import matplotlib.pyplot as plt - p1,p2,p3,p4 = test_unwrap2D() + + p0,p1,p2,p3,p4 = test_unwrap2D() + plt.figure(1) plt.clf() - plt.subplot(221) + plt.subplot(322) + plt.imshow(p0,interpolation = 'nearest') + plt.subplot(323) plt.imshow(p1,interpolation = 'nearest') - plt.subplot(222) + plt.subplot(324) plt.imshow(p2, interpolation = 'nearest') - plt.subplot(223) + plt.subplot(325) plt.imshow(p3, interpolation = 'nearest') - plt.subplot(224) + plt.subplot(326) plt.imshow(p4, interpolation = 'nearest') plt.draw() + + + p0,p1,p2,p3,p4 = test_unwrap3D() + plt.figure(2) + plt.clf() + plt.subplot(322) + plt.imshow(p0[:,:,0],interpolation = 'nearest') + plt.subplot(323) + plt.imshow(p1[:,:,0],interpolation = 'nearest') + plt.subplot(324) + plt.imshow(p2[:,:,0], interpolation = 'nearest') + plt.subplot(325) + plt.imshow(p3[:,:,0], interpolation = 'nearest') + plt.subplot(326) + plt.imshow(p4[:,:,0], interpolation = 'nearest') + plt.draw() plt.show() diff --git a/unwrap2D/unwrap.py b/unwrap2D/unwrap.py index 8a61a779..a4fb7d2c 100644 --- a/unwrap2D/unwrap.py +++ b/unwrap2D/unwrap.py @@ -1,15 +1,29 @@ import numpy as np -from unwrap2D import _unwrap2D -def unwrap2D(wrapped_array, wrap_around_x = False, wrap_around_y = False): +def unwrap(wrapped_array, + wrap_around_axis_0 = False, + wrap_around_axis_1 = False, + wrap_around_axis_2 = False): + wrapped_array = np.require(wrapped_array, np.float32, ['C']) + if wrapped_array.ndim not in [2,3]: + raise ValueError('input array needs to have 2 or 3 dimensions') + wrapped_array_masked = np.ma.asarray(wrapped_array) unwrapped_array = np.empty_like(wrapped_array_masked.data) - - _unwrap2D(wrapped_array_masked.data, - np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), - unwrapped_array, - wrap_around_x, wrap_around_y) + if wrapped_array.ndim == 2: + import unwrap2D + unwrap2D._unwrap2D(wrapped_array_masked.data, + np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), + unwrapped_array, + bool(wrap_around_axis_0), bool(wrap_around_axis_1)) + elif wrapped_array.ndim == 3: + import unwrap3D + unwrap3D._unwrap3D(wrapped_array_masked.data, + np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), + unwrapped_array, + bool(wrap_around_axis_0), bool(wrap_around_axis_1), bool(wrap_around_axis_2)) + if np.ma.isMaskedArray(wrapped_array): return np.ma.array(unwrapped_array, mask = wrapped_array_masked.mask) else: diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx index 2dd0b33c..c4ca7f31 100644 --- a/unwrap2D/unwrap2D.pyx +++ b/unwrap2D/unwrap2D.pyx @@ -13,7 +13,7 @@ def _unwrap2D(float[:,::1] array, unwrap2D(&array[0,0], &unwrapped_array[0,0], &mask[0,0], - array.shape[0], array.shape[1], + array.shape[1], array.shape[0], wrap_around_x, wrap_around_y, ) diff --git a/unwrap2D/unwrap3D.pyx b/unwrap2D/unwrap3D.pyx index 1df8a4d6..6d5507d1 100644 --- a/unwrap2D/unwrap3D.pyx +++ b/unwrap2D/unwrap3D.pyx @@ -11,7 +11,7 @@ def _unwrap3D(float[:,:,::1] array, unwrap3D(&array[0,0,0], &unwrapped_array[0,0,0], &mask[0,0,0], - array.shape[0], array.shape[1], array.shape[2], + array.shape[0], array.shape[1], array.shape[2], #TODO: check!!! wrap_around_x, wrap_around_y, wrap_around_z, ) From 2cbdef4bb27b94e126a499ff9f98fbd6235f9195 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Sun, 13 May 2012 23:45:38 +0200 Subject: [PATCH 15/84] unwrap: 3d tested ok --- unwrap2D/test_unwrap.py | 2 +- unwrap2D/unwrap3D.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unwrap2D/test_unwrap.py b/unwrap2D/test_unwrap.py index e297f1ce..eb2c3ee1 100644 --- a/unwrap2D/test_unwrap.py +++ b/unwrap2D/test_unwrap.py @@ -25,7 +25,7 @@ def test_unwrap2D(): phi_w_ma/(np.pi*2), phi_ma/(np.pi*2),) def test_unwrap3D(): - x, y, z = np.ogrid[:8, :8, :4] + x, y, z = np.ogrid[:8, :12, :4] phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) phi_wrapped = np.angle(np.exp(1j*phi)) diff --git a/unwrap2D/unwrap3D.pyx b/unwrap2D/unwrap3D.pyx index 6d5507d1..7a0aee9b 100644 --- a/unwrap2D/unwrap3D.pyx +++ b/unwrap2D/unwrap3D.pyx @@ -11,7 +11,7 @@ def _unwrap3D(float[:,:,::1] array, unwrap3D(&array[0,0,0], &unwrapped_array[0,0,0], &mask[0,0,0], - array.shape[0], array.shape[1], array.shape[2], #TODO: check!!! + array.shape[2], array.shape[1], array.shape[0], #TODO: check!!! wrap_around_x, wrap_around_y, wrap_around_z, ) From abb283fdf9e6de8853805b55dd9ab453260510b5 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Mon, 14 May 2012 11:51:10 +0200 Subject: [PATCH 16/84] unwrap: made it compile with MSVC (but crashes), still ok with gcc --- ...wrapper_with_mask_and_wrap_around_option.c | 34 ++++++++++--------- ...wrapper_with_mask_and_wrap_around_option.c | 30 ++++++++-------- unwrap2D/unwrap2D.pyx | 2 -- 3 files changed, 34 insertions(+), 32 deletions(-) mode change 100644 => 100755 unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c mode change 100644 => 100755 unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c mode change 100644 => 100755 unwrap2D/unwrap2D.pyx diff --git a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c old mode 100644 new mode 100755 index d7524d7c..e0e4cb94 --- a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c @@ -19,8 +19,8 @@ #include #include -static float PI = 3.141592654; -static float TWOPI = 6.283185307; +static float PI = 3.141592654f; +static float TWOPI = 6.283185307f; #define NOMASK 0 #define MASK 1 @@ -35,7 +35,7 @@ typedef struct } params_t; //VOXELM information -struct voxelm +struct VOXELM { int increment; //No. of 2*pi to add to the voxel to unwrap it int number_of_voxels_in_group;//No. of voxel in the voxel group @@ -45,16 +45,16 @@ struct voxelm unsigned char extended_mask; //MASK voxel is masked. NOMASK voxel is not masked int group; //group No. int new_group; - struct voxelm *head; //pointer to the first voxel in the group in the linked list - struct voxelm *last; //pointer to the last voxel in the group - struct voxelm *next; //pointer to the next voxel in the group + struct VOXELM *head; //pointer to the first voxel in the group in the linked list + struct VOXELM *last; //pointer to the last voxel in the group + struct VOXELM *next; //pointer to the next voxel in the group }; -typedef struct voxelm VOXELM; +typedef struct VOXELM VOXELM; //the EDGE is the line that connects two voxels. //if we have S voxels, then we have S horizontal edges and S vertical edges -struct edge +struct EDGE { float reliab; //reliabilty of the edge and it depends on the two voxels VOXELM *pointer_1; //pointer to the first voxel @@ -64,7 +64,7 @@ struct edge //the second }; -typedef struct edge EDGE; +typedef struct EDGE EDGE; //---------------start quicker_sort algorithm -------------------------------- #define swap(x,y) {EDGE t; t=x; x=y; y=t;} @@ -159,7 +159,7 @@ void initialiseVOXELs(float *WrappedVolume, unsigned char *input_mask, unsigned voxel_pointer->increment = 0; voxel_pointer->number_of_voxels_in_group = 1; voxel_pointer->value = *wrapped_volume_pointer; - voxel_pointer->reliability = 9999999 + rand(); + voxel_pointer->reliability = 9999999.f + rand(); voxel_pointer->input_mask = *input_mask_pointer; voxel_pointer->extended_mask = *extended_mask_pointer; voxel_pointer->head = voxel_pointer; @@ -738,6 +738,8 @@ void verticalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_heig int no_of_edges = params->no_of_edges; VOXELM *voxel_pointer = voxel; EDGE *edge_pointer = edge + no_of_edges; + int frame_size = volume_width * volume_height; + int next_voxel = frame_size - volume_width; for (n=0; n < volume_depth; n++) { @@ -760,8 +762,6 @@ void verticalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_heig voxel_pointer += volume_width; } - int frame_size = volume_width * volume_height; - int next_voxel = frame_size - volume_width; if (params->y_connectivity == 1) { voxel_pointer = voxel + frame_size - volume_width; @@ -793,7 +793,8 @@ void normalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height int frame_size = volume_width * volume_height; int volume_size = volume_width * volume_height * volume_depth; VOXELM *voxel_pointer = voxel; - EDGE *edge_pointer = edge + no_of_edges; + EDGE *edge_pointer = edge + no_of_edges; + int next_voxel = volume_size - frame_size; for (n=0; n < volume_depth - 1; n++) { @@ -816,7 +817,6 @@ void normalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height } - int next_voxel = volume_size - frame_size; if (params->z_connectivity == 1) { voxel_pointer = voxel + next_voxel; @@ -1017,12 +1017,14 @@ unwrap3D(float* wrapped_volume, float* unwrapped_volume, unsigned char* input_ma { params_t params = {TWOPI, wrap_around_x, wrap_around_y, wrap_around_z, 0}; unsigned char *extended_mask; + VOXELM *voxel; + EDGE *edge; int volume_size = volume_height * volume_width * volume_depth; int No_of_Edges_initially = 3 * volume_width * volume_height * volume_depth; extended_mask = (unsigned char *) calloc(volume_size, sizeof(unsigned char)); - VOXELM *voxel = (VOXELM *) calloc(volume_size, sizeof(VOXELM)); - EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; + voxel = (VOXELM *) calloc(volume_size, sizeof(VOXELM)); + edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; extend_mask(input_mask, extended_mask, volume_width, volume_height, volume_depth, ¶ms); initialiseVOXELs(wrapped_volume, input_mask, extended_mask, voxel, volume_width, volume_height, volume_depth); diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c old mode 100644 new mode 100755 index 67d61c51..3017c529 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -20,8 +20,8 @@ //TODO: remove global variables //TODO: make thresholds independent -static float PI = 3.141592654; -static float TWOPI = 6.283185307; +static float PI = 3.141592654f; +static float TWOPI = 6.283185307f; #define NOMASK 0 #define MASK 1 @@ -35,7 +35,7 @@ typedef struct } params_t; //PIXELM information -struct pixelm +struct PIXELM { int increment; //No. of 2*pi to add to the pixel to unwrap it int number_of_pixels_in_group;//No. of pixel in the pixel group @@ -45,16 +45,16 @@ struct pixelm unsigned char extended_mask; //0 pixel is masked. NOMASK pixel is not masked int group; //group No. int new_group; - struct pixelm *head; //pointer to the first pixel in the group in the linked list - struct pixelm *last; //pointer to the last pixel in the group - struct pixelm *next; //pointer to the next pixel in the group + struct PIXELM *head; //pointer to the first pixel in the group in the linked list + struct PIXELM *last; //pointer to the last pixel in the group + struct PIXELM *next; //pointer to the next pixel in the group }; -typedef struct pixelm PIXELM; +typedef struct PIXELM PIXELM; //the EDGE is the line that connects two pixels. //if we have S pixels, then we have S horizontal edges and S vertical edges -struct edge +struct EDGE { float reliab; //reliabilty of the edge and it depends on the two pixels PIXELM *pointer_1; //pointer to the first pixel @@ -63,7 +63,7 @@ struct edge //unwrap it with respect to the second }; -typedef struct edge EDGE; +typedef struct EDGE EDGE; //---------------start quicker_sort algorithm -------------------------------- #define swap(x,y) {EDGE t; t=x; x=y; y=t;} @@ -155,7 +155,7 @@ void initialisePIXELs(float *wrapped_image, unsigned char *input_mask, unsigned pixel_pointer->increment = 0; pixel_pointer->number_of_pixels_in_group = 1; pixel_pointer->value = *wrapped_image_pointer; - pixel_pointer->reliability = 9999999 + rand(); + pixel_pointer->reliability = 9999999.f + rand(); pixel_pointer->input_mask = *input_mask_pointer; pixel_pointer->extended_mask = *extended_mask_pointer; pixel_pointer->head = pixel_pointer; @@ -631,8 +631,8 @@ void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int i PIXELM *pointer_pixel = pixel; unsigned char *IMP = input_mask; //input mask pointer - float min=99999999.; - int i, j; + float min=99999999.f; + int i; int image_size = image_width * image_height; //find the minimum of the unwrapped phase @@ -686,12 +686,14 @@ unwrap2D(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, { params_t params = {TWOPI, wrap_around_x, wrap_around_y, 0}; unsigned char *extended_mask; + PIXELM *pixel; + EDGE *edge; int image_size = image_height * image_width; int No_of_Edges_initially = 2 * image_width * image_height; extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); - PIXELM *pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); - EDGE *edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE));; + pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); + edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE)); extend_mask(input_mask, extended_mask, image_width, image_height, ¶ms); initialisePIXELs(wrapped_image, input_mask, extended_mask, pixel, image_width, image_height); diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx old mode 100644 new mode 100755 index c4ca7f31..9bd901d5 --- a/unwrap2D/unwrap2D.pyx +++ b/unwrap2D/unwrap2D.pyx @@ -8,8 +8,6 @@ def _unwrap2D(float[:,::1] array, unsigned char[:,::1] mask, float[:,::1] unwrapped_array, wrap_around_x, wrap_around_y): - cdef int h = array.shape[0] - cdef int w = array.shape[1] unwrap2D(&array[0,0], &unwrapped_array[0,0], &mask[0,0], From c88bbf989178456293f9d78f0bd8aea24417e4ae Mon Sep 17 00:00:00 2001 From: cgohlke Date: Mon, 14 May 2012 17:05:14 -0700 Subject: [PATCH 17/84] unwrap: Fix crash on Windows --- unwrap2D/unwrap2D.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unwrap2D/unwrap2D.pyx b/unwrap2D/unwrap2D.pyx index 9bd901d5..dab52167 100755 --- a/unwrap2D/unwrap2D.pyx +++ b/unwrap2D/unwrap2D.pyx @@ -1,4 +1,4 @@ -cdef extern unwrap2D(float* wrapped_image, +cdef extern void unwrap2D(float* wrapped_image, float* unwrapped_image, unsigned char* input_mask, int image_width, int image_height, From 0231f72c96687cf62f5deb066a0fe7fbf4c6f8e5 Mon Sep 17 00:00:00 2001 From: cgohlke Date: Mon, 14 May 2012 17:05:45 -0700 Subject: [PATCH 18/84] unwrap: Fix crash on Windows --- unwrap2D/unwrap3D.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unwrap2D/unwrap3D.pyx b/unwrap2D/unwrap3D.pyx index 7a0aee9b..aa18b377 100644 --- a/unwrap2D/unwrap3D.pyx +++ b/unwrap2D/unwrap3D.pyx @@ -1,4 +1,4 @@ -cdef extern unwrap3D(float* wrapped_volume, +cdef extern void unwrap3D(float* wrapped_volume, float* unwrapped_volume, unsigned char* input_mask, int image_width, int image_height, int volume_depth, From 22f23c22fdf52845c7145b2afa6e855464b75df3 Mon Sep 17 00:00:00 2001 From: cgohlke Date: Mon, 14 May 2012 17:06:18 -0700 Subject: [PATCH 19/84] unwrap: Fix crash on Windows --- unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c | 1 + 1 file changed, 1 insertion(+) diff --git a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c index e0e4cb94..08f51aa0 100755 --- a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c @@ -1011,6 +1011,7 @@ void returnVolume(VOXELM *voxel, float *unwrappedVolume, int volume_width, int } //the main function of the unwrapper +void unwrap3D(float* wrapped_volume, float* unwrapped_volume, unsigned char* input_mask, int volume_width, int volume_height, int volume_depth, int wrap_around_x, int wrap_around_y, int wrap_around_z) From 73b03953a8b36e1a4c00813fc3460d989dc38af9 Mon Sep 17 00:00:00 2001 From: cgohlke Date: Mon, 14 May 2012 17:06:48 -0700 Subject: [PATCH 20/84] unwrap: Fix crash on Windows --- .../Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index 3017c529..a9bae512 100755 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -1,9 +1,9 @@ // 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer -//This program was written by Munther Gdeisat and Miguel Arevallilo Herra´ez to program the two-dimensional unwrapper +//This program was written by Munther Gdeisat and Miguel Arevallilo Herraďż˝ez to program the two-dimensional unwrapper //entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by //reliability following a noncontinuous path" -//by Miguel Arevallilo Herra´ez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat +//by Miguel Arevallilo Herraďż˝ez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat //published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. //This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. //Date 26th August 2007 @@ -680,6 +680,7 @@ void returnImage(PIXELM *pixel, float *unwrapped_image, int image_width, int im } //the main function of the unwrapper +void unwrap2D(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, int image_width, int image_height, int wrap_around_x, int wrap_around_y) From b614206a8049ca5f6b714fcefcce68f44b3b4dd2 Mon Sep 17 00:00:00 2001 From: cgohlke Date: Mon, 14 May 2012 17:12:29 -0700 Subject: [PATCH 21/84] unwrap: Fix unicode --- .../Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index a9bae512..854fcffd 100755 --- a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -1,9 +1,9 @@ // 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer -//This program was written by Munther Gdeisat and Miguel Arevallilo Herraďż˝ez to program the two-dimensional unwrapper +//This program was written by Munther Gdeisat and Miguel Arevallilo Herraez to program the two-dimensional unwrapper //entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by //reliability following a noncontinuous path" -//by Miguel Arevallilo Herraďż˝ez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat +//by Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat //published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. //This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. //Date 26th August 2007 From 6ba69a3167c67d93c7a32968858e3f06654b2eb3 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Fri, 18 May 2012 22:44:55 +0200 Subject: [PATCH 22/84] unwrap: added numpy test cases --- unwrap2D/test_unwrap.py | 189 ++++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 87 deletions(-) diff --git a/unwrap2D/test_unwrap.py b/unwrap2D/test_unwrap.py index eb2c3ee1..f371494f 100644 --- a/unwrap2D/test_unwrap.py +++ b/unwrap2D/test_unwrap.py @@ -1,107 +1,122 @@ -from numpy.testing import * +from numpy.testing import run_module_suite, TestCase, assert_array_almost_equal from unwrap import unwrap - import numpy as np -def test_unwrap2D(): - nx, ny = 16, 32 - x = np.arange(nx) - y = np.arange(ny) - x.shape = (-1,1) - y.shape = (1,-1) +class test_unwrap(TestCase): - z = np.exp(1j*x*0.2*np.pi) * np.exp(1j*y*0.1*np.pi) - phi_w = np.angle(z) - phi = unwrap(phi_w, - wrap_around_axis_0 = False) + def test_unwrap2D(self): + x, y = np.ogrid[:8, :16] + phi = 2*np.pi*(x*0.2 + y*0.1) + phi_wrapped = np.angle(np.exp(1j*phi)) + phi_unwrapped = unwrap(phi_wrapped) - mask = 0*np.ones((nx, ny), dtype = np.uint8) - mask[4:16, 4:16] = 1 - phi_w_ma = np.ma.array(phi_w, dtype = np.float32, mask = mask) - phi_ma = unwrap(phi_w_ma) + s = np.round(phi_unwrapped[0,0]/(2*np.pi)) + assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) - return (phi/(np.pi*2), - phi_w/(np.pi*2), phi/(np.pi*2), - phi_w_ma/(np.pi*2), phi_ma/(np.pi*2),) + def test_unwrap2D_masked(self): + x, y = np.ogrid[:8, :16] + phi = 2*np.pi*(x*0.2 + y*0.1) + + mask = np.zeros_like(phi, dtype = np.uint8) + mask[4:6, 4:8] = 1 + + phi_wrapped = np.angle(np.exp(1j*phi)) + phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) + phi_unwrapped_masked = unwrap(phi_wrapped_masked) + + s = np.round(phi_unwrapped_masked[0,0]/(2*np.pi)) + assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) + + def test_unwrap3D(self): + x, y, z = np.ogrid[:8, :12, :4] + phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) + phi_wrapped = np.angle(np.exp(1j*phi)) + phi_unwrapped = unwrap(phi_wrapped) + + s = np.round(phi_unwrapped[0,0]/(2*np.pi)) + assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) + + def test_unwrap3D_masked(self): + x, y, z = np.ogrid[:8, :12, :4] + phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) + phi_wrapped = np.angle(np.exp(1j*phi)) + mask = np.zeros_like(phi, dtype = np.uint8) + mask[4:6, 4:6, 1:3] = 1 + phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) + phi_unwrapped_masked = unwrap(phi_wrapped_masked) + + s = np.round(phi_unwrapped_masked[0,0,0]/(2*np.pi)) + assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) + +def unwrap_plots(): -def test_unwrap3D(): - x, y, z = np.ogrid[:8, :12, :4] + x, y = np.ogrid[:32, :32] + phi = 2*np.pi*(x*0.2 + y*0.1) - phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) + #phi = 1*np.arctan2(x-14.3, y-6.3) - 2*np.arctan2(x-18.3, y-22.1) + + phi[8,8] = np.NaN + phi_wrapped = np.angle(np.exp(1j*phi)) - phi_unwrapped = unwrap(phi_wrapped) + phi_unwrapped = unwrap(phi_wrapped, + #wrap_around_axis_0 = True, + #wrap_around_axis_1 = True, + ) mask = np.zeros_like(phi, dtype = np.uint8) - mask[4:6, 4:6, 1:3] = 1 + #mask[10:22, 4:10] = 1 phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) phi_unwrapped_masked = unwrap(phi_wrapped_masked) - - s = np.round(phi_unwrapped[0,0,0]/(2*np.pi)) - assert_array_almost_equal(phi/(2*np.pi), phi_unwrapped/(2*np.pi) - s, decimal = 5) - assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked, decimal = 5) - - return (phi/(np.pi*2), - phi_wrapped/(np.pi*2), phi_unwrapped/(np.pi*2), - phi_wrapped_masked/(np.pi*2), phi_unwrapped_masked/(np.pi*2),) - - - -# class test_unwrap(TestCase): -# def test_simple2d(self, level=1): -# grid = outer(ones(64), arange(-32,32)) + \ -# 1.j * outer(arange(-32,32), ones(64)) -# pgrid = abs(grid) -# wr_grid = normalize_angle(pgrid) -# uw_grid = unwrap2D(wr_grid) -# uw_grid += (pgrid[32,32] - uw_grid[32,32]) - -# assert_array_almost_equal(pgrid, uw_grid, decimal=5) - -# def test_simple3d(self): -# grid = indices((64,64,64)) -# grid[0] -= 32 -# grid[1] -= 32 -# grid[2] -= 32 -# # get distance of each point in the grid from 0 -# grid = power(power(grid, 2.0).sum(axis=0), 0.5) -# wr_grid = normalize_angle(grid) -# uw_grid = unwrap3D(wr_grid) -# uw_grid += (grid[32,32,32] - uw_grid[32,32,32]) -# assert_array_almost_equal(grid, uw_grid, decimal=5) - -if __name__=="__main__": - #NumpyTest().run() import matplotlib.pyplot as plt - - p0,p1,p2,p3,p4 = test_unwrap2D() plt.figure(1) plt.clf() - plt.subplot(322) - plt.imshow(p0,interpolation = 'nearest') - plt.subplot(323) - plt.imshow(p1,interpolation = 'nearest') - plt.subplot(324) - plt.imshow(p2, interpolation = 'nearest') - plt.subplot(325) - plt.imshow(p3, interpolation = 'nearest') - plt.subplot(326) - plt.imshow(p4, interpolation = 'nearest') - plt.draw() + plt.gray() + plt.subplot(221) + plt.imshow(phi, interpolation = 'nearest') + plt.subplot(222) + plt.imshow(phi_wrapped, interpolation = 'nearest') + plt.subplot(223) + plt.imshow(phi_unwrapped, interpolation = 'nearest') + plt.subplot(224) + plt.imshow(phi_unwrapped_masked, interpolation = 'nearest') - - p0,p1,p2,p3,p4 = test_unwrap3D() - plt.figure(2) - plt.clf() - plt.subplot(322) - plt.imshow(p0[:,:,0],interpolation = 'nearest') - plt.subplot(323) - plt.imshow(p1[:,:,0],interpolation = 'nearest') - plt.subplot(324) - plt.imshow(p2[:,:,0], interpolation = 'nearest') - plt.subplot(325) - plt.imshow(p3[:,:,0], interpolation = 'nearest') - plt.subplot(326) - plt.imshow(p4[:,:,0], interpolation = 'nearest') plt.draw() plt.show() + +if __name__=="__main__": + run_module_suite() + + unwrap_plots() + + # p0,p1,p2,p3,p4 = test_unwrap2D() + # plt.figure(1) + # plt.clf() + # plt.subplot(322) + # plt.imshow(p0,interpolation = 'nearest') + # plt.subplot(323) + # plt.imshow(p1,interpolation = 'nearest') + # plt.subplot(324) + # plt.imshow(p2, interpolation = 'nearest') + # plt.subplot(325) + # plt.imshow(p3, interpolation = 'nearest') + # plt.subplot(326) + # plt.imshow(p4, interpolation = 'nearest') + # plt.draw() + + + # p0,p1,p2,p3,p4 = test_unwrap3D() + # plt.figure(2) + # plt.clf() + # plt.subplot(322) + # plt.imshow(p0[:,:,0],interpolation = 'nearest') + # plt.subplot(323) + # plt.imshow(p1[:,:,0],interpolation = 'nearest') + # plt.subplot(324) + # plt.imshow(p2[:,:,0], interpolation = 'nearest') + # plt.subplot(325) + # plt.imshow(p3[:,:,0], interpolation = 'nearest') + # plt.subplot(326) + # plt.imshow(p4[:,:,0], interpolation = 'nearest') + # plt.draw() + # plt.show() From aef6d7dc76e4f50069a15c12850120bad593b5f1 Mon Sep 17 00:00:00 2001 From: Gregor Thalhammer Date: Mon, 16 Jul 2012 15:03:24 +0200 Subject: [PATCH 23/84] unwrap: add unwrap.py to python modules in setup.py --- unwrap2D/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/unwrap2D/setup.py b/unwrap2D/setup.py index cc780a48..848d43b5 100644 --- a/unwrap2D/setup.py +++ b/unwrap2D/setup.py @@ -28,4 +28,5 @@ setup( # ), cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules, + py_modules = ['unwrap',] ) From 5692989a11e777ccacdd35353d55e154ba394dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Sat, 6 Jul 2013 22:21:44 +0200 Subject: [PATCH 24/84] unwrap: Move files to skimage directory tree. --- .../Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c | 0 .../Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c | 0 {unwrap2D => skimage/exposure/tests}/test_unwrap.py | 0 {unwrap2D => skimage/exposure}/unwrap.py | 0 {unwrap2D => skimage/exposure}/unwrap2D.pyx | 0 {unwrap2D => skimage/exposure}/unwrap3D.pyx | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename {unwrap2D => skimage/exposure}/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c (100%) rename {unwrap2D => skimage/exposure}/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c (100%) rename {unwrap2D => skimage/exposure/tests}/test_unwrap.py (100%) rename {unwrap2D => skimage/exposure}/unwrap.py (100%) rename {unwrap2D => skimage/exposure}/unwrap2D.pyx (100%) rename {unwrap2D => skimage/exposure}/unwrap3D.pyx (100%) diff --git a/unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c b/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c similarity index 100% rename from unwrap2D/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c rename to skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c diff --git a/unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c similarity index 100% rename from unwrap2D/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c rename to skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c diff --git a/unwrap2D/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py similarity index 100% rename from unwrap2D/test_unwrap.py rename to skimage/exposure/tests/test_unwrap.py diff --git a/unwrap2D/unwrap.py b/skimage/exposure/unwrap.py similarity index 100% rename from unwrap2D/unwrap.py rename to skimage/exposure/unwrap.py diff --git a/unwrap2D/unwrap2D.pyx b/skimage/exposure/unwrap2D.pyx similarity index 100% rename from unwrap2D/unwrap2D.pyx rename to skimage/exposure/unwrap2D.pyx diff --git a/unwrap2D/unwrap3D.pyx b/skimage/exposure/unwrap3D.pyx similarity index 100% rename from unwrap2D/unwrap3D.pyx rename to skimage/exposure/unwrap3D.pyx From 4aa1bfb0ba172944db9fc8e60059ffa97016330a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Sat, 6 Jul 2013 22:22:15 +0200 Subject: [PATCH 25/84] unwrap: Delete old setup script. --- unwrap2D/setup.py | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 unwrap2D/setup.py diff --git a/unwrap2D/setup.py b/unwrap2D/setup.py deleted file mode 100644 index 848d43b5..00000000 --- a/unwrap2D/setup.py +++ /dev/null @@ -1,32 +0,0 @@ -from distutils.core import setup -from distutils.extension import Extension -from Cython.Distutils import build_ext -#from Cython.Build import cythonize -import numpy as np - -ext_modules = [ - Extension('unwrap2D', - ['unwrap2D.pyx', - 'Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c', - ], - include_dirs = [np.get_include(),], - ), - Extension('unwrap3D', - ['unwrap3D.pyx', - 'Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c', - ], - include_dirs = [np.get_include(),], - ), - ] - -import numpy as np - -setup( - name = 'unwrap', - #ext_modules = cythonize(['cytransient.pyx',], - # include_path = [np.get_include(),], - # ), - cmdclass = {'build_ext': build_ext}, - ext_modules = ext_modules, - py_modules = ['unwrap',] - ) From 4c84106b2689906a4df19948a1eea2b048f11612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Sat, 6 Jul 2013 22:23:25 +0200 Subject: [PATCH 26/84] unwrap: Remove executable bit. --- .../Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c | 0 .../Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c | 0 skimage/exposure/unwrap2D.pyx | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c mode change 100755 => 100644 skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c mode change 100755 => 100644 skimage/exposure/unwrap2D.pyx diff --git a/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c b/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c old mode 100755 new mode 100644 diff --git a/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c old mode 100755 new mode 100644 diff --git a/skimage/exposure/unwrap2D.pyx b/skimage/exposure/unwrap2D.pyx old mode 100755 new mode 100644 From 3bd60446a2e36a8dba4431af9fd2b6c319e4d021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 12:21:42 +0200 Subject: [PATCH 27/84] unwrap: Rename cython files to skimage conventions. --- skimage/exposure/{unwrap2D.pyx => _unwrap_2d.pyx} | 0 skimage/exposure/{unwrap3D.pyx => _unwrap_3d.pyx} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename skimage/exposure/{unwrap2D.pyx => _unwrap_2d.pyx} (100%) rename skimage/exposure/{unwrap3D.pyx => _unwrap_3d.pyx} (100%) diff --git a/skimage/exposure/unwrap2D.pyx b/skimage/exposure/_unwrap_2d.pyx similarity index 100% rename from skimage/exposure/unwrap2D.pyx rename to skimage/exposure/_unwrap_2d.pyx diff --git a/skimage/exposure/unwrap3D.pyx b/skimage/exposure/_unwrap_3d.pyx similarity index 100% rename from skimage/exposure/unwrap3D.pyx rename to skimage/exposure/_unwrap_3d.pyx From 011ea024c97bf58d75e06aa6e3c3747f4e4261f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 12:23:12 +0200 Subject: [PATCH 28/84] unwrap: Add setup script to build extensions. --- skimage/exposure/setup.py | 41 +++++++++++++++++++++++++++++++++++++++ skimage/setup.py | 1 + 2 files changed, 42 insertions(+) create mode 100644 skimage/exposure/setup.py diff --git a/skimage/exposure/setup.py b/skimage/exposure/setup.py new file mode 100644 index 00000000..ed1515fe --- /dev/null +++ b/skimage/exposure/setup.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +import os + +from skimage._build import cython + +base_path = os.path.abspath(os.path.dirname(__file__)) + + +def configuration(parent_package='', top_path=None): + from numpy.distutils.misc_util import Configuration, get_numpy_include_dirs + + config = Configuration('exposure', parent_package, top_path) + config.add_data_dir('tests') + + cython(['_unwrap_2d.pyx'], working_path=base_path) + cython(['_unwrap_3d.pyx'], working_path=base_path) + + unwrap_sources_2d = ['_unwrap_2d.c', + 'Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c'] + config.add_extension('_unwrap_2d', sources=unwrap_sources_2d, + extra_compile_args=['-g'], + include_dirs=[get_numpy_include_dirs()]) + unwrap_sources_3d = ['_unwrap_3d.c', + 'Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c'] + config.add_extension('_unwrap_3d', sources=unwrap_sources_3d, + extra_compile_args=['-g'], + include_dirs=[get_numpy_include_dirs()]) + + return config + +if __name__ == '__main__': + from numpy.distutils.core import setup + setup(maintainer='scikit-image Developers', + author='scikit-image Developers', + maintainer_email='scikit-image@googlegroups.com', + description='Exposure corrections', + url='https://github.com/scikit-image/scikit-image', + license='SciPy License (BSD Style)', + **(configuration(top_path='').todict()) + ) diff --git a/skimage/setup.py b/skimage/setup.py index 1082ba07..14f66897 100644 --- a/skimage/setup.py +++ b/skimage/setup.py @@ -10,6 +10,7 @@ def configuration(parent_package='', top_path=None): config.add_subpackage('color') config.add_subpackage('data') config.add_subpackage('draw') + config.add_subpackage('exposure') config.add_subpackage('feature') config.add_subpackage('filter') config.add_subpackage('graph') From 0df05f6048ab4a411f807713a1ee166cfead56e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 12:26:47 +0200 Subject: [PATCH 29/84] unwrap: Use new imports in python module. --- skimage/exposure/unwrap.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index a4fb7d2c..0c76ea94 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -12,14 +12,14 @@ def unwrap(wrapped_array, wrapped_array_masked = np.ma.asarray(wrapped_array) unwrapped_array = np.empty_like(wrapped_array_masked.data) if wrapped_array.ndim == 2: - import unwrap2D - unwrap2D._unwrap2D(wrapped_array_masked.data, + import _unwrap_2d + _unwrap_2d._unwrap2D(wrapped_array_masked.data, np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), unwrapped_array, bool(wrap_around_axis_0), bool(wrap_around_axis_1)) elif wrapped_array.ndim == 3: - import unwrap3D - unwrap3D._unwrap3D(wrapped_array_masked.data, + import _unwrap_3d + _unwrap_3d._unwrap3D(wrapped_array_masked.data, np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), unwrapped_array, bool(wrap_around_axis_0), bool(wrap_around_axis_1), bool(wrap_around_axis_2)) From 05419e49c438c3f867c1ab4bd37021755ec09332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Sat, 6 Jul 2013 23:31:10 +0200 Subject: [PATCH 30/84] Make unwrap visible in the exposure package. --- skimage/exposure/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/skimage/exposure/__init__.py b/skimage/exposure/__init__.py index b873c339..390d042b 100644 --- a/skimage/exposure/__init__.py +++ b/skimage/exposure/__init__.py @@ -3,6 +3,7 @@ from .exposure import histogram, equalize, equalize_hist, \ adjust_gamma, adjust_sigmoid, adjust_log from ._adapthist import equalize_adapthist +from .unwrap import unwrap __all__ = ['histogram', 'equalize', @@ -12,4 +13,5 @@ __all__ = ['histogram', 'cumulative_distribution', 'adjust_gamma', 'adjust_sigmoid', - 'adjust_log'] + 'adjust_log', + 'unwrap'] From e780bd7a5ac7b958994963cd396f69e0dc322e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Sat, 6 Jul 2013 23:32:02 +0200 Subject: [PATCH 31/84] unwrap: refactor tests. Update imports to skimage Use simple test functions, do not wrap in a class Whitespace fixes --- skimage/exposure/tests/test_unwrap.py | 85 +++++++++++++-------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index f371494f..5627bd79 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -1,64 +1,63 @@ -from numpy.testing import run_module_suite, TestCase, assert_array_almost_equal -from unwrap import unwrap import numpy as np +from numpy.testing import run_module_suite, TestCase, assert_array_almost_equal -class test_unwrap(TestCase): +from skimage.exposure import unwrap - def test_unwrap2D(self): - x, y = np.ogrid[:8, :16] - phi = 2*np.pi*(x*0.2 + y*0.1) - phi_wrapped = np.angle(np.exp(1j*phi)) - phi_unwrapped = unwrap(phi_wrapped) +def test_unwrap2D(): + x, y = np.ogrid[:8, :16] + phi = 2*np.pi*(x*0.2 + y*0.1) + phi_wrapped = np.angle(np.exp(1j*phi)) + phi_unwrapped = unwrap(phi_wrapped) - s = np.round(phi_unwrapped[0,0]/(2*np.pi)) - assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) + s = np.round(phi_unwrapped[0,0]/(2*np.pi)) + assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) - def test_unwrap2D_masked(self): - x, y = np.ogrid[:8, :16] - phi = 2*np.pi*(x*0.2 + y*0.1) +def test_unwrap2D_masked(): + x, y = np.ogrid[:8, :16] + phi = 2*np.pi*(x*0.2 + y*0.1) - mask = np.zeros_like(phi, dtype = np.uint8) - mask[4:6, 4:8] = 1 + mask = np.zeros_like(phi, dtype = np.uint8) + mask[4:6, 4:8] = 1 - phi_wrapped = np.angle(np.exp(1j*phi)) - phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) - phi_unwrapped_masked = unwrap(phi_wrapped_masked) + phi_wrapped = np.angle(np.exp(1j*phi)) + phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) + phi_unwrapped_masked = unwrap(phi_wrapped_masked) - s = np.round(phi_unwrapped_masked[0,0]/(2*np.pi)) - assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) + s = np.round(phi_unwrapped_masked[0,0]/(2*np.pi)) + assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) - def test_unwrap3D(self): - x, y, z = np.ogrid[:8, :12, :4] - phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) - phi_wrapped = np.angle(np.exp(1j*phi)) - phi_unwrapped = unwrap(phi_wrapped) +def test_unwrap3D(): + x, y, z = np.ogrid[:8, :12, :4] + phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) + phi_wrapped = np.angle(np.exp(1j*phi)) + phi_unwrapped = unwrap(phi_wrapped) - s = np.round(phi_unwrapped[0,0]/(2*np.pi)) - assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) + s = np.round(phi_unwrapped[0,0]/(2*np.pi)) + assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) - def test_unwrap3D_masked(self): - x, y, z = np.ogrid[:8, :12, :4] - phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) - phi_wrapped = np.angle(np.exp(1j*phi)) - mask = np.zeros_like(phi, dtype = np.uint8) - mask[4:6, 4:6, 1:3] = 1 - phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) - phi_unwrapped_masked = unwrap(phi_wrapped_masked) +def test_unwrap3D_masked(): + x, y, z = np.ogrid[:8, :12, :4] + phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) + phi_wrapped = np.angle(np.exp(1j*phi)) + mask = np.zeros_like(phi, dtype = np.uint8) + mask[4:6, 4:6, 1:3] = 1 + phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) + phi_unwrapped_masked = unwrap(phi_wrapped_masked) - s = np.round(phi_unwrapped_masked[0,0,0]/(2*np.pi)) - assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) + s = np.round(phi_unwrapped_masked[0,0,0]/(2*np.pi)) + assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) def unwrap_plots(): - + x, y = np.ogrid[:32, :32] phi = 2*np.pi*(x*0.2 + y*0.1) #phi = 1*np.arctan2(x-14.3, y-6.3) - 2*np.arctan2(x-18.3, y-22.1) phi[8,8] = np.NaN - + phi_wrapped = np.angle(np.exp(1j*phi)) - phi_unwrapped = unwrap(phi_wrapped, + phi_unwrapped = unwrap(phi_wrapped, #wrap_around_axis_0 = True, #wrap_around_axis_1 = True, ) @@ -67,7 +66,7 @@ def unwrap_plots(): #mask[10:22, 4:10] = 1 phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) phi_unwrapped_masked = unwrap(phi_wrapped_masked) - + import matplotlib.pyplot as plt plt.figure(1) plt.clf() @@ -83,12 +82,12 @@ def unwrap_plots(): plt.draw() plt.show() - + if __name__=="__main__": run_module_suite() unwrap_plots() - + # p0,p1,p2,p3,p4 = test_unwrap2D() # plt.figure(1) # plt.clf() From d2fb06fa3b460f0fa76d64ed9e59bb9065cc02fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 12:29:53 +0200 Subject: [PATCH 32/84] unwrap: Whitespace fixes. --- skimage/exposure/unwrap.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 0c76ea94..eb3e442b 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -1,8 +1,9 @@ import numpy as np -def unwrap(wrapped_array, - wrap_around_axis_0 = False, - wrap_around_axis_1 = False, + +def unwrap(wrapped_array, + wrap_around_axis_0 = False, + wrap_around_axis_1 = False, wrap_around_axis_2 = False): wrapped_array = np.require(wrapped_array, np.float32, ['C']) From e72e5de06e0e6df4852a750a7a95b0e1d79edb48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 12:30:15 +0200 Subject: [PATCH 33/84] unwrap: Move imports to module level. --- skimage/exposure/unwrap.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index eb3e442b..b5f32fed 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -1,5 +1,8 @@ import numpy as np +import _unwrap_2d +import _unwrap_3d + def unwrap(wrapped_array, wrap_around_axis_0 = False, @@ -13,13 +16,11 @@ def unwrap(wrapped_array, wrapped_array_masked = np.ma.asarray(wrapped_array) unwrapped_array = np.empty_like(wrapped_array_masked.data) if wrapped_array.ndim == 2: - import _unwrap_2d _unwrap_2d._unwrap2D(wrapped_array_masked.data, np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), unwrapped_array, bool(wrap_around_axis_0), bool(wrap_around_axis_1)) elif wrapped_array.ndim == 3: - import _unwrap_3d _unwrap_3d._unwrap3D(wrapped_array_masked.data, np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), unwrapped_array, From f67b03643a8674845670562069adc584900fe81e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 12:35:29 +0200 Subject: [PATCH 34/84] unwrap: Fix whitespace in c code. --- ...wrapper_with_mask_and_wrap_around_option.c | 208 +++++++++--------- ...wrapper_with_mask_and_wrap_around_option.c | 126 +++++------ 2 files changed, 167 insertions(+), 167 deletions(-) diff --git a/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c b/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c index 08f51aa0..7c203465 100644 --- a/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c +++ b/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c @@ -1,17 +1,17 @@ // 3D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer //This program was written by Hussein Abdul-Rahman and Munther Gdeisat to program the three-dimensional phase unwrapper -//entitled "Fast three-dimensional phase-unwrapping algorithm based on sorting by +//entitled "Fast three-dimensional phase-unwrapping algorithm based on sorting by //reliability following a noncontinuous path" -//by Hussein Abdul-Rahman, Munther A. Gdeisat, David R. Burton, and Michael J. Lalor, -//published in the Proceedings of SPIE - +//by Hussein Abdul-Rahman, Munther A. Gdeisat, David R. Burton, and Michael J. Lalor, +//published in the Proceedings of SPIE - //The International Society for Optical Engineering, Vol. 5856, No. 1, 2005, pp. 32-40 //This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. //Date 31st August 2007 //The wrapped phase volume is assumed to be of floating point data type. The resultant unwrapped phase volume is also of floating point type. //Read the data from the file frame by frame -//The mask is of byte data type. -//When the mask is 255 this means that the voxel is valid +//The mask is of byte data type. +//When the mask is 255 this means that the voxel is valid //When the mask is 0 this means that the voxel is invalid (noisy or corrupted voxel) //This program takes into consideration the image wrap around problem encountered in MRI imaging. @@ -32,7 +32,7 @@ typedef struct int y_connectivity; int z_connectivity; int no_of_edges; -} params_t; +} params_t; //VOXELM information struct VOXELM @@ -55,7 +55,7 @@ typedef struct VOXELM VOXELM; //the EDGE is the line that connects two voxels. //if we have S voxels, then we have S horizontal edges and S vertical edges struct EDGE -{ +{ float reliab; //reliabilty of the edge and it depends on the two voxels VOXELM *pointer_1; //pointer to the first voxel VOXELM *pointer_2; //pointer to the second voxel @@ -157,14 +157,14 @@ void initialiseVOXELs(float *WrappedVolume, unsigned char *input_mask, unsigned for (j=0; j < volume_width; j++) { voxel_pointer->increment = 0; - voxel_pointer->number_of_voxels_in_group = 1; + voxel_pointer->number_of_voxels_in_group = 1; voxel_pointer->value = *wrapped_volume_pointer; voxel_pointer->reliability = 9999999.f + rand(); voxel_pointer->input_mask = *input_mask_pointer; voxel_pointer->extended_mask = *extended_mask_pointer; voxel_pointer->head = voxel_pointer; voxel_pointer->last = voxel_pointer; - voxel_pointer->next = NULL; + voxel_pointer->next = NULL; voxel_pointer->new_group = 0; voxel_pointer->group = -1; voxel_pointer++; @@ -190,7 +190,7 @@ float wrap(float voxel_value) // voxelL_value is the left voxel, voxelR_value is the right voxel int find_wrap(float voxelL_value, float voxelR_value) { - float difference; + float difference; int wrap_value; difference = voxelL_value - voxelR_value; @@ -199,14 +199,14 @@ int find_wrap(float voxelL_value, float voxelR_value) else wrap_value = 0; return wrap_value; -} +} void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int volume_width, int volume_height, int volume_depth, params_t *params) { int n, i, j; int vw = volume_width, vh = volume_height, vd = volume_depth; int fs = volume_width * volume_height; //frame size - int frame_size = volume_width * volume_height; + int frame_size = volume_width * volume_height; int volume_size = volume_width * volume_height * volume_depth; //volume size int vs = volume_size; unsigned char *IMP = input_mask + frame_size + volume_width + 1; //input mask pointer @@ -219,7 +219,7 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo { for (j=1; j < volume_width - 1; j++) { - if( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + if( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && (*(IMP + vw) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && (*(IMP - vw) == NOMASK) && (*(IMP - vw - 1) == NOMASK) && (*(IMP - vw + 1) == NOMASK) && (*(IMP + fs) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && @@ -228,7 +228,7 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo (*(IMP - fs) == NOMASK) && (*(IMP - fs - 1) == NOMASK) && (*(IMP - fs + 1) == NOMASK) && (*(IMP - fs - vw) == NOMASK) && (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP - fs + vw) == NOMASK) && (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP - fs + vw + 1) == NOMASK)) - { + { *EMP = NOMASK; } ++EMP; @@ -239,7 +239,7 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo } EMP += 2 * volume_width; IMP += 2 * volume_width; - } + } if (params->x_connectivity == 1) { @@ -251,19 +251,19 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo for (i=1; i < volume_height - 1; i++) { if( (*IMP) == NOMASK && (*(IMP + vw - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && (*(IMP - fs) == NOMASK) && (*(IMP + fs) == NOMASK) && (*(IMP - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && - (*(IMP - vw + 1) == NOMASK) && (*(IMP + 2 * vw - 1) == NOMASK) && - (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP + 2 * vw - 1) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && (*(IMP - fs - vw) == NOMASK) && (*(IMP + fs + vw) == NOMASK) && - (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP + fs + 2 * vw - 1) == NOMASK) && - (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP + fs + 2 * vw - 1) == NOMASK) && + (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && (*(IMP - fs + 2 * vw - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && - (*(IMP - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && + (*(IMP - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && (*(IMP - fs + vw + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) ) - { + { *EMP = NOMASK; } EMP += vw; @@ -281,19 +281,19 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo for (i=1; i < volume_height - 1; i++) { if( (*IMP) == NOMASK && (*(IMP - vw + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && - (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && (*(IMP - fs) == NOMASK) && (*(IMP + fs) == NOMASK) && (*(IMP - vw - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP + vw - 1) == NOMASK) && (*(IMP - 2 * vw + 1) == NOMASK) && - (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP + vw - 1) == NOMASK) && (*(IMP - 2 * vw + 1) == NOMASK) && + (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && (*(IMP - fs - 2 * vw + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && - (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && - (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && + (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && (*(IMP - fs - vw) == NOMASK) && (*(IMP + fs + vw) == NOMASK) && (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP + fs - 2 * vw + 1) == NOMASK) && - (*(IMP - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && - (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) ) - { + (*(IMP - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && + (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) ) + { *EMP = NOMASK; } EMP += vw; @@ -302,31 +302,31 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo EMP += 2 * vw; IMP += 2 *vw; } - } + } if (params->y_connectivity == 1) { //extend the mask to the left side of the phase volume - IMP = input_mask + frame_size + 1; + IMP = input_mask + frame_size + 1; EMP = extended_mask + frame_size + 1; for (n=1; n < volume_depth - 1; n++) { for (j=1; j < volume_width - 1; j++) { if( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP + fs - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP + fs - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && (*(IMP - fs) == NOMASK) && (*(IMP + fs) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && - (*(IMP + fs - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && - (*(IMP - vw - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && + (*(IMP + fs - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && + (*(IMP - vw - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && (*(IMP - vw) == NOMASK) && (*(IMP + fs + vw) == NOMASK) && - (*(IMP - vw + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && - (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP + 2 * fs - vw + 1) == NOMASK) && - (*(IMP - fs + vw) == NOMASK) && (*(IMP + 2 * fs - vw) == NOMASK) && + (*(IMP - fs + vw) == NOMASK) && (*(IMP + 2 * fs - vw) == NOMASK) && (*(IMP - fs + vw + 1) == NOMASK) && (*(IMP + 2 * fs - vw - 1) == NOMASK) ) - { + { *EMP = NOMASK; } EMP++; @@ -344,19 +344,19 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo for (j=1; j < volume_width - 1; j++) { if( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && - (*(IMP - vw) == NOMASK) && (*(IMP - fs + vw) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP - fs + vw) == NOMASK) && (*(IMP - fs) == NOMASK) && (*(IMP + fs) == NOMASK) && (*(IMP - vw - 1) == NOMASK) && (*(IMP - fs + vw + 1) == NOMASK) && - (*(IMP - vw + 1) == NOMASK) && (*(IMP - fs + vw - 1) == NOMASK) && - (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP - fs + vw - 1) == NOMASK) && + (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && - (*(IMP - fs - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && - (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP - fs - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && (*(IMP - fs + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && (*(IMP - 2 * fs + vw - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && - (*(IMP - 2 * fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && - (*(IMP - 2 * fs + vw + 1) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) ) - { + (*(IMP - 2 * fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && + (*(IMP - 2 * fs + vw + 1) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) ) + { *EMP = NOMASK; } EMP++; @@ -370,26 +370,26 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo if (params->z_connectivity == 1) { //extend the mask to the bottom side of the phase volume - IMP = input_mask + volume_width + 1; + IMP = input_mask + volume_width + 1; EMP = extended_mask + volume_width + 1; for (i=1; i < volume_height - 1; ++i) { for (j=1; j < volume_width - 1; ++j) { if( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP + vw) == NOMASK) && (*(IMP + fs) == NOMASK) && (*(IMP + vs - fs) == NOMASK) && (*(IMP - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && - (*(IMP - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && - (*(IMP + vs - fs - vw - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && + (*(IMP + vs - fs - vw - 1) == NOMASK) && (*(IMP + fs + vw + 1) == NOMASK) && (*(IMP + vs - fs - vw) == NOMASK) && (*(IMP + fs + vw) == NOMASK) && - (*(IMP + vs - fs - vw + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && - (*(IMP + vs - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && + (*(IMP + vs - fs - vw + 1) == NOMASK) && (*(IMP + fs + vw - 1) == NOMASK) && + (*(IMP + vs - fs - 1) == NOMASK) && (*(IMP + fs + 1) == NOMASK) && (*(IMP + vs - fs + 1) == NOMASK) && (*(IMP + fs - 1) == NOMASK) && (*(IMP + vs - fs + vw - 1) == NOMASK) && (*(IMP + fs - vw + 1) == NOMASK) && - (*(IMP + vs - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && + (*(IMP + vs - fs + vw) == NOMASK) && (*(IMP + fs - vw) == NOMASK) && (*(IMP + vs - fs + vw + 1) == NOMASK) && (*(IMP + fs - vw - 1) == NOMASK) ) - { + { *EMP = NOMASK; } EMP++; @@ -400,26 +400,26 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo } //extend the mask to the top side of the phase volume - IMP = input_mask + volume_size - frame_size + volume_width + 1; + IMP = input_mask + volume_size - frame_size + volume_width + 1; EMP = extended_mask + volume_size - frame_size + volume_width + 1; for (i=1; i < volume_height - 1; ++i) { for (j=1; j < volume_width - 1; ++j) { if( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && - (*(IMP - vw) == NOMASK) && (*(IMP - fs + vw) == NOMASK) && + (*(IMP - vw) == NOMASK) && (*(IMP - fs + vw) == NOMASK) && (*(IMP - fs) == NOMASK) && (*(IMP - vs + fs) == NOMASK) && (*(IMP - vw - 1) == NOMASK) && (*(IMP + vw + 1) == NOMASK) && - (*(IMP - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && - (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP - vs + fs + vw + 1) == NOMASK) && + (*(IMP - vw + 1) == NOMASK) && (*(IMP + vw - 1) == NOMASK) && + (*(IMP - fs - vw - 1) == NOMASK) && (*(IMP - vs + fs + vw + 1) == NOMASK) && (*(IMP - fs - vw + 1) == NOMASK) && (*(IMP - vs + fs + vw - 1) == NOMASK) && - (*(IMP - fs - vw) == NOMASK) && (*(IMP - vs + fs + vw) == NOMASK) && - (*(IMP - fs - 1) == NOMASK) && (*(IMP - vs + fs + 1) == NOMASK) && + (*(IMP - fs - vw) == NOMASK) && (*(IMP - vs + fs + vw) == NOMASK) && + (*(IMP - fs - 1) == NOMASK) && (*(IMP - vs + fs + 1) == NOMASK) && (*(IMP - fs + 1) == NOMASK) && (*(IMP - vs + fs - 1) == NOMASK) && (*(IMP - fs + vw - 1) == NOMASK) && (*(IMP - vs + fs - vw + 1) == NOMASK) && - (*(IMP - fs + vw) == NOMASK) && (*(IMP - vs + fs - vw) == NOMASK) && - (*(IMP - fs + vw + 1) == NOMASK) && (*(IMP - vs + fs - vw - 1) == NOMASK) ) - { + (*(IMP - fs + vw) == NOMASK) && (*(IMP - vs + fs - vw) == NOMASK) && + (*(IMP - fs + vw + 1) == NOMASK) && (*(IMP - vs + fs - vw - 1) == NOMASK) ) + { *EMP = NOMASK; } EMP++; @@ -432,14 +432,14 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo } void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width, int volume_height, int volume_depth, params_t *params) -{ +{ int frame_size = volume_width * volume_height; int volume_size = volume_width * volume_height * volume_depth; VOXELM *voxel_pointer; float H, V, N, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10; float *WVP; int n, i, j; - + WVP = wrappedVolume + frame_size + volume_width + 1; voxel_pointer = voxel + frame_size + volume_width + 1; for (n=1; n < volume_depth - 1; n++) @@ -449,7 +449,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width for (j=1; j < volume_width - 1; j++) { if (voxel_pointer->extended_mask == NOMASK) - { + { H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); @@ -463,7 +463,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + D7*D7 + D8*D8 + D9*D9 + D10*D10; } voxel_pointer++; @@ -486,7 +486,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width for (i=1; i < volume_height - 1; ++i) { if (voxel_pointer->extended_mask == NOMASK) - { + { H = wrap(*(WVP + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); @@ -500,7 +500,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width D8 = wrap(*(WVP - frame_size + 2 * volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + D7*D7 + D8*D8 + D9*D9 + D10*D10; } voxel_pointer += volume_width; @@ -509,7 +509,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width voxel_pointer += 2 * volume_width; WVP += 2 * volume_width; } - + //calculating reliability for the rear side of the phase volume..... subtract volume_width WVP = wrappedVolume + frame_size + 2 * volume_width - 1; voxel_pointer = voxel + frame_size + 2 * volume_width - 1; @@ -518,7 +518,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width for (i=1; i < volume_height - 1; ++i) { if (voxel_pointer->extended_mask == NOMASK) - { + { H = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); @@ -532,7 +532,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - 2 * volume_width + 1)); D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); D10 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + D7*D7 + D8*D8 + D9*D9 + D10*D10; } voxel_pointer += volume_width; @@ -540,7 +540,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width } voxel_pointer += 2 * volume_width; WVP += 2 * volume_width; - } + } } if (params->y_connectivity == 1) @@ -553,7 +553,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width for (j=1; j < volume_width - 1; ++j) { if (voxel_pointer->extended_mask == NOMASK) - { + { H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); V = wrap(*(WVP + frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); @@ -567,7 +567,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width + 1)); D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width)); D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + 2 * frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + D7*D7 + D8*D8 + D9*D9 + D10*D10; } voxel_pointer++; @@ -575,7 +575,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width } voxel_pointer += frame_size - volume_width + 2; WVP += frame_size - volume_width + 2; - } + } //calculating reliability for the right side of the phase volume...subtract frame_size WVP = wrappedVolume + 2 * frame_size - volume_width + 1; @@ -585,7 +585,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width for (j=1; j < volume_width - 1; ++j) { if (voxel_pointer->extended_mask == NOMASK) - { + { H = wrap(*(WVP + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP - frame_size + volume_width)); N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP + frame_size)); @@ -599,7 +599,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width D8 = wrap(*(WVP - 2 * frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); D9 = wrap(*(WVP - 2 * frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); D10 = wrap(*(WVP - 2 * frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + D7*D7 + D8*D8 + D9*D9 + D10*D10; } voxel_pointer++; @@ -607,7 +607,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width } voxel_pointer += frame_size - volume_width + 2; WVP += frame_size - volume_width + 2; - } + } } if (params->z_connectivity == 1) @@ -620,7 +620,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width for (j=1; j < volume_width - 1; ++j) { if (voxel_pointer->extended_mask == NOMASK) - { + { H = wrap(*(WVP - 1) - *WVP) - wrap(*WVP - *(WVP + 1)); V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); N = wrap(*(WVP + frame_size) - *WVP) - wrap(*WVP - *(WVP + volume_size - frame_size)); @@ -634,7 +634,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width D8 = wrap(*(WVP + volume_size - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width + 1)); D9 = wrap(*(WVP + volume_size - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width)); D10 = wrap(*(WVP + volume_size - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + D7*D7 + D8*D8 + D9*D9 + D10*D10; } voxel_pointer++; @@ -642,7 +642,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width } voxel_pointer += 2; WVP += 2; - } + } //calculating reliability for the top side of the phase volume...subtract volume_size WVP = wrappedVolume + volume_size - frame_size + volume_width + 1; @@ -652,7 +652,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width for (j=1; j < volume_width - 1; ++j) { if (voxel_pointer->extended_mask == NOMASK) - { + { H = wrap(*(WVP + 1) - *WVP) - wrap(*WVP - *(WVP - 1)); V = wrap(*(WVP - volume_width) - *WVP) - wrap(*WVP - *(WVP + volume_width)); N = wrap(*(WVP - frame_size) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size)); @@ -660,13 +660,13 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width D2 = wrap(*(WVP - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP + volume_width - 1)); D3 = wrap(*(WVP - frame_size - volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width + 1)); D4 = wrap(*(WVP - frame_size - volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width - 1)); - D5 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width)); + D5 = wrap(*(WVP - frame_size - volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + volume_width)); D6 = wrap(*(WVP - frame_size - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size + 1)); D7 = wrap(*(WVP - frame_size + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - 1)); D8 = wrap(*(WVP - frame_size + volume_width - 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width + 1)); D9 = wrap(*(WVP - frame_size + volume_width) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width)); D10 = wrap(*(WVP - frame_size + volume_width + 1) - *WVP) - wrap(*WVP - *(WVP - volume_size + frame_size - volume_width - 1)); - voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + voxel_pointer->reliability = H*H + V*V + N*N + D1*D1 + D2*D2 + D3*D3 + D4*D4 + D5*D5 + D6*D6 + D7*D7 + D8*D8 + D9*D9 + D10*D10; } voxel_pointer++; @@ -674,7 +674,7 @@ void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width } voxel_pointer += 2; WVP += 2; - } + } } } @@ -688,12 +688,12 @@ void horizontalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_he EDGE *edge_pointer = edge; VOXELM *voxel_pointer = voxel; int no_of_edges = params->no_of_edges; - + for (n=0; n < volume_depth; n++) { for (i = 0; i < volume_height; i++) { - for (j = 0; j < volume_width - 1; j++) + for (j = 0; j < volume_width - 1; j++) { if (voxel_pointer->input_mask == NOMASK && (voxel_pointer + 1)->input_mask == NOMASK ) { @@ -737,7 +737,7 @@ void verticalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_heig int n, i, j; int no_of_edges = params->no_of_edges; VOXELM *voxel_pointer = voxel; - EDGE *edge_pointer = edge + no_of_edges; + EDGE *edge_pointer = edge + no_of_edges; int frame_size = volume_width * volume_height; int next_voxel = frame_size - volume_width; @@ -745,7 +745,7 @@ void verticalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_heig { for (i=0; iinput_mask == NOMASK && (voxel_pointer + volume_width)->input_mask == NOMASK ) { @@ -760,7 +760,7 @@ void verticalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_heig } } voxel_pointer += volume_width; - } + } if (params->y_connectivity == 1) { @@ -800,7 +800,7 @@ void normalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height { for (i=0; iinput_mask == NOMASK && (voxel_pointer + frame_size)->input_mask == NOMASK ) { @@ -816,7 +816,7 @@ void normalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height } } - + if (params->z_connectivity == 1) { voxel_pointer = voxel + next_voxel; @@ -840,11 +840,11 @@ void normalEDGEs(VOXELM *voxel, EDGE *edge, int volume_width, int volume_height params->no_of_edges = no_of_edges; } -//gather the voxels of the volume into groups +//gather the voxels of the volume into groups void gatherVOXELs(EDGE *edge, params_t *params) { int k; - VOXELM *VOXEL1; + VOXELM *VOXEL1; VOXELM *VOXEL2; VOXELM *group1; VOXELM *group2; @@ -862,7 +862,7 @@ void gatherVOXELs(EDGE *edge, params_t *params) if (VOXEL2->head != VOXEL1->head) { //VOXELM 2 is alone in its group - //merge this voxel with VOXELM 1 group and find the number of 2 pi to add + //merge this voxel with VOXELM 1 group and find the number of 2 pi to add //to or subtract to unwrap it if ((VOXEL2->next == NULL) && (VOXEL2->head == VOXEL2)) { @@ -874,7 +874,7 @@ void gatherVOXELs(EDGE *edge, params_t *params) } //VOXELM 1 is alone in its group - //merge this voxel with VOXELM 2 group and find the number of 2 pi to add + //merge this voxel with VOXELM 2 group and find the number of 2 pi to add //to or subtract to unwrap it else if ((VOXEL1->next == NULL) && (VOXEL1->head == VOXEL1)) { @@ -883,7 +883,7 @@ void gatherVOXELs(EDGE *edge, params_t *params) (VOXEL2->head->number_of_voxels_in_group)++; VOXEL1->head = VOXEL2->head; VOXEL1->increment = VOXEL2->increment+pointer_edge->increment; - } + } //VOXELM 1 and VOXELM 2 both have groups else @@ -909,7 +909,7 @@ void gatherVOXELs(EDGE *edge, params_t *params) group2->increment += incremento; group2 = group2->next; } - } + } //if the no. of voxels in VOXELM 2 group is larger than the no. of voxels //in VOXELM 1 group. Merge VOXELM 1 group to VOXELM 2 group @@ -938,7 +938,7 @@ void gatherVOXELs(EDGE *edge, params_t *params) } } -//unwrap the volume +//unwrap the volume void unwrapVolume(VOXELM *voxel, int volume_width, int volume_height, int volume_depth) { int i; @@ -969,7 +969,7 @@ void maskVolume(VOXELM *voxel, unsigned char *input_mask, int volume_width, int //find the minimum of the unwrapped phase for (i = 0; i < volume_size; i++) { - if ((pointer_voxel->value < min) && (*IMP == NOMASK)) + if ((pointer_voxel->value < min) && (*IMP == NOMASK)) min = pointer_voxel->value; pointer_voxel++; @@ -977,7 +977,7 @@ void maskVolume(VOXELM *voxel, unsigned char *input_mask, int volume_width, int } pointer_voxel = voxel; - IMP = input_mask; + IMP = input_mask; //set the masked voxels to minimum for (i = 0; i < volume_size; i++) @@ -1002,7 +1002,7 @@ void returnVolume(VOXELM *voxel, float *unwrappedVolume, int volume_width, int float *unwrappedVolume_pointer = unwrappedVolume; VOXELM *voxel_pointer = voxel; - for (i=0; i < volume_size; i++) + for (i=0; i < volume_size; i++) { *unwrappedVolume_pointer = voxel_pointer->value; voxel_pointer++; diff --git a/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c index 854fcffd..e6249062 100644 --- a/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c @@ -1,15 +1,15 @@ // 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer //This program was written by Munther Gdeisat and Miguel Arevallilo Herraez to program the two-dimensional unwrapper -//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by +//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by //reliability following a noncontinuous path" //by Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat //published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. //This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. //Date 26th August 2007 //The wrapped phase map is assumed to be of floating point data type. The resultant unwrapped phase map is also of floating point type. -//The mask is of byte data type. -//When the mask is 255 this means that the pixel is valid +//The mask is of byte data type. +//When the mask is 255 this means that the pixel is valid //When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) //This program takes into consideration the image wrap around problem encountered in MRI imaging. @@ -55,13 +55,13 @@ typedef struct PIXELM PIXELM; //the EDGE is the line that connects two pixels. //if we have S pixels, then we have S horizontal edges and S vertical edges struct EDGE -{ +{ float reliab; //reliabilty of the edge and it depends on the two pixels PIXELM *pointer_1; //pointer to the first pixel PIXELM *pointer_2; //pointer to the second pixel int increment; //No. of 2*pi to add to one of the pixels to //unwrap it with respect to the second -}; +}; typedef struct EDGE EDGE; @@ -147,20 +147,20 @@ void initialisePIXELs(float *wrapped_image, unsigned char *input_mask, unsigned unsigned char *input_mask_pointer = input_mask; unsigned char *extended_mask_pointer = extended_mask; int i, j; - + for (i=0; i < image_height; i++) { for (j=0; j < image_width; j++) { pixel_pointer->increment = 0; - pixel_pointer->number_of_pixels_in_group = 1; + pixel_pointer->number_of_pixels_in_group = 1; pixel_pointer->value = *wrapped_image_pointer; pixel_pointer->reliability = 9999999.f + rand(); pixel_pointer->input_mask = *input_mask_pointer; pixel_pointer->extended_mask = *extended_mask_pointer; pixel_pointer->head = pixel_pointer; pixel_pointer->last = pixel_pointer; - pixel_pointer->next = NULL; + pixel_pointer->next = NULL; pixel_pointer->new_group = 0; pixel_pointer->group = -1; pixel_pointer++; @@ -185,7 +185,7 @@ float wrap(float pixel_value) // pixelL_value is the left pixel, pixelR_value is the right pixel int find_wrap(float pixelL_value, float pixelR_value) { - float difference; + float difference; int wrap_value; difference = pixelL_value - pixelR_value; @@ -194,10 +194,10 @@ int find_wrap(float pixelL_value, float pixelR_value) else wrap_value = 0; return wrap_value; -} +} -void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, - int image_width, int image_height, +void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, + int image_width, int image_height, params_t *params) { int i,j; @@ -211,11 +211,11 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, { for (j=1; j < image_width - 1; ++j) { - if ( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && + if ( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && (*(IMP - image_width_minus_one) == NOMASK) && (*(IMP - image_width_plus_one) == NOMASK) && (*(IMP + image_width_minus_one) == NOMASK) && (*(IMP + image_width_plus_one) == NOMASK) ) - { + { *EMP = NOMASK; } ++EMP; @@ -224,7 +224,7 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, EMP += 2; IMP += 2; } - + if (params->x_connectivity == 1) { //extend the mask for the right border of the image @@ -236,7 +236,7 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && (*(IMP + image_width - 1) == NOMASK) && (*(IMP - 2 * image_width + 1) == NOMASK) ) - { + { *EMP = NOMASK; } EMP += image_width; @@ -248,11 +248,11 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, EMP = extended_mask + image_width; for (i=1; i < image_height - 1; ++i) { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && (*(IMP + image_width + 1) == NOMASK) && (*(IMP + image_width - 1) == NOMASK) && (*(IMP + 2 * image_width - 1) == NOMASK) ) - { + { *EMP = NOMASK; } EMP += image_width; @@ -267,11 +267,11 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, EMP = extended_mask + 1; for (i=1; i < image_width - 1; ++i) { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && (*(IMP + image_width) == NOMASK) && (*(IMP + image_width * (image_height - 1)) == NOMASK) && (*(IMP + image_width + 1) == NOMASK) && (*(IMP + image_width - 1) == NOMASK) && (*(IMP + image_width * (image_height - 1) - 1) == NOMASK) && (*(IMP + image_width * (image_height - 1) + 1) == NOMASK) ) - { + { *EMP = NOMASK; } EMP++; @@ -283,21 +283,21 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, EMP = extended_mask + image_width * (image_height - 1) + 1; for (i=1; i < image_width - 1; ++i) { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && (*(IMP - image_width) == NOMASK) && (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && - (*(IMP - image_width * (image_height - 1) ) == NOMASK) && - (*(IMP - image_width * (image_height - 1) - 1) == NOMASK) && + (*(IMP - image_width * (image_height - 1) ) == NOMASK) && + (*(IMP - image_width * (image_height - 1) - 1) == NOMASK) && (*(IMP - image_width * (image_height - 1) + 1) == NOMASK) ) - { + { *EMP = NOMASK; } EMP++; IMP++; } - } + } } -void calculate_reliability(float *wrappedImage, PIXELM *pixel, +void calculate_reliability(float *wrappedImage, PIXELM *pixel, int image_width, int image_height, params_t *params) { @@ -307,7 +307,7 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer float H, V, D1, D2; int i, j; - + for (i = 1; i < image_height -1; ++i) { for (j = 1; j < image_width - 1; ++j) @@ -331,8 +331,8 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, { //calculating the reliability for the left border of the image PIXELM *pixel_pointer = pixel + image_width; - float *WIP = wrappedImage + image_width; - + float *WIP = wrappedImage + image_width; + for (i = 1; i < image_height - 1; ++i) { if (pixel_pointer->extended_mask == NOMASK) @@ -349,8 +349,8 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, //calculating the reliability for the right border of the image pixel_pointer = pixel + 2 * image_width - 1; - WIP = wrappedImage + 2 * image_width - 1; - + WIP = wrappedImage + 2 * image_width - 1; + for (i = 1; i < image_height - 1; ++i) { if (pixel_pointer->extended_mask == NOMASK) @@ -370,8 +370,8 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, { //calculating the reliability for the top border of the image PIXELM *pixel_pointer = pixel + 1; - float *WIP = wrappedImage + 1; - + float *WIP = wrappedImage + 1; + for (i = 1; i < image_width - 1; ++i) { if (pixel_pointer->extended_mask == NOMASK) @@ -388,8 +388,8 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, //calculating the reliability for the bottom border of the image pixel_pointer = pixel + (image_height - 1) * image_width + 1; - WIP = wrappedImage + (image_height - 1) * image_width + 1; - + WIP = wrappedImage + (image_height - 1) * image_width + 1; + for (i = 1; i < image_width - 1; ++i) { if (pixel_pointer->extended_mask == NOMASK) @@ -407,10 +407,10 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, } //calculate the reliability of the horizontal edges of the image -//it is calculated by adding the reliability of pixel and the relibility of +//it is calculated by adding the reliability of pixel and the relibility of //its right-hand neighbour //edge is calculated between a pixel and its next neighbour -void horizontalEDGEs(PIXELM *pixel, EDGE *edge, +void horizontalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height, params_t *params) { @@ -418,10 +418,10 @@ void horizontalEDGEs(PIXELM *pixel, EDGE *edge, EDGE *edge_pointer = edge; PIXELM *pixel_pointer = pixel; int no_of_edges = params->no_of_edges; - + for (i = 0; i < image_height; i++) { - for (j = 0; j < image_width - 1; j++) + for (j = 0; j < image_width - 1; j++) { if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + 1)->input_mask == NOMASK) { @@ -458,20 +458,20 @@ void horizontalEDGEs(PIXELM *pixel, EDGE *edge, } //calculate the reliability of the vertical edges of the image -//it is calculated by adding the reliability of pixel and the relibility of +//it is calculated by adding the reliability of pixel and the relibility of //its lower neighbour in the image. -void verticalEDGEs(PIXELM *pixel, EDGE *edge, +void verticalEDGEs(PIXELM *pixel, EDGE *edge, int image_width, int image_height, params_t *params) { int i, j; int no_of_edges = params->no_of_edges; PIXELM *pixel_pointer = pixel; - EDGE *edge_pointer = edge + no_of_edges; + EDGE *edge_pointer = edge + no_of_edges; for (i=0; i < image_height - 1; i++) { - for (j=0; j < image_width; j++) + for (j=0; j < image_width; j++) { if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + image_width)->input_mask == NOMASK) { @@ -507,11 +507,11 @@ void verticalEDGEs(PIXELM *pixel, EDGE *edge, params->no_of_edges = no_of_edges; } -//gather the pixels of the image into groups +//gather the pixels of the image into groups void gatherPIXELs(EDGE *edge, params_t *params) { int k; - PIXELM *PIXEL1; + PIXELM *PIXEL1; PIXELM *PIXEL2; PIXELM *group1; PIXELM *group2; @@ -529,7 +529,7 @@ void gatherPIXELs(EDGE *edge, params_t *params) if (PIXEL2->head != PIXEL1->head) { //PIXELM 2 is alone in its group - //merge this pixel with PIXELM 1 group and find the number of 2 pi to add + //merge this pixel with PIXELM 1 group and find the number of 2 pi to add //to or subtract to unwrap it if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) { @@ -541,7 +541,7 @@ void gatherPIXELs(EDGE *edge, params_t *params) } //PIXELM 1 is alone in its group - //merge this pixel with PIXELM 2 group and find the number of 2 pi to add + //merge this pixel with PIXELM 2 group and find the number of 2 pi to add //to or subtract to unwrap it else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) { @@ -550,7 +550,7 @@ void gatherPIXELs(EDGE *edge, params_t *params) (PIXEL2->head->number_of_pixels_in_group)++; PIXEL1->head = PIXEL2->head; PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; - } + } //PIXELM 1 and PIXELM 2 both have groups else @@ -577,7 +577,7 @@ void gatherPIXELs(EDGE *edge, params_t *params) group2->increment += incremento; group2 = group2->next; } - } + } //if the no. of pixels in PIXELM 2 group is larger than the //no. of pixels in PIXELM 1 group. Merge PIXELM 1 group to @@ -607,7 +607,7 @@ void gatherPIXELs(EDGE *edge, params_t *params) } } -//unwrap the image +//unwrap the image void unwrapImage(PIXELM *pixel, int image_width, int image_height) { int i; @@ -638,7 +638,7 @@ void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int i //find the minimum of the unwrapped phase for (i = 0; i < image_size; i++) { - if ((pointer_pixel->value < min) && (*IMP == NOMASK)) + if ((pointer_pixel->value < min) && (*IMP == NOMASK)) min = pointer_pixel->value; pointer_pixel++; @@ -646,7 +646,7 @@ void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int i } pointer_pixel = pixel; - IMP = input_mask; + IMP = input_mask; //set the masked pixels to minimum for (i = 0; i < image_size; i++) @@ -670,8 +670,8 @@ void returnImage(PIXELM *pixel, float *unwrapped_image, int image_width, int im int image_size = image_width * image_height; float *unwrapped_image_pointer = unwrapped_image; PIXELM *pixel_pointer = pixel; - - for (i=0; i < image_size; i++) + + for (i=0; i < image_size; i++) { *unwrapped_image_pointer = pixel_pointer->value; pixel_pointer++; @@ -681,8 +681,8 @@ void returnImage(PIXELM *pixel, float *unwrapped_image, int image_width, int im //the main function of the unwrapper void -unwrap2D(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, - int image_width, int image_height, +unwrap2D(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, + int image_width, int image_height, int wrap_around_x, int wrap_around_y) { params_t params = {TWOPI, wrap_around_x, wrap_around_y, 0}; @@ -691,32 +691,32 @@ unwrap2D(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, EDGE *edge; int image_size = image_height * image_width; int No_of_Edges_initially = 2 * image_width * image_height; - + extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE)); - + extend_mask(input_mask, extended_mask, image_width, image_height, ¶ms); initialisePIXELs(wrapped_image, input_mask, extended_mask, pixel, image_width, image_height); calculate_reliability(wrapped_image, pixel, image_width, image_height, ¶ms); horizontalEDGEs(pixel, edge, image_width, image_height, ¶ms); verticalEDGEs(pixel, edge, image_width, image_height, ¶ms); - + //sort the EDGEs depending on their reiability. The PIXELs with higher //relibility (small value) first quicker_sort(edge, edge + params.no_of_edges - 1); - + //gather PIXELs into groups gatherPIXELs(edge, ¶ms); - + unwrapImage(pixel, image_width, image_height); maskImage(pixel, input_mask, image_width, image_height); - + //copy the image from PIXELM structure to the unwrapped phase array //passed to this function //TODO: replace by (cython?) function to directly write into numpy array ? returnImage(pixel, UnwrappedImage, image_width, image_height); - + free(edge); free(pixel); free(extended_mask); From 933e2c77f3affc4043b78f430e01c8c01c1f86c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 11:52:06 +0200 Subject: [PATCH 35/84] unwrap: Add unfinished docstrings. Conflicts: skimage/exposure/unwrap.py --- skimage/exposure/unwrap.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index b5f32fed..76dc3dbe 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -5,10 +5,21 @@ import _unwrap_3d def unwrap(wrapped_array, - wrap_around_axis_0 = False, - wrap_around_axis_1 = False, - wrap_around_axis_2 = False): + wrap_around_axis_0=False, + wrap_around_axis_1=False, + wrap_around_axis_2=False): + '''From ``image``, wrapped to lie in the interval [-pi, pi), recover the + original, unwrapped image. + Parameters + ---------- + image : 2D or 3D ndarray, optionally a masked array + wrap_around : bool or sequence of bool + + Returns + ------- + image_unwrapped : array_like + ''' wrapped_array = np.require(wrapped_array, np.float32, ['C']) if wrapped_array.ndim not in [2,3]: raise ValueError('input array needs to have 2 or 3 dimensions') From b29dd83eea3c6dc04ee0ff32ee712c8a3cea5cc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 11:59:22 +0200 Subject: [PATCH 36/84] unwrap: Refactor wrap_around argument. --- skimage/exposure/unwrap.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 76dc3dbe..ea674af3 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -4,10 +4,7 @@ import _unwrap_2d import _unwrap_3d -def unwrap(wrapped_array, - wrap_around_axis_0=False, - wrap_around_axis_1=False, - wrap_around_axis_2=False): +def unwrap(wrapped_array, wrap_around=False): '''From ``image``, wrapped to lie in the interval [-pi, pi), recover the original, unwrapped image. @@ -21,8 +18,19 @@ def unwrap(wrapped_array, image_unwrapped : array_like ''' wrapped_array = np.require(wrapped_array, np.float32, ['C']) - if wrapped_array.ndim not in [2,3]: - raise ValueError('input array needs to have 2 or 3 dimensions') + if wrapped_array.ndim not in (2, 3): + raise ValueError('image must be 2 or 3 dimensional') + if isinstance(wrap_around, bool): + wrap_around = [wrap_around] * wrapped_array.ndim + elif (hasattr(wrap_around, '__getitem__') + and not isinstance(wrap_around, basestring)): + if not len(wrap_around) == wrapped_array.ndim: + raise ValueError('Length of wrap_around must equal the ' + 'dimensionality of image') + wrap_around = [bool(wa) for wa in wrap_around] + else: + raise ValueError('wrap_around must be a bool or a sequence with ' + 'length equal to the dimensionality of image') wrapped_array_masked = np.ma.asarray(wrapped_array) unwrapped_array = np.empty_like(wrapped_array_masked.data) @@ -30,12 +38,12 @@ def unwrap(wrapped_array, _unwrap_2d._unwrap2D(wrapped_array_masked.data, np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), unwrapped_array, - bool(wrap_around_axis_0), bool(wrap_around_axis_1)) + wrap_around[0], wrap_around[1]) elif wrapped_array.ndim == 3: _unwrap_3d._unwrap3D(wrapped_array_masked.data, np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), unwrapped_array, - bool(wrap_around_axis_0), bool(wrap_around_axis_1), bool(wrap_around_axis_2)) + wrap_around[0], wrap_around[1], wrap_around[2]) if np.ma.isMaskedArray(wrapped_array): return np.ma.array(unwrapped_array, mask = wrapped_array_masked.mask) From 26138fbeb61965da2d332eeed33c768f65d67692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 12:43:28 +0200 Subject: [PATCH 37/84] unwrap: Refactor to skimage-style variable names. --- skimage/exposure/unwrap.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index ea674af3..8a0b8970 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -4,7 +4,7 @@ import _unwrap_2d import _unwrap_3d -def unwrap(wrapped_array, wrap_around=False): +def unwrap(image, wrap_around=False): '''From ``image``, wrapped to lie in the interval [-pi, pi), recover the original, unwrapped image. @@ -17,14 +17,14 @@ def unwrap(wrapped_array, wrap_around=False): ------- image_unwrapped : array_like ''' - wrapped_array = np.require(wrapped_array, np.float32, ['C']) - if wrapped_array.ndim not in (2, 3): + image = np.require(image, np.float32, ['C']) + if image.ndim not in (2, 3): raise ValueError('image must be 2 or 3 dimensional') if isinstance(wrap_around, bool): - wrap_around = [wrap_around] * wrapped_array.ndim + wrap_around = [wrap_around] * image.ndim elif (hasattr(wrap_around, '__getitem__') and not isinstance(wrap_around, basestring)): - if not len(wrap_around) == wrapped_array.ndim: + if not len(wrap_around) == image.ndim: raise ValueError('Length of wrap_around must equal the ' 'dimensionality of image') wrap_around = [bool(wa) for wa in wrap_around] @@ -32,23 +32,23 @@ def unwrap(wrapped_array, wrap_around=False): raise ValueError('wrap_around must be a bool or a sequence with ' 'length equal to the dimensionality of image') - wrapped_array_masked = np.ma.asarray(wrapped_array) - unwrapped_array = np.empty_like(wrapped_array_masked.data) - if wrapped_array.ndim == 2: - _unwrap_2d._unwrap2D(wrapped_array_masked.data, - np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), - unwrapped_array, + image_masked = np.ma.asarray(image) + image_unwrapped = np.empty_like(image_masked.data) + if image.ndim == 2: + _unwrap_2d._unwrap2D(image_masked.data, + np.ma.getmaskarray(image_masked).astype(np.uint8), + image_unwrapped, wrap_around[0], wrap_around[1]) - elif wrapped_array.ndim == 3: - _unwrap_3d._unwrap3D(wrapped_array_masked.data, - np.ma.getmaskarray(wrapped_array_masked).astype(np.uint8), - unwrapped_array, + elif image.ndim == 3: + _unwrap_3d._unwrap3D(image_masked.data, + np.ma.getmaskarray(image_masked).astype(np.uint8), + image_unwrapped, wrap_around[0], wrap_around[1], wrap_around[2]) - if np.ma.isMaskedArray(wrapped_array): - return np.ma.array(unwrapped_array, mask = wrapped_array_masked.mask) + if np.ma.isMaskedArray(image): + return np.ma.array(image_unwrapped, mask = image_masked.mask) else: - return unwrapped_array + return image_unwrapped #TODO: set_fill to minimum value #TODO: check for empty mask, not a single contiguous pixel From 37f36cd98b51a9b7776660e263f768643c1bae43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 12:55:02 +0200 Subject: [PATCH 38/84] unwrap: Add docstring. --- skimage/exposure/unwrap.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 8a0b8970..d208e0ce 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -10,12 +10,29 @@ def unwrap(image, wrap_around=False): Parameters ---------- - image : 2D or 3D ndarray, optionally a masked array + image : 2D or 3D ndarray of floats, optionally a masked array + The values should be in the range ``[-pi, pi)``. If a masked array is + provided, the masked entries will not be changed, and their values + will not be used to guide the unwrapping of neighboring, unmasked + values. wrap_around : bool or sequence of bool + When an element of the sequence is ``True``, the unwrapping process + will regard the edges along the corresponding axis of the image to be + connected and use this connectivity to guide the phase unwrapping + process. If only a single boolean is given, it will apply to all axes. Returns ------- - image_unwrapped : array_like + image_unwrapped : array_like, float32 + Unwrapped image of the same shape as the input. If the input ``image`` + was a masked array, the mask will be preserved. + + References + ---------- + - Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, + and Munther A. Gdeisat, "Fast two-dimensional phase-unwrapping + algorithm based on sorting by reliability following a noncontinuous + path", Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002 ''' image = np.require(image, np.float32, ['C']) if image.ndim not in (2, 3): From 5bfbd7cdadae691176bab93b754b51b3b185ddd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 13:44:31 +0200 Subject: [PATCH 39/84] Add example for phase unwrapping. --- doc/examples/plot_phase_unwrap.py | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 doc/examples/plot_phase_unwrap.py diff --git a/doc/examples/plot_phase_unwrap.py b/doc/examples/plot_phase_unwrap.py new file mode 100644 index 00000000..258ed21e --- /dev/null +++ b/doc/examples/plot_phase_unwrap.py @@ -0,0 +1,64 @@ +""" +================ +Phase Unwrapping +================ + +Some signals can only be observed modulo 2*pi, and this can also apply to +two- and three dimensional images. In these cases phase unwrapping is +needed to recover the underlying, unwrapped signal. In this example we will +demonstrate an algorithm [1]_ implemented in ``skimage`` at work for such a +problem. +""" + +import numpy as np +from matplotlib import pyplot as plt +from skimage import data, img_as_float, color, exposure + + +# Load an image as a floating-point grayscale +image = color.rgb2gray(img_as_float(data.chelsea())) +# Scale the image to [0, 4*pi] +image = exposure.rescale_intensity(image, out_range=(0, 4 * np.pi)) +# Create a phase-wrapped image in the interval [-pi, pi) +image_wrapped = np.angle(np.exp(1j * image)) +# Perform phase unwrapping +image_unwrapped = exposure.unwrap(image_wrapped) + +# Plotting +plt.figure() +plt.gray() # grayscale colormap as default +imkwargs = dict(vmin=0, vmax=4 * np.pi) +plt.subplot(221) +plt.title('Original') +plt.imshow(image, **imkwargs) +plt.colorbar() + +plt.subplot(222) +plt.title('Wrapped phase') +plt.imshow(image_wrapped, vmin=-np.pi, vmax=np.pi) +plt.colorbar() + +plt.subplot(223) +plt.title('After phase unwrapping') +plt.imshow(image_unwrapped) +plt.colorbar() + +plt.subplot(224) +plt.title('Unwrapped minus original') +plt.imshow(image_unwrapped - image) +plt.colorbar() + +plt.show() + + +""" +.. image:: PLOT2RST.current_figure + +References +---------- + +.. [1] Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, + and Munther A. Gdeisat, "Fast two-dimensional phase-unwrapping + algorithm based on sorting by reliability following a noncontinuous + path", Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002 +""" From a2a6f8d4b505e5a7d21a71a2920509927aa99a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 14:06:28 +0200 Subject: [PATCH 40/84] unwrap: Use relative imports --- skimage/exposure/unwrap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index d208e0ce..d83c2c65 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -1,7 +1,7 @@ import numpy as np -import _unwrap_2d -import _unwrap_3d +import ._unwrap_2d +import ._unwrap_3d def unwrap(image, wrap_around=False): From 2f784366b7f1ccc9e8ec18f9e1baf9c53bc4e055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 8 Jul 2013 14:26:37 +0200 Subject: [PATCH 41/84] unwrap: Correct use of relative imports. --- skimage/exposure/unwrap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index d83c2c65..648842db 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -1,7 +1,7 @@ import numpy as np -import ._unwrap_2d -import ._unwrap_3d +from . import _unwrap_2d +from . import _unwrap_3d def unwrap(image, wrap_around=False): From 8a81624ba887dc3d5699f1645f2bc9c7cebe18d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 9 Jul 2013 20:49:57 +0200 Subject: [PATCH 42/84] unwrap: Format references correctly. --- skimage/exposure/unwrap.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 648842db..01b996e5 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -29,10 +29,10 @@ def unwrap(image, wrap_around=False): References ---------- - - Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, - and Munther A. Gdeisat, "Fast two-dimensional phase-unwrapping - algorithm based on sorting by reliability following a noncontinuous - path", Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002 + .. [1] Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, + and Munther A. Gdeisat, "Fast two-dimensional phase-unwrapping + algorithm based on sorting by reliability following a noncontinuous + path", Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002 ''' image = np.require(image, np.float32, ['C']) if image.ndim not in (2, 3): From 0e56ee957754c635266119b2a5bcc8596084e5d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 9 Jul 2013 20:50:43 +0200 Subject: [PATCH 43/84] unwrap: Remove plotting code. --- skimage/exposure/tests/test_unwrap.py | 34 --------------------------- 1 file changed, 34 deletions(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 5627bd79..8de57c92 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -85,37 +85,3 @@ def unwrap_plots(): if __name__=="__main__": run_module_suite() - - unwrap_plots() - - # p0,p1,p2,p3,p4 = test_unwrap2D() - # plt.figure(1) - # plt.clf() - # plt.subplot(322) - # plt.imshow(p0,interpolation = 'nearest') - # plt.subplot(323) - # plt.imshow(p1,interpolation = 'nearest') - # plt.subplot(324) - # plt.imshow(p2, interpolation = 'nearest') - # plt.subplot(325) - # plt.imshow(p3, interpolation = 'nearest') - # plt.subplot(326) - # plt.imshow(p4, interpolation = 'nearest') - # plt.draw() - - - # p0,p1,p2,p3,p4 = test_unwrap3D() - # plt.figure(2) - # plt.clf() - # plt.subplot(322) - # plt.imshow(p0[:,:,0],interpolation = 'nearest') - # plt.subplot(323) - # plt.imshow(p1[:,:,0],interpolation = 'nearest') - # plt.subplot(324) - # plt.imshow(p2[:,:,0], interpolation = 'nearest') - # plt.subplot(325) - # plt.imshow(p3[:,:,0], interpolation = 'nearest') - # plt.subplot(326) - # plt.imshow(p4[:,:,0], interpolation = 'nearest') - # plt.draw() - # plt.show() From ebef821a70041cf230b2ebacb10ed2262816a5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 10:51:44 +0200 Subject: [PATCH 44/84] unwrap: Add citation for 3D. --- skimage/exposure/unwrap.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 01b996e5..04e7d9c6 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -33,6 +33,11 @@ def unwrap(image, wrap_around=False): and Munther A. Gdeisat, "Fast two-dimensional phase-unwrapping algorithm based on sorting by reliability following a noncontinuous path", Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002 + .. [2] Abdul-Rahman, H., Gdeisat, M., Burton, D., & Lalor, M., "Fast + three-dimensional phase-unwrapping algorithm based on sorting by + reliability following a non-continuous path. In W. Osten, + C. Gorecki, & E. L. Novak (Eds.), Optical Metrology (2005) 32--40, + International Society for Optics and Photonics. ''' image = np.require(image, np.float32, ['C']) if image.ndim not in (2, 3): From 54865ecb23a3c840e8ef2c5350efaf9074e1e327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 10:52:12 +0200 Subject: [PATCH 45/84] unwrap: reformat references --- skimage/exposure/unwrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 04e7d9c6..a80c02f3 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -32,7 +32,7 @@ def unwrap(image, wrap_around=False): .. [1] Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat, "Fast two-dimensional phase-unwrapping algorithm based on sorting by reliability following a noncontinuous - path", Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002 + path", Journal Applied Optics, Vol. 41, No. 35 (2002) 7437, .. [2] Abdul-Rahman, H., Gdeisat, M., Burton, D., & Lalor, M., "Fast three-dimensional phase-unwrapping algorithm based on sorting by reliability following a non-continuous path. In W. Osten, From ac330662b9ed6ede245889b3c958037dd172455f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 10:52:31 +0200 Subject: [PATCH 46/84] unwrap: Remove unused imports --- skimage/exposure/tests/test_unwrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 8de57c92..4a329928 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -1,5 +1,5 @@ import numpy as np -from numpy.testing import run_module_suite, TestCase, assert_array_almost_equal +from numpy.testing import run_module_suite, assert_array_almost_equal from skimage.exposure import unwrap From 0e8be31ba60a1426325576bc05581d3d74be7b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 12:14:59 +0200 Subject: [PATCH 47/84] unwrap: Simplify handling of masked arrays. --- skimage/exposure/unwrap.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index a80c02f3..c1251734 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -39,7 +39,6 @@ def unwrap(image, wrap_around=False): C. Gorecki, & E. L. Novak (Eds.), Optical Metrology (2005) 32--40, International Society for Optics and Photonics. ''' - image = np.require(image, np.float32, ['C']) if image.ndim not in (2, 3): raise ValueError('image must be 2 or 3 dimensional') if isinstance(wrap_around, bool): @@ -54,21 +53,22 @@ def unwrap(image, wrap_around=False): raise ValueError('wrap_around must be a bool or a sequence with ' 'length equal to the dimensionality of image') - image_masked = np.ma.asarray(image) - image_unwrapped = np.empty_like(image_masked.data) + if np.ma.isMaskedArray(image): + mask = np.require(image.mask, np.uint8, ['C']) + else: + mask = np.zeros(image.shape, dtype=np.uint8, order='C') + image_not_masked = np.asarray(image, dtype=np.float32, order='C') + image_unwrapped = np.empty(image.shape, dtype=np.float32) + if image.ndim == 2: - _unwrap_2d._unwrap2D(image_masked.data, - np.ma.getmaskarray(image_masked).astype(np.uint8), - image_unwrapped, + _unwrap_2d._unwrap2D(image_not_masked, mask, image_unwrapped, wrap_around[0], wrap_around[1]) elif image.ndim == 3: - _unwrap_3d._unwrap3D(image_masked.data, - np.ma.getmaskarray(image_masked).astype(np.uint8), - image_unwrapped, + _unwrap_3d._unwrap3D(image_not_masked, mask, image_unwrapped, wrap_around[0], wrap_around[1], wrap_around[2]) if np.ma.isMaskedArray(image): - return np.ma.array(image_unwrapped, mask = image_masked.mask) + return np.ma.array(image_unwrapped, mask=mask) else: return image_unwrapped From 6dbe6965e6d5a7dd13c481cd7868fb46cbf64d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 12:46:45 +0200 Subject: [PATCH 48/84] unwrap: Test wrap_around functionality. This test is currently failing. Most likely, the axes are swapped. --- skimage/exposure/tests/test_unwrap.py | 43 ++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 4a329928..9798bba0 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -1,8 +1,12 @@ +from __future__ import print_function, division + import numpy as np -from numpy.testing import run_module_suite, assert_array_almost_equal +from numpy.testing import (run_module_suite, assert_array_almost_equal, + assert_almost_equal) from skimage.exposure import unwrap + def test_unwrap2D(): x, y = np.ogrid[:8, :16] phi = 2*np.pi*(x*0.2 + y*0.1) @@ -47,6 +51,43 @@ def test_unwrap3D_masked(): s = np.round(phi_unwrapped_masked[0,0,0]/(2*np.pi)) assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) + +def check_wrap_around(ndim, axis): + # create a ramp, but with the last pixel along axis equalling the first + elements = 100 + ramp = np.linspace(0, 12 * np.pi, elements) + ramp[-1] = ramp[0] + image = ramp.reshape(tuple([elements if n == axis else 1 + for n in range(ndim)])) + image_wrapped = np.angle(np.exp(1j * image)) + + index_first = tuple([0] * ndim) + index_last = tuple([-1 if n == axis else 0 for n in range(ndim)]) + # unwrap the image without wrap around + image_unwrap_no_wrap_around = unwrap(image_wrapped) + print('endpoints without wrap_around:', + image_unwrap_no_wrap_around[index_first], + image_unwrap_no_wrap_around[index_last]) + # without wrap around, the endpoints of the image should differ + assert abs(image_unwrap_no_wrap_around[index_first] + - image_unwrap_no_wrap_around[index_last]) > np.pi + # unwrap the image with wrap around + wrap_around = [n == axis for n in range(ndim)] + image_unwrap_wrap_around = unwrap(image_wrapped, wrap_around) + print('endpoints with wrap_around:', + image_unwrap_wrap_around[index_first], + image_unwrap_wrap_around[index_last]) + # with wrap around, the endpoints of the image should be equal + assert_almost_equal(image_unwrap_wrap_around[index_first], + image_unwrap_wrap_around[index_last]) + + +def test_wrap_around(): + for ndim in (2, 3): + for axis in range(ndim): + yield check_wrap_around, ndim, axis + + def unwrap_plots(): x, y = np.ogrid[:32, :32] From 12268ff5553753791beacfa84006e9cffb7bd15f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 12:51:08 +0200 Subject: [PATCH 49/84] unwrap: Refactor and fix wrap around functionality. --- skimage/exposure/_unwrap_2d.pyx | 4 ++-- skimage/exposure/_unwrap_3d.pyx | 4 ++-- skimage/exposure/unwrap.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/skimage/exposure/_unwrap_2d.pyx b/skimage/exposure/_unwrap_2d.pyx index dab52167..19292f02 100644 --- a/skimage/exposure/_unwrap_2d.pyx +++ b/skimage/exposure/_unwrap_2d.pyx @@ -7,12 +7,12 @@ cdef extern void unwrap2D(float* wrapped_image, def _unwrap2D(float[:,::1] array, unsigned char[:,::1] mask, float[:,::1] unwrapped_array, - wrap_around_x, wrap_around_y): + wrap_around): unwrap2D(&array[0,0], &unwrapped_array[0,0], &mask[0,0], array.shape[1], array.shape[0], - wrap_around_x, wrap_around_y, + wrap_around[1], wrap_around[0], ) diff --git a/skimage/exposure/_unwrap_3d.pyx b/skimage/exposure/_unwrap_3d.pyx index aa18b377..871bc293 100644 --- a/skimage/exposure/_unwrap_3d.pyx +++ b/skimage/exposure/_unwrap_3d.pyx @@ -7,12 +7,12 @@ cdef extern void unwrap3D(float* wrapped_volume, def _unwrap3D(float[:,:,::1] array, unsigned char[:,:,::1] mask, float[:,:,::1] unwrapped_array, - wrap_around_x, wrap_around_y, wrap_around_z): + wrap_around): unwrap3D(&array[0,0,0], &unwrapped_array[0,0,0], &mask[0,0,0], array.shape[2], array.shape[1], array.shape[0], #TODO: check!!! - wrap_around_x, wrap_around_y, wrap_around_z, + wrap_around[2], wrap_around[1], wrap_around[0], ) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index c1251734..a67adc22 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -62,10 +62,10 @@ def unwrap(image, wrap_around=False): if image.ndim == 2: _unwrap_2d._unwrap2D(image_not_masked, mask, image_unwrapped, - wrap_around[0], wrap_around[1]) + wrap_around) elif image.ndim == 3: _unwrap_3d._unwrap3D(image_not_masked, mask, image_unwrapped, - wrap_around[0], wrap_around[1], wrap_around[2]) + wrap_around) if np.ma.isMaskedArray(image): return np.ma.array(image_unwrapped, mask=mask) From e8fa4998ad86642e63f313fbc9dac25e247c3301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 12:52:15 +0200 Subject: [PATCH 50/84] unwrap: Whitespace fixes and comment removal. --- skimage/exposure/_unwrap_2d.pyx | 16 +++++++--------- skimage/exposure/_unwrap_3d.pyx | 16 +++++++--------- skimage/exposure/unwrap.py | 4 ---- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/skimage/exposure/_unwrap_2d.pyx b/skimage/exposure/_unwrap_2d.pyx index 19292f02..bbbe301c 100644 --- a/skimage/exposure/_unwrap_2d.pyx +++ b/skimage/exposure/_unwrap_2d.pyx @@ -1,18 +1,16 @@ -cdef extern void unwrap2D(float* wrapped_image, - float* unwrapped_image, - unsigned char* input_mask, +cdef extern void unwrap2D(float* wrapped_image, + float* unwrapped_image, + unsigned char* input_mask, int image_width, int image_height, int wrap_around_x, int wrap_around_y) -def _unwrap2D(float[:,::1] array, +def _unwrap2D(float[:,::1] array, unsigned char[:,::1] mask, float[:,::1] unwrapped_array, wrap_around): - unwrap2D(&array[0,0], - &unwrapped_array[0,0], - &mask[0,0], + unwrap2D(&array[0,0], + &unwrapped_array[0,0], + &mask[0,0], array.shape[1], array.shape[0], wrap_around[1], wrap_around[0], ) - - diff --git a/skimage/exposure/_unwrap_3d.pyx b/skimage/exposure/_unwrap_3d.pyx index 871bc293..b214c96e 100644 --- a/skimage/exposure/_unwrap_3d.pyx +++ b/skimage/exposure/_unwrap_3d.pyx @@ -1,18 +1,16 @@ -cdef extern void unwrap3D(float* wrapped_volume, - float* unwrapped_volume, - unsigned char* input_mask, +cdef extern void unwrap3D(float* wrapped_volume, + float* unwrapped_volume, + unsigned char* input_mask, int image_width, int image_height, int volume_depth, int wrap_around_x, int wrap_around_y, int wrap_around_z) -def _unwrap3D(float[:,:,::1] array, +def _unwrap3D(float[:,:,::1] array, unsigned char[:,:,::1] mask, float[:,:,::1] unwrapped_array, wrap_around): - unwrap3D(&array[0,0,0], - &unwrapped_array[0,0,0], - &mask[0,0,0], + unwrap3D(&array[0,0,0], + &unwrapped_array[0,0,0], + &mask[0,0,0], array.shape[2], array.shape[1], array.shape[0], #TODO: check!!! wrap_around[2], wrap_around[1], wrap_around[0], ) - - diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index a67adc22..9fd9621c 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -71,7 +71,3 @@ def unwrap(image, wrap_around=False): return np.ma.array(image_unwrapped, mask=mask) else: return image_unwrapped - - #TODO: set_fill to minimum value - #TODO: check for empty mask, not a single contiguous pixel - From 676ba5a07ed7de88f20456f94db1081a5449a605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 13:03:05 +0200 Subject: [PATCH 51/84] unwrap: rename cython functions. --- skimage/exposure/_unwrap_2d.pyx | 2 +- skimage/exposure/_unwrap_3d.pyx | 2 +- skimage/exposure/unwrap.py | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/skimage/exposure/_unwrap_2d.pyx b/skimage/exposure/_unwrap_2d.pyx index bbbe301c..1d67d932 100644 --- a/skimage/exposure/_unwrap_2d.pyx +++ b/skimage/exposure/_unwrap_2d.pyx @@ -4,7 +4,7 @@ cdef extern void unwrap2D(float* wrapped_image, int image_width, int image_height, int wrap_around_x, int wrap_around_y) -def _unwrap2D(float[:,::1] array, +def unwrap_2d(float[:,::1] array, unsigned char[:,::1] mask, float[:,::1] unwrapped_array, wrap_around): diff --git a/skimage/exposure/_unwrap_3d.pyx b/skimage/exposure/_unwrap_3d.pyx index b214c96e..9a900cf2 100644 --- a/skimage/exposure/_unwrap_3d.pyx +++ b/skimage/exposure/_unwrap_3d.pyx @@ -4,7 +4,7 @@ cdef extern void unwrap3D(float* wrapped_volume, int image_width, int image_height, int volume_depth, int wrap_around_x, int wrap_around_y, int wrap_around_z) -def _unwrap3D(float[:,:,::1] array, +def unwrap_3d(float[:,:,::1] array, unsigned char[:,:,::1] mask, float[:,:,::1] unwrapped_array, wrap_around): diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 9fd9621c..f21ec455 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -1,7 +1,7 @@ import numpy as np -from . import _unwrap_2d -from . import _unwrap_3d +from ._unwrap_2d import unwrap_2d +from ._unwrap_3d import unwrap_3d def unwrap(image, wrap_around=False): @@ -61,10 +61,10 @@ def unwrap(image, wrap_around=False): image_unwrapped = np.empty(image.shape, dtype=np.float32) if image.ndim == 2: - _unwrap_2d._unwrap2D(image_not_masked, mask, image_unwrapped, + unwrap_2d(image_not_masked, mask, image_unwrapped, wrap_around) elif image.ndim == 3: - _unwrap_3d._unwrap3D(image_not_masked, mask, image_unwrapped, + unwrap_3d(image_not_masked, mask, image_unwrapped, wrap_around) if np.ma.isMaskedArray(image): From 5022cfb699ca3e49a5ab1a9a9d0c48852e86c708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 13:04:38 +0200 Subject: [PATCH 52/84] unwrap: PEP8 fixes for cython extensions. --- skimage/exposure/_unwrap_2d.pyx | 12 ++++++------ skimage/exposure/_unwrap_3d.pyx | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/skimage/exposure/_unwrap_2d.pyx b/skimage/exposure/_unwrap_2d.pyx index 1d67d932..4727404c 100644 --- a/skimage/exposure/_unwrap_2d.pyx +++ b/skimage/exposure/_unwrap_2d.pyx @@ -4,13 +4,13 @@ cdef extern void unwrap2D(float* wrapped_image, int image_width, int image_height, int wrap_around_x, int wrap_around_y) -def unwrap_2d(float[:,::1] array, - unsigned char[:,::1] mask, - float[:,::1] unwrapped_array, +def unwrap_2d(float[:, ::1] array, + unsigned char[:, ::1] mask, + float[:, ::1] unwrapped_array, wrap_around): - unwrap2D(&array[0,0], - &unwrapped_array[0,0], - &mask[0,0], + unwrap2D(&array[0, 0], + &unwrapped_array[0, 0], + &mask[0, 0], array.shape[1], array.shape[0], wrap_around[1], wrap_around[0], ) diff --git a/skimage/exposure/_unwrap_3d.pyx b/skimage/exposure/_unwrap_3d.pyx index 9a900cf2..f7a4f10e 100644 --- a/skimage/exposure/_unwrap_3d.pyx +++ b/skimage/exposure/_unwrap_3d.pyx @@ -4,13 +4,13 @@ cdef extern void unwrap3D(float* wrapped_volume, int image_width, int image_height, int volume_depth, int wrap_around_x, int wrap_around_y, int wrap_around_z) -def unwrap_3d(float[:,:,::1] array, - unsigned char[:,:,::1] mask, - float[:,:,::1] unwrapped_array, +def unwrap_3d(float[:, :, ::1] array, + unsigned char[:, :, ::1] mask, + float[:, :, ::1] unwrapped_array, wrap_around): - unwrap3D(&array[0,0,0], - &unwrapped_array[0,0,0], - &mask[0,0,0], + unwrap3D(&array[0, 0, 0], + &unwrapped_array[0, 0, 0], + &mask[0, 0, 0], array.shape[2], array.shape[1], array.shape[0], #TODO: check!!! wrap_around[2], wrap_around[1], wrap_around[0], ) From 9644ed56551b12a67e7ac53cc1617337ba4e328b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 13:06:43 +0200 Subject: [PATCH 53/84] unwrap: rename variables in cython extensions --- skimage/exposure/_unwrap_2d.pyx | 10 +++++----- skimage/exposure/_unwrap_3d.pyx | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/skimage/exposure/_unwrap_2d.pyx b/skimage/exposure/_unwrap_2d.pyx index 4727404c..88983287 100644 --- a/skimage/exposure/_unwrap_2d.pyx +++ b/skimage/exposure/_unwrap_2d.pyx @@ -4,13 +4,13 @@ cdef extern void unwrap2D(float* wrapped_image, int image_width, int image_height, int wrap_around_x, int wrap_around_y) -def unwrap_2d(float[:, ::1] array, +def unwrap_2d(float[:, ::1] image, unsigned char[:, ::1] mask, - float[:, ::1] unwrapped_array, + float[:, ::1] unwrapped_image, wrap_around): - unwrap2D(&array[0, 0], - &unwrapped_array[0, 0], + unwrap2D(&image[0, 0], + &unwrapped_image[0, 0], &mask[0, 0], - array.shape[1], array.shape[0], + image.shape[1], image.shape[0], wrap_around[1], wrap_around[0], ) diff --git a/skimage/exposure/_unwrap_3d.pyx b/skimage/exposure/_unwrap_3d.pyx index f7a4f10e..b202e8b9 100644 --- a/skimage/exposure/_unwrap_3d.pyx +++ b/skimage/exposure/_unwrap_3d.pyx @@ -4,13 +4,13 @@ cdef extern void unwrap3D(float* wrapped_volume, int image_width, int image_height, int volume_depth, int wrap_around_x, int wrap_around_y, int wrap_around_z) -def unwrap_3d(float[:, :, ::1] array, +def unwrap_3d(float[:, :, ::1] image, unsigned char[:, :, ::1] mask, - float[:, :, ::1] unwrapped_array, + float[:, :, ::1] unwrapped_image, wrap_around): - unwrap3D(&array[0, 0, 0], - &unwrapped_array[0, 0, 0], + unwrap3D(&image[0, 0, 0], + &unwrapped_image[0, 0, 0], &mask[0, 0, 0], - array.shape[2], array.shape[1], array.shape[0], #TODO: check!!! + image.shape[2], image.shape[1], image.shape[0], #TODO: check!!! wrap_around[2], wrap_around[1], wrap_around[0], ) From a39695154fef8ed695ebc22cc231558a2939fbec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 14:16:32 +0200 Subject: [PATCH 54/84] unwrap: Update bento.info. --- bento.info | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bento.info b/bento.info index 84ddf4a8..7be7bbd3 100644 --- a/bento.info +++ b/bento.info @@ -144,6 +144,12 @@ Library: Extension: skimage.filter.rank.bilateral_cy Sources: skimage/filter/rank/bilateral_cy.pyx + Extension: skimage.exposure._unwrap_3d + Sources: + skimage/exposure/_unwrap_3d.pyx, skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c + Extension: skimage.exposure._unwrap_2d + Sources: + skimage/exposure/_unwrap_2d.pyx, skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c Executable: skivi Module: skimage.scripts.skivi From b9f119a42876f6e4e5647f7d0428d67ddac228f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Thu, 11 Jul 2013 18:01:58 +0200 Subject: [PATCH 55/84] unwrap: Python 3 compatibility. --- skimage/exposure/unwrap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index f21ec455..4f93ae0a 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -2,6 +2,7 @@ import numpy as np from ._unwrap_2d import unwrap_2d from ._unwrap_3d import unwrap_3d +from .._shared.six import string_types def unwrap(image, wrap_around=False): @@ -44,7 +45,7 @@ def unwrap(image, wrap_around=False): if isinstance(wrap_around, bool): wrap_around = [wrap_around] * image.ndim elif (hasattr(wrap_around, '__getitem__') - and not isinstance(wrap_around, basestring)): + and not isinstance(wrap_around, string_types)): if not len(wrap_around) == image.ndim: raise ValueError('Length of wrap_around must equal the ' 'dimensionality of image') From 43d110627b8c0f0a65567cccb314c382a9f6f8f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 10:51:30 +0200 Subject: [PATCH 56/84] unwrap: PEP8 fixes. --- skimage/exposure/tests/test_unwrap.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 9798bba0..bb345b00 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -16,6 +16,7 @@ def test_unwrap2D(): s = np.round(phi_unwrapped[0,0]/(2*np.pi)) assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) + def test_unwrap2D_masked(): x, y = np.ogrid[:8, :16] phi = 2*np.pi*(x*0.2 + y*0.1) @@ -30,6 +31,7 @@ def test_unwrap2D_masked(): s = np.round(phi_unwrapped_masked[0,0]/(2*np.pi)) assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) + def test_unwrap3D(): x, y, z = np.ogrid[:8, :12, :4] phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) @@ -39,6 +41,7 @@ def test_unwrap3D(): s = np.round(phi_unwrapped[0,0]/(2*np.pi)) assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) + def test_unwrap3D_masked(): x, y, z = np.ogrid[:8, :12, :4] phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) @@ -124,5 +127,6 @@ def unwrap_plots(): plt.draw() plt.show() + if __name__=="__main__": run_module_suite() From b0c21ea9727dc1f1841663af447b4852c9ca7580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 11:38:36 +0200 Subject: [PATCH 57/84] unwrap: Reduce duplication in tests. --- skimage/exposure/tests/test_unwrap.py | 43 ++++++++++++++++++--------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index bb345b00..a549cc0b 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -2,19 +2,40 @@ from __future__ import print_function, division import numpy as np from numpy.testing import (run_module_suite, assert_array_almost_equal, - assert_almost_equal) + assert_almost_equal, assert_array_equal) +import warnings from skimage.exposure import unwrap +def assert_phase_almost_equal(a, b, *args, **kwargs): + '''An assert_almost_equal insensitive to phase shifts of n*2*pi.''' + shift = 2 * np.pi * np.round((b.mean() - a.mean()) / (2 * np.pi)) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + print('assert_phase_allclose, abs', np.max(np.abs(a - (b - shift)))) + print('assert_phase_allclose, rel', + np.max(np.abs((a - (b - shift)) / a))) + if np.ma.isMaskedArray(a): + assert np.ma.isMaskedArray(b) + assert_array_equal(a.mask, b.mask) + au = np.asarray(a) + bu = np.asarray(b) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + print('assert_phase_allclose, no mask, abs', + np.max(np.abs(au - (bu - shift)))) + print('assert_phase_allclose, no mask, rel', + np.max(np.abs((au - (bu - shift)) / au))) + assert_array_almost_equal(a + shift, b, *args, **kwargs) + + def test_unwrap2D(): x, y = np.ogrid[:8, :16] phi = 2*np.pi*(x*0.2 + y*0.1) phi_wrapped = np.angle(np.exp(1j*phi)) phi_unwrapped = unwrap(phi_wrapped) - - s = np.round(phi_unwrapped[0,0]/(2*np.pi)) - assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) + assert_phase_almost_equal(phi, phi_unwrapped) def test_unwrap2D_masked(): @@ -25,11 +46,9 @@ def test_unwrap2D_masked(): mask[4:6, 4:8] = 1 phi_wrapped = np.angle(np.exp(1j*phi)) - phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) + phi_wrapped_masked = np.ma.array(phi_wrapped, dtype=np.float32, mask=mask) phi_unwrapped_masked = unwrap(phi_wrapped_masked) - - s = np.round(phi_unwrapped_masked[0,0]/(2*np.pi)) - assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) + assert_phase_almost_equal(phi, phi_unwrapped_masked) def test_unwrap3D(): @@ -37,9 +56,7 @@ def test_unwrap3D(): phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) phi_wrapped = np.angle(np.exp(1j*phi)) phi_unwrapped = unwrap(phi_wrapped) - - s = np.round(phi_unwrapped[0,0]/(2*np.pi)) - assert_array_almost_equal(phi, phi_unwrapped - s*2*np.pi) + assert_phase_almost_equal(phi, phi_unwrapped) def test_unwrap3D_masked(): @@ -50,9 +67,7 @@ def test_unwrap3D_masked(): mask[4:6, 4:6, 1:3] = 1 phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) phi_unwrapped_masked = unwrap(phi_wrapped_masked) - - s = np.round(phi_unwrapped_masked[0,0,0]/(2*np.pi)) - assert_array_almost_equal(phi + 2*np.pi*s, phi_unwrapped_masked) + assert_phase_almost_equal(phi, phi_unwrapped_masked) def check_wrap_around(ndim, axis): From 619da811d87eadcc91b3577c268da3fb0d4c6c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 11:56:28 +0200 Subject: [PATCH 58/84] unwrap: Reduce code duplication. Use the yield functionality in nose to minimize setup. --- skimage/exposure/tests/test_unwrap.py | 56 +++++++++++---------------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index a549cc0b..9e11c207 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -30,44 +30,32 @@ def assert_phase_almost_equal(a, b, *args, **kwargs): assert_array_almost_equal(a + shift, b, *args, **kwargs) -def test_unwrap2D(): +def check_unwrap(image, mask=None): + image_wrapped = np.angle(np.exp(1j * image)) + if not mask is None: + print('Testing a masked image') + image = np.ma.array(image, mask=mask) + image_wrapped = np.ma.array(image_wrapped, mask=mask) + image_unwrapped = unwrap(image_wrapped) + assert_phase_almost_equal(image_unwrapped, image) + + +def test_unwrap_2d(): x, y = np.ogrid[:8, :16] - phi = 2*np.pi*(x*0.2 + y*0.1) - phi_wrapped = np.angle(np.exp(1j*phi)) - phi_unwrapped = unwrap(phi_wrapped) - assert_phase_almost_equal(phi, phi_unwrapped) + image = 2 * np.pi * (x * 0.2 + y * 0.1) + yield check_unwrap, image + mask = np.zeros(image.shape, dtype=np.bool) + mask[4:6, 4:8] = True + yield check_unwrap, image, mask -def test_unwrap2D_masked(): - x, y = np.ogrid[:8, :16] - phi = 2*np.pi*(x*0.2 + y*0.1) - - mask = np.zeros_like(phi, dtype = np.uint8) - mask[4:6, 4:8] = 1 - - phi_wrapped = np.angle(np.exp(1j*phi)) - phi_wrapped_masked = np.ma.array(phi_wrapped, dtype=np.float32, mask=mask) - phi_unwrapped_masked = unwrap(phi_wrapped_masked) - assert_phase_almost_equal(phi, phi_unwrapped_masked) - - -def test_unwrap3D(): +def test_unwrap_3d(): x, y, z = np.ogrid[:8, :12, :4] - phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) - phi_wrapped = np.angle(np.exp(1j*phi)) - phi_unwrapped = unwrap(phi_wrapped) - assert_phase_almost_equal(phi, phi_unwrapped) - - -def test_unwrap3D_masked(): - x, y, z = np.ogrid[:8, :12, :4] - phi = 2*np.pi*(x*0.2 + y*0.1 + z*0.05) - phi_wrapped = np.angle(np.exp(1j*phi)) - mask = np.zeros_like(phi, dtype = np.uint8) - mask[4:6, 4:6, 1:3] = 1 - phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) - phi_unwrapped_masked = unwrap(phi_wrapped_masked) - assert_phase_almost_equal(phi, phi_unwrapped_masked) + image = 2 * np.pi * (x * 0.2 + y * 0.1 + z * 0.05) + yield check_unwrap, image + mask = np.zeros(image.shape, dtype=np.bool) + mask[4:6, 4:6, 1:3] = True + yield check_unwrap, image, mask def check_wrap_around(ndim, axis): From c0d0984049b7849b0b01f1e1c0454cfb3d5826fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 12:01:04 +0200 Subject: [PATCH 59/84] unwrap: Make sure test data wraps along all dimensions. --- skimage/exposure/tests/test_unwrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 9e11c207..0115a192 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -50,7 +50,7 @@ def test_unwrap_2d(): def test_unwrap_3d(): - x, y, z = np.ogrid[:8, :12, :4] + x, y, z = np.ogrid[:8, :12, :16] image = 2 * np.pi * (x * 0.2 + y * 0.1 + z * 0.05) yield check_unwrap, image mask = np.zeros(image.shape, dtype=np.bool) From 8a93677db04d189dd9bc4c1be39882aaec65bdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 12:01:45 +0200 Subject: [PATCH 60/84] unwrap: Delete "example" from the test file. --- skimage/exposure/tests/test_unwrap.py | 37 --------------------------- 1 file changed, 37 deletions(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 0115a192..39e97769 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -94,42 +94,5 @@ def test_wrap_around(): yield check_wrap_around, ndim, axis -def unwrap_plots(): - - x, y = np.ogrid[:32, :32] - phi = 2*np.pi*(x*0.2 + y*0.1) - - #phi = 1*np.arctan2(x-14.3, y-6.3) - 2*np.arctan2(x-18.3, y-22.1) - - phi[8,8] = np.NaN - - phi_wrapped = np.angle(np.exp(1j*phi)) - phi_unwrapped = unwrap(phi_wrapped, - #wrap_around_axis_0 = True, - #wrap_around_axis_1 = True, - ) - - mask = np.zeros_like(phi, dtype = np.uint8) - #mask[10:22, 4:10] = 1 - phi_wrapped_masked = np.ma.array(phi_wrapped, dtype = np.float32, mask = mask) - phi_unwrapped_masked = unwrap(phi_wrapped_masked) - - import matplotlib.pyplot as plt - plt.figure(1) - plt.clf() - plt.gray() - plt.subplot(221) - plt.imshow(phi, interpolation = 'nearest') - plt.subplot(222) - plt.imshow(phi_wrapped, interpolation = 'nearest') - plt.subplot(223) - plt.imshow(phi_unwrapped, interpolation = 'nearest') - plt.subplot(224) - plt.imshow(phi_unwrapped_masked, interpolation = 'nearest') - - plt.draw() - plt.show() - - if __name__=="__main__": run_module_suite() From 9e50686c8f49a6b2f90b22e52ecf38c140b9bfe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 12:22:42 +0200 Subject: [PATCH 61/84] unwrap: Add test for unwrapping masked images. --- skimage/exposure/tests/test_unwrap.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 39e97769..74e84aee 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -94,5 +94,32 @@ def test_wrap_around(): yield check_wrap_around, ndim, axis +def test_mask(): + length = 100 + ramps = [np.linspace(0, 4 * np.pi, length), + np.linspace(0, 8 * np.pi, length), + np.linspace(0, 6 * np.pi, length)] + image = np.vstack(ramps) + mask_1d = np.ones((length,), dtype=np.bool) + mask_1d[0] = mask_1d[-1] = False + for i in range(len(ramps)): + # mask all ramps but the i'th one + mask = np.zeros(image.shape, dtype=np.bool) + mask |= mask_1d.reshape(1, -1) + mask[i, :] = False # unmask i'th ramp + image_wrapped = np.ma.array(np.angle(np.exp(1j * image)), mask=mask) + image_unwrapped = unwrap(image_wrapped) + image_unwrapped -= image_unwrapped[0, 0] # remove phase shift + # The end of the unwrapped array should have value equal to the + # endpoint of the unmasked ramp + assert_array_almost_equal(image_unwrapped[:, -1], image[i, -1]) + + # Same tests, but forcing use of the 3D unwrapper by reshaping + image_wrapped_3d = image_wrapped.reshape((1,) + image_wrapped.shape) + image_unwrapped_3d = unwrap(image_wrapped_3d) + image_unwrapped_3d -= image_unwrapped_3d[0, 0, 0] # remove phase shift + assert_array_almost_equal(image_unwrapped_3d[:, :, -1], image[i, -1]) + + if __name__=="__main__": run_module_suite() From 3ddd94a89cd822039caef3ef12d6852032b96c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 12:29:27 +0200 Subject: [PATCH 62/84] unwrap: Simplify example. --- doc/examples/plot_phase_unwrap.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/doc/examples/plot_phase_unwrap.py b/doc/examples/plot_phase_unwrap.py index 258ed21e..85be5fde 100644 --- a/doc/examples/plot_phase_unwrap.py +++ b/doc/examples/plot_phase_unwrap.py @@ -26,26 +26,24 @@ image_unwrapped = exposure.unwrap(image_wrapped) # Plotting plt.figure() -plt.gray() # grayscale colormap as default -imkwargs = dict(vmin=0, vmax=4 * np.pi) plt.subplot(221) plt.title('Original') -plt.imshow(image, **imkwargs) +plt.imshow(image, cmap='gray', vmin=0, vmax=4 * np.pi) plt.colorbar() plt.subplot(222) plt.title('Wrapped phase') -plt.imshow(image_wrapped, vmin=-np.pi, vmax=np.pi) +plt.imshow(image_wrapped, cmap='gray', vmin=-np.pi, vmax=np.pi) plt.colorbar() plt.subplot(223) plt.title('After phase unwrapping') -plt.imshow(image_unwrapped) +plt.imshow(image_unwrapped, cmap='gray') plt.colorbar() plt.subplot(224) plt.title('Unwrapped minus original') -plt.imshow(image_unwrapped - image) +plt.imshow(image_unwrapped - image, cmap='gray') plt.colorbar() plt.show() From e0b7fe32a1de50e1ce24db19d35c973b608d49d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 12:31:31 +0200 Subject: [PATCH 63/84] unwrap: PEP8 fixes. --- skimage/exposure/unwrap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 4f93ae0a..b9c099e0 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -63,10 +63,10 @@ def unwrap(image, wrap_around=False): if image.ndim == 2: unwrap_2d(image_not_masked, mask, image_unwrapped, - wrap_around) + wrap_around) elif image.ndim == 3: unwrap_3d(image_not_masked, mask, image_unwrapped, - wrap_around) + wrap_around) if np.ma.isMaskedArray(image): return np.ma.array(image_unwrapped, mask=mask) From 4cfec880b68962647638b6dd16439b2d01433114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 17:44:17 +0200 Subject: [PATCH 64/84] unwrap: Small style-like fixes. Based on comments by ahojnnes. --- skimage/exposure/unwrap.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index b9c099e0..e4d112bd 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -46,7 +46,7 @@ def unwrap(image, wrap_around=False): wrap_around = [wrap_around] * image.ndim elif (hasattr(wrap_around, '__getitem__') and not isinstance(wrap_around, string_types)): - if not len(wrap_around) == image.ndim: + if len(wrap_around) != image.ndim: raise ValueError('Length of wrap_around must equal the ' 'dimensionality of image') wrap_around = [bool(wa) for wa in wrap_around] @@ -57,9 +57,9 @@ def unwrap(image, wrap_around=False): if np.ma.isMaskedArray(image): mask = np.require(image.mask, np.uint8, ['C']) else: - mask = np.zeros(image.shape, dtype=np.uint8, order='C') + mask = np.zeros_like(image, dtype=np.uint8, order='C') image_not_masked = np.asarray(image, dtype=np.float32, order='C') - image_unwrapped = np.empty(image.shape, dtype=np.float32) + image_unwrapped = np.empty_like(image, dtype=np.float32, order='C') if image.ndim == 2: unwrap_2d(image_not_masked, mask, image_unwrapped, From 781ead2c9f136f088eeb0e6f316df506fddaa7b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 17:47:48 +0200 Subject: [PATCH 65/84] unwrap: Rename function unwrap() -> unwrap_phase(). --- doc/examples/plot_phase_unwrap.py | 2 +- skimage/exposure/__init__.py | 4 ++-- skimage/exposure/tests/test_unwrap.py | 12 ++++++------ skimage/exposure/unwrap.py | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/examples/plot_phase_unwrap.py b/doc/examples/plot_phase_unwrap.py index 85be5fde..c2aecdb5 100644 --- a/doc/examples/plot_phase_unwrap.py +++ b/doc/examples/plot_phase_unwrap.py @@ -22,7 +22,7 @@ image = exposure.rescale_intensity(image, out_range=(0, 4 * np.pi)) # Create a phase-wrapped image in the interval [-pi, pi) image_wrapped = np.angle(np.exp(1j * image)) # Perform phase unwrapping -image_unwrapped = exposure.unwrap(image_wrapped) +image_unwrapped = exposure.unwrap_phase(image_wrapped) # Plotting plt.figure() diff --git a/skimage/exposure/__init__.py b/skimage/exposure/__init__.py index 390d042b..c8f7b1be 100644 --- a/skimage/exposure/__init__.py +++ b/skimage/exposure/__init__.py @@ -3,7 +3,7 @@ from .exposure import histogram, equalize, equalize_hist, \ adjust_gamma, adjust_sigmoid, adjust_log from ._adapthist import equalize_adapthist -from .unwrap import unwrap +from .unwrap import unwrap_phase __all__ = ['histogram', 'equalize', @@ -14,4 +14,4 @@ __all__ = ['histogram', 'adjust_gamma', 'adjust_sigmoid', 'adjust_log', - 'unwrap'] + 'unwrap_phase'] diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 74e84aee..a465cd2c 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -5,7 +5,7 @@ from numpy.testing import (run_module_suite, assert_array_almost_equal, assert_almost_equal, assert_array_equal) import warnings -from skimage.exposure import unwrap +from skimage.exposure import unwrap_phase def assert_phase_almost_equal(a, b, *args, **kwargs): @@ -36,7 +36,7 @@ def check_unwrap(image, mask=None): print('Testing a masked image') image = np.ma.array(image, mask=mask) image_wrapped = np.ma.array(image_wrapped, mask=mask) - image_unwrapped = unwrap(image_wrapped) + image_unwrapped = unwrap_phase(image_wrapped) assert_phase_almost_equal(image_unwrapped, image) @@ -70,7 +70,7 @@ def check_wrap_around(ndim, axis): index_first = tuple([0] * ndim) index_last = tuple([-1 if n == axis else 0 for n in range(ndim)]) # unwrap the image without wrap around - image_unwrap_no_wrap_around = unwrap(image_wrapped) + image_unwrap_no_wrap_around = unwrap_phase(image_wrapped) print('endpoints without wrap_around:', image_unwrap_no_wrap_around[index_first], image_unwrap_no_wrap_around[index_last]) @@ -79,7 +79,7 @@ def check_wrap_around(ndim, axis): - image_unwrap_no_wrap_around[index_last]) > np.pi # unwrap the image with wrap around wrap_around = [n == axis for n in range(ndim)] - image_unwrap_wrap_around = unwrap(image_wrapped, wrap_around) + image_unwrap_wrap_around = unwrap_phase(image_wrapped, wrap_around) print('endpoints with wrap_around:', image_unwrap_wrap_around[index_first], image_unwrap_wrap_around[index_last]) @@ -108,7 +108,7 @@ def test_mask(): mask |= mask_1d.reshape(1, -1) mask[i, :] = False # unmask i'th ramp image_wrapped = np.ma.array(np.angle(np.exp(1j * image)), mask=mask) - image_unwrapped = unwrap(image_wrapped) + image_unwrapped = unwrap_phase(image_wrapped) image_unwrapped -= image_unwrapped[0, 0] # remove phase shift # The end of the unwrapped array should have value equal to the # endpoint of the unmasked ramp @@ -116,7 +116,7 @@ def test_mask(): # Same tests, but forcing use of the 3D unwrapper by reshaping image_wrapped_3d = image_wrapped.reshape((1,) + image_wrapped.shape) - image_unwrapped_3d = unwrap(image_wrapped_3d) + image_unwrapped_3d = unwrap_phase(image_wrapped_3d) image_unwrapped_3d -= image_unwrapped_3d[0, 0, 0] # remove phase shift assert_array_almost_equal(image_unwrapped_3d[:, :, -1], image[i, -1]) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index e4d112bd..ab05bc5e 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -5,7 +5,7 @@ from ._unwrap_3d import unwrap_3d from .._shared.six import string_types -def unwrap(image, wrap_around=False): +def unwrap_phase(image, wrap_around=False): '''From ``image``, wrapped to lie in the interval [-pi, pi), recover the original, unwrapped image. From 27c13a119368356a0f3005e1117cb36e1d189ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 17:58:49 +0200 Subject: [PATCH 66/84] unwrap: Warn about singleton dimensions in 3D arrays. --- skimage/exposure/tests/test_unwrap.py | 10 ++++++++-- skimage/exposure/unwrap.py | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index a465cd2c..1e1b0cd5 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -70,7 +70,10 @@ def check_wrap_around(ndim, axis): index_first = tuple([0] * ndim) index_last = tuple([-1 if n == axis else 0 for n in range(ndim)]) # unwrap the image without wrap around - image_unwrap_no_wrap_around = unwrap_phase(image_wrapped) + with warnings.catch_warnings(): + # We do not want warnings about length 1 dimensions + warnings.simplefilter("ignore") + image_unwrap_no_wrap_around = unwrap_phase(image_wrapped) print('endpoints without wrap_around:', image_unwrap_no_wrap_around[index_first], image_unwrap_no_wrap_around[index_last]) @@ -79,7 +82,10 @@ def check_wrap_around(ndim, axis): - image_unwrap_no_wrap_around[index_last]) > np.pi # unwrap the image with wrap around wrap_around = [n == axis for n in range(ndim)] - image_unwrap_wrap_around = unwrap_phase(image_wrapped, wrap_around) + with warnings.catch_warnings(): + # We do not want warnings about length 1 dimensions + warnings.simplefilter("ignore") + image_unwrap_wrap_around = unwrap_phase(image_wrapped, wrap_around) print('endpoints with wrap_around:', image_unwrap_wrap_around[index_first], image_unwrap_wrap_around[index_last]) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index ab05bc5e..c43e263d 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -1,4 +1,5 @@ import numpy as np +import warnings from ._unwrap_2d import unwrap_2d from ._unwrap_3d import unwrap_3d @@ -53,6 +54,9 @@ def unwrap_phase(image, wrap_around=False): else: raise ValueError('wrap_around must be a bool or a sequence with ' 'length equal to the dimensionality of image') + if image.ndim == 3 and 1 in image.shape: + warnings.warn('image is 3D and has a length 1 dimension; consider ' + 'using a 2D array to use the 2D unwrapping algorithm') if np.ma.isMaskedArray(image): mask = np.require(image.mask, np.uint8, ['C']) From b2ac1a587265e9fec53aa96fe1ce9dfeadd2cf9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 18:33:26 +0200 Subject: [PATCH 67/84] unwrap: Add docstring example. --- skimage/exposure/unwrap.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index c43e263d..a38162bd 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -29,6 +29,15 @@ def unwrap_phase(image, wrap_around=False): Unwrapped image of the same shape as the input. If the input ``image`` was a masked array, the mask will be preserved. + Examples + -------- + >>> c0, c1 = np.ogrid[-1:1:128j, -1:1:128j] + >>> image = 12 * np.pi * np.exp(-(c0**2 + c1**2)) + >>> image_wrapped = np.angle(np.exp(1j * image)) + >>> image_unwrapped = unwrap_phase(image_wrapped) + >>> np.std(image_unwrapped - image) < 1e-6 # A constant offset is normal + True + References ---------- .. [1] Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, From f87fadf0f070469af5d6c6d737ca1c41102600a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Mon, 15 Jul 2013 18:47:58 +0200 Subject: [PATCH 68/84] unwrap: Rename C files. --- bento.info | 4 ++-- skimage/exposure/setup.py | 6 ++---- ..._with_mask_and_wrap_around_option.c => unwrap_2d_ljmu.c} | 1 + ..._with_mask_and_wrap_around_option.c => unwrap_3d_ljmu.c} | 1 + 4 files changed, 6 insertions(+), 6 deletions(-) rename skimage/exposure/{Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c => unwrap_2d_ljmu.c} (96%) rename skimage/exposure/{Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c => unwrap_3d_ljmu.c} (99%) diff --git a/bento.info b/bento.info index 7be7bbd3..e8ae3b07 100644 --- a/bento.info +++ b/bento.info @@ -146,10 +146,10 @@ Library: skimage/filter/rank/bilateral_cy.pyx Extension: skimage.exposure._unwrap_3d Sources: - skimage/exposure/_unwrap_3d.pyx, skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c + skimage/exposure/_unwrap_3d.pyx, skimage/exposure/unwrap_3d_ljmu.c Extension: skimage.exposure._unwrap_2d Sources: - skimage/exposure/_unwrap_2d.pyx, skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c + skimage/exposure/_unwrap_2d.pyx, skimage/exposure/unwrap_2d_ljmu.c Executable: skivi Module: skimage.scripts.skivi diff --git a/skimage/exposure/setup.py b/skimage/exposure/setup.py index ed1515fe..d21f41f0 100644 --- a/skimage/exposure/setup.py +++ b/skimage/exposure/setup.py @@ -16,13 +16,11 @@ def configuration(parent_package='', top_path=None): cython(['_unwrap_2d.pyx'], working_path=base_path) cython(['_unwrap_3d.pyx'], working_path=base_path) - unwrap_sources_2d = ['_unwrap_2d.c', - 'Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c'] + unwrap_sources_2d = ['_unwrap_2d.c', 'unwrap_2d_ljmu.c'] config.add_extension('_unwrap_2d', sources=unwrap_sources_2d, extra_compile_args=['-g'], include_dirs=[get_numpy_include_dirs()]) - unwrap_sources_3d = ['_unwrap_3d.c', - 'Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c'] + unwrap_sources_3d = ['_unwrap_3d.c', 'unwrap_3d_ljmu.c'] config.add_extension('_unwrap_3d', sources=unwrap_sources_3d, extra_compile_args=['-g'], include_dirs=[get_numpy_include_dirs()]) diff --git a/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c b/skimage/exposure/unwrap_2d_ljmu.c similarity index 96% rename from skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c rename to skimage/exposure/unwrap_2d_ljmu.c index e6249062..7ffcbeef 100644 --- a/skimage/exposure/Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c +++ b/skimage/exposure/unwrap_2d_ljmu.c @@ -1,4 +1,5 @@ // 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer +// Original file name: Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c //This program was written by Munther Gdeisat and Miguel Arevallilo Herraez to program the two-dimensional unwrapper //entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by diff --git a/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c b/skimage/exposure/unwrap_3d_ljmu.c similarity index 99% rename from skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c rename to skimage/exposure/unwrap_3d_ljmu.c index 7c203465..b8a44a73 100644 --- a/skimage/exposure/Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c +++ b/skimage/exposure/unwrap_3d_ljmu.c @@ -1,4 +1,5 @@ // 3D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer +// Original file name: Hussein_3D_unwrapper_with_mask_and_wrap_around_option.c //This program was written by Hussein Abdul-Rahman and Munther Gdeisat to program the three-dimensional phase unwrapper //entitled "Fast three-dimensional phase-unwrapping algorithm based on sorting by From f53a4e0764583a4f0f074efb466db4cf242b204c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 12:40:52 +0200 Subject: [PATCH 69/84] unwrap: Add naive 1D unwrapper. The naive 1D unwrapper does not support masked arrays because the 1D unwrapping problem has an infite number of solutions when faced with missing data. Wrap around is not implemented because 1D phase unwrapping must start at a certain pixel, and there will always be a risk of a discontinuity there, wrap around or not. --- bento.info | 3 +++ skimage/exposure/_unwrap_1d.pyx | 22 ++++++++++++++++++ skimage/exposure/setup.py | 3 +++ skimage/exposure/tests/test_unwrap.py | 12 +++++++++- skimage/exposure/unwrap.py | 33 ++++++++++++++++++++------- 5 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 skimage/exposure/_unwrap_1d.pyx diff --git a/bento.info b/bento.info index e8ae3b07..30367057 100644 --- a/bento.info +++ b/bento.info @@ -150,6 +150,9 @@ Library: Extension: skimage.exposure._unwrap_2d Sources: skimage/exposure/_unwrap_2d.pyx, skimage/exposure/unwrap_2d_ljmu.c + Extension: skimage.exposure._unwrap_1d + Sources: + skimage/exposure/_unwrap_1d.pyx Executable: skivi Module: skimage.scripts.skivi diff --git a/skimage/exposure/_unwrap_1d.pyx b/skimage/exposure/_unwrap_1d.pyx new file mode 100644 index 00000000..d39f9e57 --- /dev/null +++ b/skimage/exposure/_unwrap_1d.pyx @@ -0,0 +1,22 @@ +#cython: cdivision=True +#cython: boundscheck=False +#cython: nonecheck=False +#cython: wraparound=False + +from libc.math cimport M_PI + + +def unwrap_1d(float[::1] image, float[::1] unwrapped_image): + '''Phase unwrapping using the naive approach.''' + cdef: + Py_ssize_t i + float difference + long periods = 0 + unwrapped_image[0] = image[0] + for i in range(1, image.shape[0]): + difference = image[i] - image[i - 1] + if difference > M_PI: + periods -= 1 + elif difference < -M_PI: + periods += 1 + unwrapped_image[i] = image[i] + 2 * M_PI * periods diff --git a/skimage/exposure/setup.py b/skimage/exposure/setup.py index d21f41f0..1e801088 100644 --- a/skimage/exposure/setup.py +++ b/skimage/exposure/setup.py @@ -13,9 +13,12 @@ def configuration(parent_package='', top_path=None): config = Configuration('exposure', parent_package, top_path) config.add_data_dir('tests') + cython(['_unwrap_1d.pyx'], working_path=base_path) cython(['_unwrap_2d.pyx'], working_path=base_path) cython(['_unwrap_3d.pyx'], working_path=base_path) + config.add_extension('_unwrap_1d', sources=['_unwrap_1d.c'], + include_dirs=[get_numpy_include_dirs()]) unwrap_sources_2d = ['_unwrap_2d.c', 'unwrap_2d_ljmu.c'] config.add_extension('_unwrap_2d', sources=unwrap_sources_2d, extra_compile_args=['-g'], diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 1e1b0cd5..220bb177 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -2,7 +2,8 @@ from __future__ import print_function, division import numpy as np from numpy.testing import (run_module_suite, assert_array_almost_equal, - assert_almost_equal, assert_array_equal) + assert_almost_equal, assert_array_equal, + assert_raises) import warnings from skimage.exposure import unwrap_phase @@ -40,6 +41,15 @@ def check_unwrap(image, mask=None): assert_phase_almost_equal(image_unwrapped, image) +def test_unwrap_1d(): + image = np.linspace(0, 10 * np.pi, 100) + check_unwrap(image) + # Masked arrays are not allowed in 1D + assert_raises(ValueError, check_unwrap, image, True) + # wrap_around is not allowed in 1D + assert_raises(ValueError, unwrap_phase, image, True) + + def test_unwrap_2d(): x, y = np.ogrid[:8, :16] image = 2 * np.pi * (x * 0.2 + y * 0.1) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index a38162bd..a2a8c42a 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -1,6 +1,7 @@ import numpy as np import warnings +from ._unwrap_1d import unwrap_1d from ._unwrap_2d import unwrap_2d from ._unwrap_3d import unwrap_3d from .._shared.six import string_types @@ -12,16 +13,18 @@ def unwrap_phase(image, wrap_around=False): Parameters ---------- - image : 2D or 3D ndarray of floats, optionally a masked array + image : 1D, 2D or 3D ndarray of floats, optionally a masked array The values should be in the range ``[-pi, pi)``. If a masked array is provided, the masked entries will not be changed, and their values will not be used to guide the unwrapping of neighboring, unmasked - values. + values. Masked 1D arrays are not allowed, and will raise a + ``ValueError``. wrap_around : bool or sequence of bool When an element of the sequence is ``True``, the unwrapping process will regard the edges along the corresponding axis of the image to be connected and use this connectivity to guide the phase unwrapping process. If only a single boolean is given, it will apply to all axes. + Wrap around is not supported for 1D arrays. Returns ------- @@ -29,6 +32,12 @@ def unwrap_phase(image, wrap_around=False): Unwrapped image of the same shape as the input. If the input ``image`` was a masked array, the mask will be preserved. + Raises + ------ + ValueError + If called with a masked 1D array or called with a 1D array and + ``wrap_around=True``. + Examples -------- >>> c0, c1 = np.ogrid[-1:1:128j, -1:1:128j] @@ -50,8 +59,8 @@ def unwrap_phase(image, wrap_around=False): C. Gorecki, & E. L. Novak (Eds.), Optical Metrology (2005) 32--40, International Society for Optics and Photonics. ''' - if image.ndim not in (2, 3): - raise ValueError('image must be 2 or 3 dimensional') + if image.ndim not in (1, 2, 3): + raise ValueError('image must be 1, 2 or 3 dimensional') if isinstance(wrap_around, bool): wrap_around = [wrap_around] * image.ndim elif (hasattr(wrap_around, '__getitem__') @@ -63,9 +72,15 @@ def unwrap_phase(image, wrap_around=False): else: raise ValueError('wrap_around must be a bool or a sequence with ' 'length equal to the dimensionality of image') - if image.ndim == 3 and 1 in image.shape: - warnings.warn('image is 3D and has a length 1 dimension; consider ' - 'using a 2D array to use the 2D unwrapping algorithm') + if image.ndim == 1: + if np.ma.isMaskedArray(image): + raise ValueError('1D masked images cannot be unwrapped') + if wrap_around[0]: + raise ValueError('wrap_around is not supported for 1D images') + if image.ndim in (2, 3) and 1 in image.shape: + warnings.warn('image has a length 1 dimension; consider using an ' + 'array of lower dimensionality to use a more efficient ' + 'algorithm') if np.ma.isMaskedArray(image): mask = np.require(image.mask, np.uint8, ['C']) @@ -74,7 +89,9 @@ def unwrap_phase(image, wrap_around=False): image_not_masked = np.asarray(image, dtype=np.float32, order='C') image_unwrapped = np.empty_like(image, dtype=np.float32, order='C') - if image.ndim == 2: + if image.ndim == 1: + unwrap_1d(image_not_masked, image_unwrapped) + elif image.ndim == 2: unwrap_2d(image_not_masked, mask, image_unwrapped, wrap_around) elif image.ndim == 3: From a6e7bd4a00afba5aba43d937facc22bc5c7c6f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 12:49:27 +0200 Subject: [PATCH 70/84] unwrap: Use constants from math.h in C code. --- skimage/exposure/unwrap_2d_ljmu.c | 7 ++++--- skimage/exposure/unwrap_3d_ljmu.c | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/skimage/exposure/unwrap_2d_ljmu.c b/skimage/exposure/unwrap_2d_ljmu.c index 7ffcbeef..abc66451 100644 --- a/skimage/exposure/unwrap_2d_ljmu.c +++ b/skimage/exposure/unwrap_2d_ljmu.c @@ -17,13 +17,14 @@ #include #include #include +#include + +#define PI M_PI +#define TWOPI (2 * M_PI) //TODO: remove global variables //TODO: make thresholds independent -static float PI = 3.141592654f; -static float TWOPI = 6.283185307f; - #define NOMASK 0 #define MASK 1 diff --git a/skimage/exposure/unwrap_3d_ljmu.c b/skimage/exposure/unwrap_3d_ljmu.c index b8a44a73..99800410 100644 --- a/skimage/exposure/unwrap_3d_ljmu.c +++ b/skimage/exposure/unwrap_3d_ljmu.c @@ -19,9 +19,10 @@ #include #include #include +#include -static float PI = 3.141592654f; -static float TWOPI = 6.283185307f; +#define PI M_PI +#define TWOPI (2 * M_PI) #define NOMASK 0 #define MASK 1 From ebf457cea82dfb4765fc5377f2b2ed83d8484beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 13:00:49 +0200 Subject: [PATCH 71/84] unwrap: Convert 2D C code from float to double. --- skimage/exposure/unwrap_2d_ljmu.c | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/skimage/exposure/unwrap_2d_ljmu.c b/skimage/exposure/unwrap_2d_ljmu.c index abc66451..285fca3d 100644 --- a/skimage/exposure/unwrap_2d_ljmu.c +++ b/skimage/exposure/unwrap_2d_ljmu.c @@ -30,7 +30,7 @@ typedef struct { - float mod; + double mod; int x_connectivity; int y_connectivity; int no_of_edges; @@ -41,8 +41,8 @@ struct PIXELM { int increment; //No. of 2*pi to add to the pixel to unwrap it int number_of_pixels_in_group;//No. of pixel in the pixel group - float value; //value of the pixel - float reliability; + double value; //value of the pixel + double reliability; unsigned char input_mask; //0 pixel is masked. NOMASK pixel is not masked unsigned char extended_mask; //0 pixel is masked. NOMASK pixel is not masked int group; //group No. @@ -58,7 +58,7 @@ typedef struct PIXELM PIXELM; //if we have S pixels, then we have S horizontal edges and S vertical edges struct EDGE { - float reliab; //reliabilty of the edge and it depends on the two pixels + double reliab; //reliabilty of the edge and it depends on the two pixels PIXELM *pointer_1; //pointer to the first pixel PIXELM *pointer_2; //pointer to the second pixel int increment; //No. of 2*pi to add to one of the pixels to @@ -75,7 +75,7 @@ typedef struct EDGE EDGE; typedef enum {yes, no} yes_no; -yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) +yes_no find_pivot(EDGE *left, EDGE *right, double *pivot_ptr) { EDGE a, b, c, *p; @@ -107,7 +107,7 @@ yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) } } -EDGE *partition(EDGE *left, EDGE *right, float pivot) +EDGE *partition(EDGE *left, EDGE *right, double pivot) { while (left <= right) { @@ -128,7 +128,7 @@ EDGE *partition(EDGE *left, EDGE *right, float pivot) void quicker_sort(EDGE *left, EDGE *right) { EDGE *p; - float pivot; + double pivot; if (find_pivot(left, right, &pivot) == yes) { @@ -142,10 +142,10 @@ void quicker_sort(EDGE *left, EDGE *right) //--------------------start initialize pixels ---------------------------------- //initialize pixels. See the explination of the pixel class above. //initially every pixel is assumed to belong to a group consisting of only itself -void initialisePIXELs(float *wrapped_image, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) +void initialisePIXELs(double *wrapped_image, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) { PIXELM *pixel_pointer = pixel; - float *wrapped_image_pointer = wrapped_image; + double *wrapped_image_pointer = wrapped_image; unsigned char *input_mask_pointer = input_mask; unsigned char *extended_mask_pointer = extended_mask; int i, j; @@ -157,7 +157,7 @@ void initialisePIXELs(float *wrapped_image, unsigned char *input_mask, unsigned pixel_pointer->increment = 0; pixel_pointer->number_of_pixels_in_group = 1; pixel_pointer->value = *wrapped_image_pointer; - pixel_pointer->reliability = 9999999.f + rand(); + pixel_pointer->reliability = 9999999. + rand(); pixel_pointer->input_mask = *input_mask_pointer; pixel_pointer->extended_mask = *extended_mask_pointer; pixel_pointer->head = pixel_pointer; @@ -175,9 +175,9 @@ void initialisePIXELs(float *wrapped_image, unsigned char *input_mask, unsigned //-------------------end initialize pixels ----------- //gamma function in the paper -float wrap(float pixel_value) +double wrap(double pixel_value) { - float wrapped_pixel_value; + double wrapped_pixel_value; if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; else wrapped_pixel_value = pixel_value; @@ -185,9 +185,9 @@ float wrap(float pixel_value) } // pixelL_value is the left pixel, pixelR_value is the right pixel -int find_wrap(float pixelL_value, float pixelR_value) +int find_wrap(double pixelL_value, double pixelR_value) { - float difference; + double difference; int wrap_value; difference = pixelL_value - pixelR_value; @@ -299,15 +299,15 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, } } -void calculate_reliability(float *wrappedImage, PIXELM *pixel, +void calculate_reliability(double *wrappedImage, PIXELM *pixel, int image_width, int image_height, params_t *params) { int image_width_plus_one = image_width + 1; int image_width_minus_one = image_width - 1; PIXELM *pixel_pointer = pixel + image_width_plus_one; - float *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer - float H, V, D1, D2; + double *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer + double H, V, D1, D2; int i, j; for (i = 1; i < image_height -1; ++i) @@ -333,7 +333,7 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, { //calculating the reliability for the left border of the image PIXELM *pixel_pointer = pixel + image_width; - float *WIP = wrappedImage + image_width; + double *WIP = wrappedImage + image_width; for (i = 1; i < image_height - 1; ++i) { @@ -372,7 +372,7 @@ void calculate_reliability(float *wrappedImage, PIXELM *pixel, { //calculating the reliability for the top border of the image PIXELM *pixel_pointer = pixel + 1; - float *WIP = wrappedImage + 1; + double *WIP = wrappedImage + 1; for (i = 1; i < image_width - 1; ++i) { @@ -618,7 +618,7 @@ void unwrapImage(PIXELM *pixel, int image_width, int image_height) for (i = 0; i < image_size; i++) { - pixel_pointer->value += TWOPI * (float)(pixel_pointer->increment); + pixel_pointer->value += TWOPI * (double)(pixel_pointer->increment); pixel_pointer++; } } @@ -633,7 +633,7 @@ void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int i PIXELM *pointer_pixel = pixel; unsigned char *IMP = input_mask; //input mask pointer - float min=99999999.f; + double min=99999999; int i; int image_size = image_width * image_height; @@ -666,11 +666,11 @@ void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int i //phase map. copy the image on the buffer passed to this unwrapper to //over-write the unwrapped phase map on the buffer of the wrapped //phase map. -void returnImage(PIXELM *pixel, float *unwrapped_image, int image_width, int image_height) +void returnImage(PIXELM *pixel, double *unwrapped_image, int image_width, int image_height) { int i; int image_size = image_width * image_height; - float *unwrapped_image_pointer = unwrapped_image; + double *unwrapped_image_pointer = unwrapped_image; PIXELM *pixel_pointer = pixel; for (i=0; i < image_size; i++) @@ -683,7 +683,7 @@ void returnImage(PIXELM *pixel, float *unwrapped_image, int image_width, int im //the main function of the unwrapper void -unwrap2D(float* wrapped_image, float* UnwrappedImage, unsigned char* input_mask, +unwrap2D(double* wrapped_image, double* UnwrappedImage, unsigned char* input_mask, int image_width, int image_height, int wrap_around_x, int wrap_around_y) { From 9bacb0d54a4dcef760923bb340ac7386e6fd45c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 13:02:14 +0200 Subject: [PATCH 72/84] unwrap: Use UNIX line endings. --- skimage/exposure/unwrap_2d_ljmu.c | 1450 ++++++++++++++--------------- 1 file changed, 725 insertions(+), 725 deletions(-) diff --git a/skimage/exposure/unwrap_2d_ljmu.c b/skimage/exposure/unwrap_2d_ljmu.c index 285fca3d..6be7966a 100644 --- a/skimage/exposure/unwrap_2d_ljmu.c +++ b/skimage/exposure/unwrap_2d_ljmu.c @@ -1,725 +1,725 @@ -// 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer -// Original file name: Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c - -//This program was written by Munther Gdeisat and Miguel Arevallilo Herraez to program the two-dimensional unwrapper -//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by -//reliability following a noncontinuous path" -//by Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat -//published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. -//This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. -//Date 26th August 2007 -//The wrapped phase map is assumed to be of floating point data type. The resultant unwrapped phase map is also of floating point type. -//The mask is of byte data type. -//When the mask is 255 this means that the pixel is valid -//When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) -//This program takes into consideration the image wrap around problem encountered in MRI imaging. - -#include -#include -#include -#include - -#define PI M_PI -#define TWOPI (2 * M_PI) - -//TODO: remove global variables -//TODO: make thresholds independent - -#define NOMASK 0 -#define MASK 1 - -typedef struct -{ - double mod; - int x_connectivity; - int y_connectivity; - int no_of_edges; -} params_t; - -//PIXELM information -struct PIXELM -{ - int increment; //No. of 2*pi to add to the pixel to unwrap it - int number_of_pixels_in_group;//No. of pixel in the pixel group - double value; //value of the pixel - double reliability; - unsigned char input_mask; //0 pixel is masked. NOMASK pixel is not masked - unsigned char extended_mask; //0 pixel is masked. NOMASK pixel is not masked - int group; //group No. - int new_group; - struct PIXELM *head; //pointer to the first pixel in the group in the linked list - struct PIXELM *last; //pointer to the last pixel in the group - struct PIXELM *next; //pointer to the next pixel in the group -}; - -typedef struct PIXELM PIXELM; - -//the EDGE is the line that connects two pixels. -//if we have S pixels, then we have S horizontal edges and S vertical edges -struct EDGE -{ - double reliab; //reliabilty of the edge and it depends on the two pixels - PIXELM *pointer_1; //pointer to the first pixel - PIXELM *pointer_2; //pointer to the second pixel - int increment; //No. of 2*pi to add to one of the pixels to - //unwrap it with respect to the second -}; - -typedef struct EDGE EDGE; - -//---------------start quicker_sort algorithm -------------------------------- -#define swap(x,y) {EDGE t; t=x; x=y; y=t;} -#define order(x,y) if (x.reliab > y.reliab) swap(x,y) -#define o2(x,y) order(x,y) -#define o3(x,y,z) o2(x,y); o2(x,z); o2(y,z) - -typedef enum {yes, no} yes_no; - -yes_no find_pivot(EDGE *left, EDGE *right, double *pivot_ptr) -{ - EDGE a, b, c, *p; - - a = *left; - b = *(left + (right - left) /2 ); - c = *right; - o3(a,b,c); - - if (a.reliab < b.reliab) - { - *pivot_ptr = b.reliab; - return yes; - } - - if (b.reliab < c.reliab) - { - *pivot_ptr = c.reliab; - return yes; - } - - for (p = left + 1; p <= right; ++p) - { - if (p->reliab != left->reliab) - { - *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; - return yes; - } - return no; - } -} - -EDGE *partition(EDGE *left, EDGE *right, double pivot) -{ - while (left <= right) - { - while (left->reliab < pivot) - ++left; - while (right->reliab >= pivot) - --right; - if (left < right) - { - swap (*left, *right); - ++left; - --right; - } - } - return left; -} - -void quicker_sort(EDGE *left, EDGE *right) -{ - EDGE *p; - double pivot; - - if (find_pivot(left, right, &pivot) == yes) - { - p = partition(left, right, pivot); - quicker_sort(left, p - 1); - quicker_sort(p, right); - } -} -//--------------end quicker_sort algorithm ----------------------------------- - -//--------------------start initialize pixels ---------------------------------- -//initialize pixels. See the explination of the pixel class above. -//initially every pixel is assumed to belong to a group consisting of only itself -void initialisePIXELs(double *wrapped_image, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) -{ - PIXELM *pixel_pointer = pixel; - double *wrapped_image_pointer = wrapped_image; - unsigned char *input_mask_pointer = input_mask; - unsigned char *extended_mask_pointer = extended_mask; - int i, j; - - for (i=0; i < image_height; i++) - { - for (j=0; j < image_width; j++) - { - pixel_pointer->increment = 0; - pixel_pointer->number_of_pixels_in_group = 1; - pixel_pointer->value = *wrapped_image_pointer; - pixel_pointer->reliability = 9999999. + rand(); - pixel_pointer->input_mask = *input_mask_pointer; - pixel_pointer->extended_mask = *extended_mask_pointer; - pixel_pointer->head = pixel_pointer; - pixel_pointer->last = pixel_pointer; - pixel_pointer->next = NULL; - pixel_pointer->new_group = 0; - pixel_pointer->group = -1; - pixel_pointer++; - wrapped_image_pointer++; - input_mask_pointer++; - extended_mask_pointer++; - } - } -} -//-------------------end initialize pixels ----------- - -//gamma function in the paper -double wrap(double pixel_value) -{ - double wrapped_pixel_value; - if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; - else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; - else wrapped_pixel_value = pixel_value; - return wrapped_pixel_value; -} - -// pixelL_value is the left pixel, pixelR_value is the right pixel -int find_wrap(double pixelL_value, double pixelR_value) -{ - double difference; - int wrap_value; - difference = pixelL_value - pixelR_value; - - if (difference > PI) wrap_value = -1; - else if (difference < -PI) wrap_value = 1; - else wrap_value = 0; - - return wrap_value; -} - -void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, - int image_width, int image_height, - params_t *params) -{ - int i,j; - int image_width_plus_one = image_width + 1; - int image_width_minus_one = image_width - 1; - unsigned char *IMP = input_mask + image_width + 1; //input mask pointer - unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer - - //extend the mask for the image except borders - for (i=1; i < image_height - 1; ++i) - { - for (j=1; j < image_width - 1; ++j) - { - if ( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && - (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && - (*(IMP - image_width_minus_one) == NOMASK) && (*(IMP - image_width_plus_one) == NOMASK) && - (*(IMP + image_width_minus_one) == NOMASK) && (*(IMP + image_width_plus_one) == NOMASK) ) - { - *EMP = NOMASK; - } - ++EMP; - ++IMP; - } - EMP += 2; - IMP += 2; - } - - if (params->x_connectivity == 1) - { - //extend the mask for the right border of the image - IMP = input_mask + 2 * image_width - 1; - EMP = extended_mask + 2 * image_width -1; - for (i=1; i < image_height - 1; ++ i) - { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && - (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && - (*(IMP + image_width - 1) == NOMASK) && (*(IMP - 2 * image_width + 1) == NOMASK) ) - { - *EMP = NOMASK; - } - EMP += image_width; - IMP += image_width; - } - - //extend the mask for the left border of the image - IMP = input_mask + image_width; - EMP = extended_mask + image_width; - for (i=1; i < image_height - 1; ++i) - { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && - (*(IMP - image_width + 1) == NOMASK) && (*(IMP + image_width + 1) == NOMASK) && - (*(IMP + image_width - 1) == NOMASK) && (*(IMP + 2 * image_width - 1) == NOMASK) ) - { - *EMP = NOMASK; - } - EMP += image_width; - IMP += image_width; - } - } - - if (params->y_connectivity == 1) - { - //extend the mask for the top border of the image - IMP = input_mask + 1; - EMP = extended_mask + 1; - for (i=1; i < image_width - 1; ++i) - { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP + image_width) == NOMASK) && (*(IMP + image_width * (image_height - 1)) == NOMASK) && - (*(IMP + image_width + 1) == NOMASK) && (*(IMP + image_width - 1) == NOMASK) && - (*(IMP + image_width * (image_height - 1) - 1) == NOMASK) && (*(IMP + image_width * (image_height - 1) + 1) == NOMASK) ) - { - *EMP = NOMASK; - } - EMP++; - IMP++; - } - - //extend the mask for the bottom border of the image - IMP = input_mask + image_width * (image_height - 1) + 1; - EMP = extended_mask + image_width * (image_height - 1) + 1; - for (i=1; i < image_width - 1; ++i) - { - if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && - (*(IMP - image_width) == NOMASK) && (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && - (*(IMP - image_width * (image_height - 1) ) == NOMASK) && - (*(IMP - image_width * (image_height - 1) - 1) == NOMASK) && - (*(IMP - image_width * (image_height - 1) + 1) == NOMASK) ) - { - *EMP = NOMASK; - } - EMP++; - IMP++; - } - } -} - -void calculate_reliability(double *wrappedImage, PIXELM *pixel, - int image_width, int image_height, - params_t *params) -{ - int image_width_plus_one = image_width + 1; - int image_width_minus_one = image_width - 1; - PIXELM *pixel_pointer = pixel + image_width_plus_one; - double *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer - double H, V, D1, D2; - int i, j; - - for (i = 1; i < image_height -1; ++i) - { - for (j = 1; j < image_width - 1; ++j) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - pixel_pointer += 2; - WIP += 2; - } - - if (params->x_connectivity == 1) - { - //calculating the reliability for the left border of the image - PIXELM *pixel_pointer = pixel + image_width; - double *WIP = wrappedImage + image_width; - - for (i = 1; i < image_height - 1; ++i) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer += image_width; - WIP += image_width; - } - - //calculating the reliability for the right border of the image - pixel_pointer = pixel + 2 * image_width - 1; - WIP = wrappedImage + 2 * image_width - 1; - - for (i = 1; i < image_height - 1; ++i) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); - D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer += image_width; - WIP += image_width; - } - } - - if (params->y_connectivity == 1) - { - //calculating the reliability for the top border of the image - PIXELM *pixel_pointer = pixel + 1; - double *WIP = wrappedImage + 1; - - for (i = 1; i < image_width - 1; ++i) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); - D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); - D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - - //calculating the reliability for the bottom border of the image - pixel_pointer = pixel + (image_height - 1) * image_width + 1; - WIP = wrappedImage + (image_height - 1) * image_width + 1; - - for (i = 1; i < image_width - 1; ++i) - { - if (pixel_pointer->extended_mask == NOMASK) - { - H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); - V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); - D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); - D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); - pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; - } - pixel_pointer++; - WIP++; - } - } -} - -//calculate the reliability of the horizontal edges of the image -//it is calculated by adding the reliability of pixel and the relibility of -//its right-hand neighbour -//edge is calculated between a pixel and its next neighbour -void horizontalEDGEs(PIXELM *pixel, EDGE *edge, - int image_width, int image_height, - params_t *params) -{ - int i, j; - EDGE *edge_pointer = edge; - PIXELM *pixel_pointer = pixel; - int no_of_edges = params->no_of_edges; - - for (i = 0; i < image_height; i++) - { - for (j = 0; j < image_width - 1; j++) - { - if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + 1)->input_mask == NOMASK) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer+1); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); - edge_pointer++; - no_of_edges++; - } - pixel_pointer++; - } - pixel_pointer++; - } - //construct edges at the right border of the image - if (params->x_connectivity == 1) - { - pixel_pointer = pixel + image_width - 1; - for (i = 0; i < image_height; i++) - { - if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width + 1)->input_mask == NOMASK) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); - edge_pointer++; - no_of_edges++; - } - pixel_pointer+=image_width; - } - } - params->no_of_edges = no_of_edges; -} - -//calculate the reliability of the vertical edges of the image -//it is calculated by adding the reliability of pixel and the relibility of -//its lower neighbour in the image. -void verticalEDGEs(PIXELM *pixel, EDGE *edge, - int image_width, int image_height, - params_t *params) -{ - int i, j; - int no_of_edges = params->no_of_edges; - PIXELM *pixel_pointer = pixel; - EDGE *edge_pointer = edge + no_of_edges; - - for (i=0; i < image_height - 1; i++) - { - for (j=0; j < image_width; j++) - { - if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + image_width)->input_mask == NOMASK) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer + image_width); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); - edge_pointer++; - no_of_edges++; - } - pixel_pointer++; - } //j loop - } // i loop - - //construct edges that connect at the bottom border of the image - if (params->y_connectivity == 1) - { - pixel_pointer = pixel + image_width *(image_height - 1); - for (i = 0; i < image_width; i++) - { - if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width *(image_height - 1))->input_mask == NOMASK) - { - edge_pointer->pointer_1 = pixel_pointer; - edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); - edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; - edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); - edge_pointer++; - no_of_edges++; - } - pixel_pointer++; - } - } - params->no_of_edges = no_of_edges; -} - -//gather the pixels of the image into groups -void gatherPIXELs(EDGE *edge, params_t *params) -{ - int k; - PIXELM *PIXEL1; - PIXELM *PIXEL2; - PIXELM *group1; - PIXELM *group2; - EDGE *pointer_edge = edge; - int incremento; - - for (k = 0; k < params->no_of_edges; k++) - { - PIXEL1 = pointer_edge->pointer_1; - PIXEL2 = pointer_edge->pointer_2; - - //PIXELM 1 and PIXELM 2 belong to different groups - //initially each pixel is a group by it self and one pixel can construct a group - //no else or else if to this if - if (PIXEL2->head != PIXEL1->head) - { - //PIXELM 2 is alone in its group - //merge this pixel with PIXELM 1 group and find the number of 2 pi to add - //to or subtract to unwrap it - if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) - { - PIXEL1->head->last->next = PIXEL2; - PIXEL1->head->last = PIXEL2; - (PIXEL1->head->number_of_pixels_in_group)++; - PIXEL2->head=PIXEL1->head; - PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; - } - - //PIXELM 1 is alone in its group - //merge this pixel with PIXELM 2 group and find the number of 2 pi to add - //to or subtract to unwrap it - else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) - { - PIXEL2->head->last->next = PIXEL1; - PIXEL2->head->last = PIXEL1; - (PIXEL2->head->number_of_pixels_in_group)++; - PIXEL1->head = PIXEL2->head; - PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; - } - - //PIXELM 1 and PIXELM 2 both have groups - else - { - group1 = PIXEL1->head; - group2 = PIXEL2->head; - //if the no. of pixels in PIXELM 1 group is larger than the - //no. of pixels in PIXELM 2 group. Merge PIXELM 2 group to - //PIXELM 1 group and find the number of wraps between PIXELM 2 - //group and PIXELM 1 group to unwrap PIXELM 2 group with respect - //to PIXELM 1 group. the no. of wraps will be added to PIXELM 2 - //group in the future - if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) - { - //merge PIXELM 2 with PIXELM 1 group - group1->last->next = group2; - group1->last = group2->last; - group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; - incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; - //merge the other pixels in PIXELM 2 group to PIXELM 1 group - while (group2 != NULL) - { - group2->head = group1; - group2->increment += incremento; - group2 = group2->next; - } - } - - //if the no. of pixels in PIXELM 2 group is larger than the - //no. of pixels in PIXELM 1 group. Merge PIXELM 1 group to - //PIXELM 2 group and find the number of wraps between PIXELM 2 - //group and PIXELM 1 group to unwrap PIXELM 1 group with respect - //to PIXELM 2 group. the no. of wraps will be added to PIXELM 1 - //group in the future - else - { - //merge PIXELM 1 with PIXELM 2 group - group2->last->next = group1; - group2->last = group1->last; - group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; - incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; - //merge the other pixels in PIXELM 2 group to PIXELM 1 group - while (group1 != NULL) - { - group1->head = group2; - group1->increment += incremento; - group1 = group1->next; - } // while - - } // else - } //else - } //if - pointer_edge++; - } -} - -//unwrap the image -void unwrapImage(PIXELM *pixel, int image_width, int image_height) -{ - int i; - int image_size = image_width * image_height; - PIXELM *pixel_pointer=pixel; - - for (i = 0; i < image_size; i++) - { - pixel_pointer->value += TWOPI * (double)(pixel_pointer->increment); - pixel_pointer++; - } -} - -//set the masked pixels (mask = 0) to the minimum of the unwrapper phase -void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int image_height) -{ - int image_width_plus_one = image_width + 1; - int image_height_plus_one = image_height + 1; - int image_width_minus_one = image_width - 1; - int image_height_minus_one = image_height - 1; - - PIXELM *pointer_pixel = pixel; - unsigned char *IMP = input_mask; //input mask pointer - double min=99999999; - int i; - int image_size = image_width * image_height; - - //find the minimum of the unwrapped phase - for (i = 0; i < image_size; i++) - { - if ((pointer_pixel->value < min) && (*IMP == NOMASK)) - min = pointer_pixel->value; - - pointer_pixel++; - IMP++; - } - - pointer_pixel = pixel; - IMP = input_mask; - - //set the masked pixels to minimum - for (i = 0; i < image_size; i++) - { - if ((*IMP) == MASK) - { - pointer_pixel->value = min; - } - pointer_pixel++; - IMP++; - } -} - -//the input to this unwrapper is an array that contains the wrapped -//phase map. copy the image on the buffer passed to this unwrapper to -//over-write the unwrapped phase map on the buffer of the wrapped -//phase map. -void returnImage(PIXELM *pixel, double *unwrapped_image, int image_width, int image_height) -{ - int i; - int image_size = image_width * image_height; - double *unwrapped_image_pointer = unwrapped_image; - PIXELM *pixel_pointer = pixel; - - for (i=0; i < image_size; i++) - { - *unwrapped_image_pointer = pixel_pointer->value; - pixel_pointer++; - unwrapped_image_pointer++; - } -} - -//the main function of the unwrapper -void -unwrap2D(double* wrapped_image, double* UnwrappedImage, unsigned char* input_mask, - int image_width, int image_height, - int wrap_around_x, int wrap_around_y) -{ - params_t params = {TWOPI, wrap_around_x, wrap_around_y, 0}; - unsigned char *extended_mask; - PIXELM *pixel; - EDGE *edge; - int image_size = image_height * image_width; - int No_of_Edges_initially = 2 * image_width * image_height; - - extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); - pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); - edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE)); - - extend_mask(input_mask, extended_mask, image_width, image_height, ¶ms); - initialisePIXELs(wrapped_image, input_mask, extended_mask, pixel, image_width, image_height); - calculate_reliability(wrapped_image, pixel, image_width, image_height, ¶ms); - horizontalEDGEs(pixel, edge, image_width, image_height, ¶ms); - verticalEDGEs(pixel, edge, image_width, image_height, ¶ms); - - //sort the EDGEs depending on their reiability. The PIXELs with higher - //relibility (small value) first - quicker_sort(edge, edge + params.no_of_edges - 1); - - //gather PIXELs into groups - gatherPIXELs(edge, ¶ms); - - unwrapImage(pixel, image_width, image_height); - maskImage(pixel, input_mask, image_width, image_height); - - //copy the image from PIXELM structure to the unwrapped phase array - //passed to this function - //TODO: replace by (cython?) function to directly write into numpy array ? - returnImage(pixel, UnwrappedImage, image_width, image_height); - - free(edge); - free(pixel); - free(extended_mask); -} +// 2D phase unwrapping, modified for inclusion in scipy by Gregor Thalhammer +// Original file name: Miguel_2D_unwrapper_with_mask_and_wrap_around_option.c + +//This program was written by Munther Gdeisat and Miguel Arevallilo Herraez to program the two-dimensional unwrapper +//entitled "Fast two-dimensional phase-unwrapping algorithm based on sorting by +//reliability following a noncontinuous path" +//by Miguel Arevallilo Herraez, David R. Burton, Michael J. Lalor, and Munther A. Gdeisat +//published in the Journal Applied Optics, Vol. 41, No. 35, pp. 7437, 2002. +//This program was written by Munther Gdeisat, Liverpool John Moores University, United Kingdom. +//Date 26th August 2007 +//The wrapped phase map is assumed to be of floating point data type. The resultant unwrapped phase map is also of floating point type. +//The mask is of byte data type. +//When the mask is 255 this means that the pixel is valid +//When the mask is 0 this means that the pixel is invalid (noisy or corrupted pixel) +//This program takes into consideration the image wrap around problem encountered in MRI imaging. + +#include +#include +#include +#include + +#define PI M_PI +#define TWOPI (2 * M_PI) + +//TODO: remove global variables +//TODO: make thresholds independent + +#define NOMASK 0 +#define MASK 1 + +typedef struct +{ + double mod; + int x_connectivity; + int y_connectivity; + int no_of_edges; +} params_t; + +//PIXELM information +struct PIXELM +{ + int increment; //No. of 2*pi to add to the pixel to unwrap it + int number_of_pixels_in_group;//No. of pixel in the pixel group + double value; //value of the pixel + double reliability; + unsigned char input_mask; //0 pixel is masked. NOMASK pixel is not masked + unsigned char extended_mask; //0 pixel is masked. NOMASK pixel is not masked + int group; //group No. + int new_group; + struct PIXELM *head; //pointer to the first pixel in the group in the linked list + struct PIXELM *last; //pointer to the last pixel in the group + struct PIXELM *next; //pointer to the next pixel in the group +}; + +typedef struct PIXELM PIXELM; + +//the EDGE is the line that connects two pixels. +//if we have S pixels, then we have S horizontal edges and S vertical edges +struct EDGE +{ + double reliab; //reliabilty of the edge and it depends on the two pixels + PIXELM *pointer_1; //pointer to the first pixel + PIXELM *pointer_2; //pointer to the second pixel + int increment; //No. of 2*pi to add to one of the pixels to + //unwrap it with respect to the second +}; + +typedef struct EDGE EDGE; + +//---------------start quicker_sort algorithm -------------------------------- +#define swap(x,y) {EDGE t; t=x; x=y; y=t;} +#define order(x,y) if (x.reliab > y.reliab) swap(x,y) +#define o2(x,y) order(x,y) +#define o3(x,y,z) o2(x,y); o2(x,z); o2(y,z) + +typedef enum {yes, no} yes_no; + +yes_no find_pivot(EDGE *left, EDGE *right, double *pivot_ptr) +{ + EDGE a, b, c, *p; + + a = *left; + b = *(left + (right - left) /2 ); + c = *right; + o3(a,b,c); + + if (a.reliab < b.reliab) + { + *pivot_ptr = b.reliab; + return yes; + } + + if (b.reliab < c.reliab) + { + *pivot_ptr = c.reliab; + return yes; + } + + for (p = left + 1; p <= right; ++p) + { + if (p->reliab != left->reliab) + { + *pivot_ptr = (p->reliab < left->reliab) ? left->reliab : p->reliab; + return yes; + } + return no; + } +} + +EDGE *partition(EDGE *left, EDGE *right, double pivot) +{ + while (left <= right) + { + while (left->reliab < pivot) + ++left; + while (right->reliab >= pivot) + --right; + if (left < right) + { + swap (*left, *right); + ++left; + --right; + } + } + return left; +} + +void quicker_sort(EDGE *left, EDGE *right) +{ + EDGE *p; + double pivot; + + if (find_pivot(left, right, &pivot) == yes) + { + p = partition(left, right, pivot); + quicker_sort(left, p - 1); + quicker_sort(p, right); + } +} +//--------------end quicker_sort algorithm ----------------------------------- + +//--------------------start initialize pixels ---------------------------------- +//initialize pixels. See the explination of the pixel class above. +//initially every pixel is assumed to belong to a group consisting of only itself +void initialisePIXELs(double *wrapped_image, unsigned char *input_mask, unsigned char *extended_mask, PIXELM *pixel, int image_width, int image_height) +{ + PIXELM *pixel_pointer = pixel; + double *wrapped_image_pointer = wrapped_image; + unsigned char *input_mask_pointer = input_mask; + unsigned char *extended_mask_pointer = extended_mask; + int i, j; + + for (i=0; i < image_height; i++) + { + for (j=0; j < image_width; j++) + { + pixel_pointer->increment = 0; + pixel_pointer->number_of_pixels_in_group = 1; + pixel_pointer->value = *wrapped_image_pointer; + pixel_pointer->reliability = 9999999. + rand(); + pixel_pointer->input_mask = *input_mask_pointer; + pixel_pointer->extended_mask = *extended_mask_pointer; + pixel_pointer->head = pixel_pointer; + pixel_pointer->last = pixel_pointer; + pixel_pointer->next = NULL; + pixel_pointer->new_group = 0; + pixel_pointer->group = -1; + pixel_pointer++; + wrapped_image_pointer++; + input_mask_pointer++; + extended_mask_pointer++; + } + } +} +//-------------------end initialize pixels ----------- + +//gamma function in the paper +double wrap(double pixel_value) +{ + double wrapped_pixel_value; + if (pixel_value > PI) wrapped_pixel_value = pixel_value - TWOPI; + else if (pixel_value < -PI) wrapped_pixel_value = pixel_value + TWOPI; + else wrapped_pixel_value = pixel_value; + return wrapped_pixel_value; +} + +// pixelL_value is the left pixel, pixelR_value is the right pixel +int find_wrap(double pixelL_value, double pixelR_value) +{ + double difference; + int wrap_value; + difference = pixelL_value - pixelR_value; + + if (difference > PI) wrap_value = -1; + else if (difference < -PI) wrap_value = 1; + else wrap_value = 0; + + return wrap_value; +} + +void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, + int image_width, int image_height, + params_t *params) +{ + int i,j; + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + unsigned char *IMP = input_mask + image_width + 1; //input mask pointer + unsigned char *EMP = extended_mask + image_width + 1; //extended mask pointer + + //extend the mask for the image except borders + for (i=1; i < image_height - 1; ++i) + { + for (j=1; j < image_width - 1; ++j) + { + if ( (*IMP) == NOMASK && (*(IMP + 1) == NOMASK) && (*(IMP - 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width_minus_one) == NOMASK) && (*(IMP - image_width_plus_one) == NOMASK) && + (*(IMP + image_width_minus_one) == NOMASK) && (*(IMP + image_width_plus_one) == NOMASK) ) + { + *EMP = NOMASK; + } + ++EMP; + ++IMP; + } + EMP += 2; + IMP += 2; + } + + if (params->x_connectivity == 1) + { + //extend the mask for the right border of the image + IMP = input_mask + 2 * image_width - 1; + EMP = extended_mask + 2 * image_width -1; + for (i=1; i < image_height - 1; ++ i) + { + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && + (*(IMP + image_width - 1) == NOMASK) && (*(IMP - 2 * image_width + 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP += image_width; + IMP += image_width; + } + + //extend the mask for the left border of the image + IMP = input_mask + image_width; + EMP = extended_mask + image_width; + for (i=1; i < image_height - 1; ++i) + { + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP - image_width) == NOMASK) && + (*(IMP - image_width + 1) == NOMASK) && (*(IMP + image_width + 1) == NOMASK) && + (*(IMP + image_width - 1) == NOMASK) && (*(IMP + 2 * image_width - 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP += image_width; + IMP += image_width; + } + } + + if (params->y_connectivity == 1) + { + //extend the mask for the top border of the image + IMP = input_mask + 1; + EMP = extended_mask + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP + image_width) == NOMASK) && (*(IMP + image_width * (image_height - 1)) == NOMASK) && + (*(IMP + image_width + 1) == NOMASK) && (*(IMP + image_width - 1) == NOMASK) && + (*(IMP + image_width * (image_height - 1) - 1) == NOMASK) && (*(IMP + image_width * (image_height - 1) + 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP++; + IMP++; + } + + //extend the mask for the bottom border of the image + IMP = input_mask + image_width * (image_height - 1) + 1; + EMP = extended_mask + image_width * (image_height - 1) + 1; + for (i=1; i < image_width - 1; ++i) + { + if ( (*IMP) == NOMASK && (*(IMP - 1) == NOMASK) && (*(IMP + 1) == NOMASK) && + (*(IMP - image_width) == NOMASK) && (*(IMP - image_width - 1) == NOMASK) && (*(IMP - image_width + 1) == NOMASK) && + (*(IMP - image_width * (image_height - 1) ) == NOMASK) && + (*(IMP - image_width * (image_height - 1) - 1) == NOMASK) && + (*(IMP - image_width * (image_height - 1) + 1) == NOMASK) ) + { + *EMP = NOMASK; + } + EMP++; + IMP++; + } + } +} + +void calculate_reliability(double *wrappedImage, PIXELM *pixel, + int image_width, int image_height, + params_t *params) +{ + int image_width_plus_one = image_width + 1; + int image_width_minus_one = image_width - 1; + PIXELM *pixel_pointer = pixel + image_width_plus_one; + double *WIP = wrappedImage + image_width_plus_one; //WIP is the wrapped image pointer + double H, V, D1, D2; + int i, j; + + for (i = 1; i < image_height -1; ++i) + { + for (j = 1; j < image_width - 1; ++j) + { + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + pixel_pointer += 2; + WIP += 2; + } + + if (params->x_connectivity == 1) + { + //calculating the reliability for the left border of the image + PIXELM *pixel_pointer = pixel + image_width; + double *WIP = wrappedImage + image_width; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP + image_width - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP + 2* image_width - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + + //calculating the reliability for the right border of the image + pixel_pointer = pixel + 2 * image_width - 1; + WIP = wrappedImage + 2 * image_width - 1; + + for (i = 1; i < image_height - 1; ++i) + { + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP - image_width_minus_one)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP + 1)); + D2 = wrap(*(WIP - 2 * image_width - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer += image_width; + WIP += image_width; + } + } + + if (params->y_connectivity == 1) + { + //calculating the reliability for the top border of the image + PIXELM *pixel_pointer = pixel + 1; + double *WIP = wrappedImage + 1; + + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP + image_width*(image_height - 1)) - *WIP) - wrap(*WIP - *(WIP + image_width)); + D1 = wrap(*(WIP + image_width*(image_height - 1) - 1) - *WIP) - wrap(*WIP - *(WIP + image_width_plus_one)); + D2 = wrap(*(WIP + image_width*(image_height - 1) + 1) - *WIP) - wrap(*WIP - *(WIP + image_width_minus_one)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + + //calculating the reliability for the bottom border of the image + pixel_pointer = pixel + (image_height - 1) * image_width + 1; + WIP = wrappedImage + (image_height - 1) * image_width + 1; + + for (i = 1; i < image_width - 1; ++i) + { + if (pixel_pointer->extended_mask == NOMASK) + { + H = wrap(*(WIP - 1) - *WIP) - wrap(*WIP - *(WIP + 1)); + V = wrap(*(WIP - image_width) - *WIP) - wrap(*WIP - *(WIP -(image_height - 1) * (image_width))); + D1 = wrap(*(WIP - image_width_plus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) + 1)); + D2 = wrap(*(WIP - image_width_minus_one) - *WIP) - wrap(*WIP - *(WIP - (image_height - 1) * (image_width) - 1)); + pixel_pointer->reliability = H*H + V*V + D1*D1 + D2*D2; + } + pixel_pointer++; + WIP++; + } + } +} + +//calculate the reliability of the horizontal edges of the image +//it is calculated by adding the reliability of pixel and the relibility of +//its right-hand neighbour +//edge is calculated between a pixel and its next neighbour +void horizontalEDGEs(PIXELM *pixel, EDGE *edge, + int image_width, int image_height, + params_t *params) +{ + int i, j; + EDGE *edge_pointer = edge; + PIXELM *pixel_pointer = pixel; + int no_of_edges = params->no_of_edges; + + for (i = 0; i < image_height; i++) + { + for (j = 0; j < image_width - 1; j++) + { + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + 1)->input_mask == NOMASK) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer+1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + 1)->value); + edge_pointer++; + no_of_edges++; + } + pixel_pointer++; + } + pixel_pointer++; + } + //construct edges at the right border of the image + if (params->x_connectivity == 1) + { + pixel_pointer = pixel + image_width - 1; + for (i = 0; i < image_height; i++) + { + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width + 1)->input_mask == NOMASK) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width + 1); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width + 1)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width + 1)->value); + edge_pointer++; + no_of_edges++; + } + pixel_pointer+=image_width; + } + } + params->no_of_edges = no_of_edges; +} + +//calculate the reliability of the vertical edges of the image +//it is calculated by adding the reliability of pixel and the relibility of +//its lower neighbour in the image. +void verticalEDGEs(PIXELM *pixel, EDGE *edge, + int image_width, int image_height, + params_t *params) +{ + int i, j; + int no_of_edges = params->no_of_edges; + PIXELM *pixel_pointer = pixel; + EDGE *edge_pointer = edge + no_of_edges; + + for (i=0; i < image_height - 1; i++) + { + for (j=0; j < image_width; j++) + { + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer + image_width)->input_mask == NOMASK) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer + image_width); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer + image_width)->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer + image_width)->value); + edge_pointer++; + no_of_edges++; + } + pixel_pointer++; + } //j loop + } // i loop + + //construct edges that connect at the bottom border of the image + if (params->y_connectivity == 1) + { + pixel_pointer = pixel + image_width *(image_height - 1); + for (i = 0; i < image_width; i++) + { + if (pixel_pointer->input_mask == NOMASK && (pixel_pointer - image_width *(image_height - 1))->input_mask == NOMASK) + { + edge_pointer->pointer_1 = pixel_pointer; + edge_pointer->pointer_2 = (pixel_pointer - image_width *(image_height - 1)); + edge_pointer->reliab = pixel_pointer->reliability + (pixel_pointer - image_width *(image_height - 1))->reliability; + edge_pointer->increment = find_wrap(pixel_pointer->value, (pixel_pointer - image_width *(image_height - 1))->value); + edge_pointer++; + no_of_edges++; + } + pixel_pointer++; + } + } + params->no_of_edges = no_of_edges; +} + +//gather the pixels of the image into groups +void gatherPIXELs(EDGE *edge, params_t *params) +{ + int k; + PIXELM *PIXEL1; + PIXELM *PIXEL2; + PIXELM *group1; + PIXELM *group2; + EDGE *pointer_edge = edge; + int incremento; + + for (k = 0; k < params->no_of_edges; k++) + { + PIXEL1 = pointer_edge->pointer_1; + PIXEL2 = pointer_edge->pointer_2; + + //PIXELM 1 and PIXELM 2 belong to different groups + //initially each pixel is a group by it self and one pixel can construct a group + //no else or else if to this if + if (PIXEL2->head != PIXEL1->head) + { + //PIXELM 2 is alone in its group + //merge this pixel with PIXELM 1 group and find the number of 2 pi to add + //to or subtract to unwrap it + if ((PIXEL2->next == NULL) && (PIXEL2->head == PIXEL2)) + { + PIXEL1->head->last->next = PIXEL2; + PIXEL1->head->last = PIXEL2; + (PIXEL1->head->number_of_pixels_in_group)++; + PIXEL2->head=PIXEL1->head; + PIXEL2->increment = PIXEL1->increment-pointer_edge->increment; + } + + //PIXELM 1 is alone in its group + //merge this pixel with PIXELM 2 group and find the number of 2 pi to add + //to or subtract to unwrap it + else if ((PIXEL1->next == NULL) && (PIXEL1->head == PIXEL1)) + { + PIXEL2->head->last->next = PIXEL1; + PIXEL2->head->last = PIXEL1; + (PIXEL2->head->number_of_pixels_in_group)++; + PIXEL1->head = PIXEL2->head; + PIXEL1->increment = PIXEL2->increment+pointer_edge->increment; + } + + //PIXELM 1 and PIXELM 2 both have groups + else + { + group1 = PIXEL1->head; + group2 = PIXEL2->head; + //if the no. of pixels in PIXELM 1 group is larger than the + //no. of pixels in PIXELM 2 group. Merge PIXELM 2 group to + //PIXELM 1 group and find the number of wraps between PIXELM 2 + //group and PIXELM 1 group to unwrap PIXELM 2 group with respect + //to PIXELM 1 group. the no. of wraps will be added to PIXELM 2 + //group in the future + if (group1->number_of_pixels_in_group > group2->number_of_pixels_in_group) + { + //merge PIXELM 2 with PIXELM 1 group + group1->last->next = group2; + group1->last = group2->last; + group1->number_of_pixels_in_group = group1->number_of_pixels_in_group + group2->number_of_pixels_in_group; + incremento = PIXEL1->increment-pointer_edge->increment - PIXEL2->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group2 != NULL) + { + group2->head = group1; + group2->increment += incremento; + group2 = group2->next; + } + } + + //if the no. of pixels in PIXELM 2 group is larger than the + //no. of pixels in PIXELM 1 group. Merge PIXELM 1 group to + //PIXELM 2 group and find the number of wraps between PIXELM 2 + //group and PIXELM 1 group to unwrap PIXELM 1 group with respect + //to PIXELM 2 group. the no. of wraps will be added to PIXELM 1 + //group in the future + else + { + //merge PIXELM 1 with PIXELM 2 group + group2->last->next = group1; + group2->last = group1->last; + group2->number_of_pixels_in_group = group2->number_of_pixels_in_group + group1->number_of_pixels_in_group; + incremento = PIXEL2->increment + pointer_edge->increment - PIXEL1->increment; + //merge the other pixels in PIXELM 2 group to PIXELM 1 group + while (group1 != NULL) + { + group1->head = group2; + group1->increment += incremento; + group1 = group1->next; + } // while + + } // else + } //else + } //if + pointer_edge++; + } +} + +//unwrap the image +void unwrapImage(PIXELM *pixel, int image_width, int image_height) +{ + int i; + int image_size = image_width * image_height; + PIXELM *pixel_pointer=pixel; + + for (i = 0; i < image_size; i++) + { + pixel_pointer->value += TWOPI * (double)(pixel_pointer->increment); + pixel_pointer++; + } +} + +//set the masked pixels (mask = 0) to the minimum of the unwrapper phase +void maskImage(PIXELM *pixel, unsigned char *input_mask, int image_width, int image_height) +{ + int image_width_plus_one = image_width + 1; + int image_height_plus_one = image_height + 1; + int image_width_minus_one = image_width - 1; + int image_height_minus_one = image_height - 1; + + PIXELM *pointer_pixel = pixel; + unsigned char *IMP = input_mask; //input mask pointer + double min=99999999; + int i; + int image_size = image_width * image_height; + + //find the minimum of the unwrapped phase + for (i = 0; i < image_size; i++) + { + if ((pointer_pixel->value < min) && (*IMP == NOMASK)) + min = pointer_pixel->value; + + pointer_pixel++; + IMP++; + } + + pointer_pixel = pixel; + IMP = input_mask; + + //set the masked pixels to minimum + for (i = 0; i < image_size; i++) + { + if ((*IMP) == MASK) + { + pointer_pixel->value = min; + } + pointer_pixel++; + IMP++; + } +} + +//the input to this unwrapper is an array that contains the wrapped +//phase map. copy the image on the buffer passed to this unwrapper to +//over-write the unwrapped phase map on the buffer of the wrapped +//phase map. +void returnImage(PIXELM *pixel, double *unwrapped_image, int image_width, int image_height) +{ + int i; + int image_size = image_width * image_height; + double *unwrapped_image_pointer = unwrapped_image; + PIXELM *pixel_pointer = pixel; + + for (i=0; i < image_size; i++) + { + *unwrapped_image_pointer = pixel_pointer->value; + pixel_pointer++; + unwrapped_image_pointer++; + } +} + +//the main function of the unwrapper +void +unwrap2D(double* wrapped_image, double* UnwrappedImage, unsigned char* input_mask, + int image_width, int image_height, + int wrap_around_x, int wrap_around_y) +{ + params_t params = {TWOPI, wrap_around_x, wrap_around_y, 0}; + unsigned char *extended_mask; + PIXELM *pixel; + EDGE *edge; + int image_size = image_height * image_width; + int No_of_Edges_initially = 2 * image_width * image_height; + + extended_mask = (unsigned char *) calloc(image_size, sizeof(unsigned char)); + pixel = (PIXELM *) calloc(image_size, sizeof(PIXELM)); + edge = (EDGE *) calloc(No_of_Edges_initially, sizeof(EDGE)); + + extend_mask(input_mask, extended_mask, image_width, image_height, ¶ms); + initialisePIXELs(wrapped_image, input_mask, extended_mask, pixel, image_width, image_height); + calculate_reliability(wrapped_image, pixel, image_width, image_height, ¶ms); + horizontalEDGEs(pixel, edge, image_width, image_height, ¶ms); + verticalEDGEs(pixel, edge, image_width, image_height, ¶ms); + + //sort the EDGEs depending on their reiability. The PIXELs with higher + //relibility (small value) first + quicker_sort(edge, edge + params.no_of_edges - 1); + + //gather PIXELs into groups + gatherPIXELs(edge, ¶ms); + + unwrapImage(pixel, image_width, image_height); + maskImage(pixel, input_mask, image_width, image_height); + + //copy the image from PIXELM structure to the unwrapped phase array + //passed to this function + //TODO: replace by (cython?) function to directly write into numpy array ? + returnImage(pixel, UnwrappedImage, image_width, image_height); + + free(edge); + free(pixel); + free(extended_mask); +} From 9091d2759a70e9714d4fa9fb5549a5a632dc479b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 13:06:53 +0200 Subject: [PATCH 73/84] unwrap: Change 2D wrapper code from float to double. --- skimage/exposure/_unwrap_2d.pyx | 8 ++++---- skimage/exposure/unwrap.py | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/skimage/exposure/_unwrap_2d.pyx b/skimage/exposure/_unwrap_2d.pyx index 88983287..6e889729 100644 --- a/skimage/exposure/_unwrap_2d.pyx +++ b/skimage/exposure/_unwrap_2d.pyx @@ -1,12 +1,12 @@ -cdef extern void unwrap2D(float* wrapped_image, - float* unwrapped_image, +cdef extern void unwrap2D(double* wrapped_image, + double* unwrapped_image, unsigned char* input_mask, int image_width, int image_height, int wrap_around_x, int wrap_around_y) -def unwrap_2d(float[:, ::1] image, +def unwrap_2d(double[:, ::1] image, unsigned char[:, ::1] mask, - float[:, ::1] unwrapped_image, + double[:, ::1] unwrapped_image, wrap_around): unwrap2D(&image[0, 0], &unwrapped_image[0, 0], diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index a2a8c42a..039ae911 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -92,6 +92,8 @@ def unwrap_phase(image, wrap_around=False): if image.ndim == 1: unwrap_1d(image_not_masked, image_unwrapped) elif image.ndim == 2: + image_not_masked = np.asarray(image, dtype=np.float64, order='C') + image_unwrapped = np.empty_like(image, dtype=np.float64, order='C') unwrap_2d(image_not_masked, mask, image_unwrapped, wrap_around) elif image.ndim == 3: From d0ccbe71c118f4bf24fefeafcba039b2c9db8cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 13:09:01 +0200 Subject: [PATCH 74/84] unwrap: Change 3D C code from float to double. --- skimage/exposure/unwrap_3d_ljmu.c | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/skimage/exposure/unwrap_3d_ljmu.c b/skimage/exposure/unwrap_3d_ljmu.c index 99800410..1874c051 100644 --- a/skimage/exposure/unwrap_3d_ljmu.c +++ b/skimage/exposure/unwrap_3d_ljmu.c @@ -29,7 +29,7 @@ typedef struct { - float mod; + double mod; int x_connectivity; int y_connectivity; int z_connectivity; @@ -41,8 +41,8 @@ struct VOXELM { int increment; //No. of 2*pi to add to the voxel to unwrap it int number_of_voxels_in_group;//No. of voxel in the voxel group - float value; //value of the voxel - float reliability; + double value; //value of the voxel + double reliability; unsigned char input_mask; //MASK voxel is masked. NOMASK voxel is not masked unsigned char extended_mask; //MASK voxel is masked. NOMASK voxel is not masked int group; //group No. @@ -58,7 +58,7 @@ typedef struct VOXELM VOXELM; //if we have S voxels, then we have S horizontal edges and S vertical edges struct EDGE { - float reliab; //reliabilty of the edge and it depends on the two voxels + double reliab; //reliabilty of the edge and it depends on the two voxels VOXELM *pointer_1; //pointer to the first voxel VOXELM *pointer_2; //pointer to the second voxel int increment; //No. of 2*pi to add to one of the @@ -76,7 +76,7 @@ typedef struct EDGE EDGE; typedef enum {yes, no} yes_no; -yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) +yes_no find_pivot(EDGE *left, EDGE *right, double *pivot_ptr) { EDGE a, b, c, *p; @@ -108,7 +108,7 @@ yes_no find_pivot(EDGE *left, EDGE *right, float *pivot_ptr) } } -EDGE *partition(EDGE *left, EDGE *right, float pivot) +EDGE *partition(EDGE *left, EDGE *right, double pivot) { while (left <= right) { @@ -129,7 +129,7 @@ EDGE *partition(EDGE *left, EDGE *right, float pivot) void quicker_sort(EDGE *left, EDGE *right) { EDGE *p; - float pivot; + double pivot; if (find_pivot(left, right, &pivot) == yes) { @@ -144,10 +144,10 @@ void quicker_sort(EDGE *left, EDGE *right) //--------------------start initialize voxels ---------------------------------- //initiale voxels. See the explanation of the voxel class above. //initially every voxel is assumed to belong to a group consisting of only itself -void initialiseVOXELs(float *WrappedVolume, unsigned char *input_mask, unsigned char *extended_mask, VOXELM *voxel, int volume_width, int volume_height, int volume_depth) +void initialiseVOXELs(double *WrappedVolume, unsigned char *input_mask, unsigned char *extended_mask, VOXELM *voxel, int volume_width, int volume_height, int volume_depth) { VOXELM *voxel_pointer = voxel; - float *wrapped_volume_pointer = WrappedVolume; + double *wrapped_volume_pointer = WrappedVolume; unsigned char *input_mask_pointer = input_mask; unsigned char *extended_mask_pointer = extended_mask; int n, i, j; @@ -161,7 +161,7 @@ void initialiseVOXELs(float *WrappedVolume, unsigned char *input_mask, unsigned voxel_pointer->increment = 0; voxel_pointer->number_of_voxels_in_group = 1; voxel_pointer->value = *wrapped_volume_pointer; - voxel_pointer->reliability = 9999999.f + rand(); + voxel_pointer->reliability = 9999999 + rand(); voxel_pointer->input_mask = *input_mask_pointer; voxel_pointer->extended_mask = *extended_mask_pointer; voxel_pointer->head = voxel_pointer; @@ -180,9 +180,9 @@ void initialiseVOXELs(float *WrappedVolume, unsigned char *input_mask, unsigned //-------------------end initialize voxels ----------- //gamma function in the paper -float wrap(float voxel_value) +double wrap(double voxel_value) { - float wrapped_voxel_value; + double wrapped_voxel_value; if (voxel_value > PI) wrapped_voxel_value = voxel_value - TWOPI; else if (voxel_value < -PI) wrapped_voxel_value = voxel_value + TWOPI; else wrapped_voxel_value = voxel_value; @@ -190,9 +190,9 @@ float wrap(float voxel_value) } // voxelL_value is the left voxel, voxelR_value is the right voxel -int find_wrap(float voxelL_value, float voxelR_value) +int find_wrap(double voxelL_value, double voxelR_value) { - float difference; + double difference; int wrap_value; difference = voxelL_value - voxelR_value; @@ -433,13 +433,13 @@ void extend_mask(unsigned char *input_mask, unsigned char *extended_mask, int vo } } -void calculate_reliability(float *wrappedVolume, VOXELM *voxel, int volume_width, int volume_height, int volume_depth, params_t *params) +void calculate_reliability(double *wrappedVolume, VOXELM *voxel, int volume_width, int volume_height, int volume_depth, params_t *params) { int frame_size = volume_width * volume_height; int volume_size = volume_width * volume_height * volume_depth; VOXELM *voxel_pointer; - float H, V, N, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10; - float *WVP; + double H, V, N, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10; + double *WVP; int n, i, j; WVP = wrappedVolume + frame_size + volume_width + 1; @@ -949,7 +949,7 @@ void unwrapVolume(VOXELM *voxel, int volume_width, int volume_height, int volume for (i = 0; i < volume_size; i++) { - voxel_pointer->value += TWOPI * (float)(voxel_pointer->increment); + voxel_pointer->value += TWOPI * (double)(voxel_pointer->increment); voxel_pointer++; } } @@ -964,7 +964,7 @@ void maskVolume(VOXELM *voxel, unsigned char *input_mask, int volume_width, int VOXELM *pointer_voxel = voxel; unsigned char *IMP = input_mask; //input mask pointer - float min=99999999.; + double min=99999999.; int i, j; int volume_size = volume_width * volume_height * volume_depth; @@ -997,11 +997,11 @@ void maskVolume(VOXELM *voxel, unsigned char *input_mask, int volume_width, int //phase map. copy the volume on the buffer passed to this unwrapper //to over-write the unwrapped phase map on the buffer of the wrapped //phase map. -void returnVolume(VOXELM *voxel, float *unwrappedVolume, int volume_width, int volume_height, int volume_depth) +void returnVolume(VOXELM *voxel, double *unwrappedVolume, int volume_width, int volume_height, int volume_depth) { int i; int volume_size = volume_width * volume_height * volume_depth; - float *unwrappedVolume_pointer = unwrappedVolume; + double *unwrappedVolume_pointer = unwrappedVolume; VOXELM *voxel_pointer = voxel; for (i=0; i < volume_size; i++) @@ -1014,7 +1014,7 @@ void returnVolume(VOXELM *voxel, float *unwrappedVolume, int volume_width, int //the main function of the unwrapper void -unwrap3D(float* wrapped_volume, float* unwrapped_volume, unsigned char* input_mask, +unwrap3D(double* wrapped_volume, double* unwrapped_volume, unsigned char* input_mask, int volume_width, int volume_height, int volume_depth, int wrap_around_x, int wrap_around_y, int wrap_around_z) { From cd5cc84aa98301dc718f29f694d9915e08c8814c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 13:10:34 +0200 Subject: [PATCH 75/84] unwrap: Change 3D wrapper code from float to double. --- skimage/exposure/_unwrap_3d.pyx | 8 ++++---- skimage/exposure/unwrap.py | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/skimage/exposure/_unwrap_3d.pyx b/skimage/exposure/_unwrap_3d.pyx index b202e8b9..370d58be 100644 --- a/skimage/exposure/_unwrap_3d.pyx +++ b/skimage/exposure/_unwrap_3d.pyx @@ -1,12 +1,12 @@ -cdef extern void unwrap3D(float* wrapped_volume, - float* unwrapped_volume, +cdef extern void unwrap3D(double* wrapped_volume, + double* unwrapped_volume, unsigned char* input_mask, int image_width, int image_height, int volume_depth, int wrap_around_x, int wrap_around_y, int wrap_around_z) -def unwrap_3d(float[:, :, ::1] image, +def unwrap_3d(double[:, :, ::1] image, unsigned char[:, :, ::1] mask, - float[:, :, ::1] unwrapped_image, + double[:, :, ::1] unwrapped_image, wrap_around): unwrap3D(&image[0, 0, 0], &unwrapped_image[0, 0, 0], diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 039ae911..0f0d4ae4 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -97,6 +97,8 @@ def unwrap_phase(image, wrap_around=False): unwrap_2d(image_not_masked, mask, image_unwrapped, wrap_around) elif image.ndim == 3: + image_not_masked = np.asarray(image, dtype=np.float64, order='C') + image_unwrapped = np.empty_like(image, dtype=np.float64, order='C') unwrap_3d(image_not_masked, mask, image_unwrapped, wrap_around) From 593a7d63cec47ff60871667d2337fdb2f98e4135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 13:12:18 +0200 Subject: [PATCH 76/84] unwrap: Change 1D unwrapper from float to double. --- skimage/exposure/_unwrap_1d.pyx | 4 ++-- skimage/exposure/unwrap.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/skimage/exposure/_unwrap_1d.pyx b/skimage/exposure/_unwrap_1d.pyx index d39f9e57..f23e5f40 100644 --- a/skimage/exposure/_unwrap_1d.pyx +++ b/skimage/exposure/_unwrap_1d.pyx @@ -6,11 +6,11 @@ from libc.math cimport M_PI -def unwrap_1d(float[::1] image, float[::1] unwrapped_image): +def unwrap_1d(double[::1] image, double[::1] unwrapped_image): '''Phase unwrapping using the naive approach.''' cdef: Py_ssize_t i - float difference + double difference long periods = 0 unwrapped_image[0] = image[0] for i in range(1, image.shape[0]): diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 0f0d4ae4..3c52acde 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -90,6 +90,8 @@ def unwrap_phase(image, wrap_around=False): image_unwrapped = np.empty_like(image, dtype=np.float32, order='C') if image.ndim == 1: + image_not_masked = np.asarray(image, dtype=np.float64, order='C') + image_unwrapped = np.empty_like(image, dtype=np.float64, order='C') unwrap_1d(image_not_masked, image_unwrapped) elif image.ndim == 2: image_not_masked = np.asarray(image, dtype=np.float64, order='C') From 8ad3d1df17aa4880515634ebcc583f17d5229713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 13:13:59 +0200 Subject: [PATCH 77/84] unwrap: Simplify code after completing float->double. --- skimage/exposure/unwrap.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/skimage/exposure/unwrap.py b/skimage/exposure/unwrap.py index 3c52acde..86444aef 100644 --- a/skimage/exposure/unwrap.py +++ b/skimage/exposure/unwrap.py @@ -86,21 +86,15 @@ def unwrap_phase(image, wrap_around=False): mask = np.require(image.mask, np.uint8, ['C']) else: mask = np.zeros_like(image, dtype=np.uint8, order='C') - image_not_masked = np.asarray(image, dtype=np.float32, order='C') - image_unwrapped = np.empty_like(image, dtype=np.float32, order='C') + image_not_masked = np.asarray(image, dtype=np.float64, order='C') + image_unwrapped = np.empty_like(image, dtype=np.float64, order='C') if image.ndim == 1: - image_not_masked = np.asarray(image, dtype=np.float64, order='C') - image_unwrapped = np.empty_like(image, dtype=np.float64, order='C') unwrap_1d(image_not_masked, image_unwrapped) elif image.ndim == 2: - image_not_masked = np.asarray(image, dtype=np.float64, order='C') - image_unwrapped = np.empty_like(image, dtype=np.float64, order='C') unwrap_2d(image_not_masked, mask, image_unwrapped, wrap_around) elif image.ndim == 3: - image_not_masked = np.asarray(image, dtype=np.float64, order='C') - image_unwrapped = np.empty_like(image, dtype=np.float64, order='C') unwrap_3d(image_not_masked, mask, image_unwrapped, wrap_around) From a10f1c1468da96877382fa621c1e3f396eeda576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 14:00:53 +0200 Subject: [PATCH 78/84] unwrap example: cleanup. --- doc/examples/plot_phase_unwrap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/examples/plot_phase_unwrap.py b/doc/examples/plot_phase_unwrap.py index c2aecdb5..a525a823 100644 --- a/doc/examples/plot_phase_unwrap.py +++ b/doc/examples/plot_phase_unwrap.py @@ -13,6 +13,7 @@ problem. import numpy as np from matplotlib import pyplot as plt from skimage import data, img_as_float, color, exposure +from skimage.exposure import unwrap_phase # Load an image as a floating-point grayscale @@ -22,9 +23,8 @@ image = exposure.rescale_intensity(image, out_range=(0, 4 * np.pi)) # Create a phase-wrapped image in the interval [-pi, pi) image_wrapped = np.angle(np.exp(1j * image)) # Perform phase unwrapping -image_unwrapped = exposure.unwrap_phase(image_wrapped) +image_unwrapped = unwrap_phase(image_wrapped) -# Plotting plt.figure() plt.subplot(221) plt.title('Original') From 3737e6ebd3b933af126885cb1fde3418e3041194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 14:01:15 +0200 Subject: [PATCH 79/84] unwrap example: Mention dimensionalities available. --- doc/examples/plot_phase_unwrap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/examples/plot_phase_unwrap.py b/doc/examples/plot_phase_unwrap.py index a525a823..aefc493e 100644 --- a/doc/examples/plot_phase_unwrap.py +++ b/doc/examples/plot_phase_unwrap.py @@ -7,7 +7,8 @@ Some signals can only be observed modulo 2*pi, and this can also apply to two- and three dimensional images. In these cases phase unwrapping is needed to recover the underlying, unwrapped signal. In this example we will demonstrate an algorithm [1]_ implemented in ``skimage`` at work for such a -problem. +problem. One-, two- and three dimensional images can all be unwrapped using +skimage. Here we will demonstrate phase unwrapping in the two dimensional case. """ import numpy as np From 38d502208f506d1397e7b477aaf79d4b09d3d08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 14:01:47 +0200 Subject: [PATCH 80/84] unwrap example: Include masking and wrap around. --- doc/examples/plot_phase_unwrap.py | 59 +++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/doc/examples/plot_phase_unwrap.py b/doc/examples/plot_phase_unwrap.py index aefc493e..39055995 100644 --- a/doc/examples/plot_phase_unwrap.py +++ b/doc/examples/plot_phase_unwrap.py @@ -39,20 +39,73 @@ plt.colorbar() plt.subplot(223) plt.title('After phase unwrapping') -plt.imshow(image_unwrapped, cmap='gray') +plt.imshow(image_unwrapped, cmap='gray') plt.colorbar() plt.subplot(224) plt.title('Unwrapped minus original') -plt.imshow(image_unwrapped - image, cmap='gray') +plt.imshow(image_unwrapped - image, cmap='gray') +plt.colorbar() + +""" +.. image:: PLOT2RST.current_figure + +The unwrapping procedure accepts masked arrays, and can also optionally +assume cyclic boundaries to connect edges of an image. In the example below, +we study a simple phase ramp which has been split in two by masking +a row of the image. +""" + +# Create a simple ramp +image = np.ones((100, 100)) * np.linspace(0, 8 * np.pi, 100).reshape((-1, 1)) +# Mask the image to split it in two horizontally +mask = np.zeros_like(image, dtype=np.bool) +mask[image.shape[0] // 2, :] = True + +image_wrapped = np.ma.array(np.angle(np.exp(1j * image)), mask=mask) +# Unwrap image without wrap around +image_unwrapped_no_wrap_around = unwrap_phase(image_wrapped, + wrap_around=(False, False)) +# Unwrap with wrap around enabled for the 0th dimension +image_unwrapped_wrap_around = unwrap_phase(image_wrapped, + wrap_around=(True, False)) + +plt.figure() +plt.subplot(221) +plt.title('Original') +plt.imshow(np.ma.array(image, mask=mask), cmap='jet') +plt.colorbar() + +plt.subplot(222) +plt.title('Wrapped phase') +plt.imshow(image_wrapped, cmap='jet', vmin=-np.pi, vmax=np.pi) +plt.colorbar() + +plt.subplot(223) +plt.title('Unwrapped without wrap_around') +plt.imshow(image_unwrapped_no_wrap_around, cmap='jet') +plt.colorbar() + +plt.subplot(224) +plt.title('Unwrapped with wrap_around') +plt.imshow(image_unwrapped_wrap_around, cmap='jet') plt.colorbar() plt.show() - """ .. image:: PLOT2RST.current_figure +In the figures above, the masked row can be seen as a white line across +the image. The difference between the two unwrapped images in the bottom row +is clear: Without unwrapping (lower left), the regions above and below the +masked boundary do not interact at all, resulting in an offset between the +two regions of an arbitrary integer times two pi. We could just as well have +unwrapped the regions as two separate images. With wrap around enabled for the +vertical direction (lower rigth), the situation changes: Unwrapping paths are +now allowed to pass from the bottom to the top of the image and vice versa, in +effect providing a way to determine the offset between the two regions. + References ---------- From 37b5a946c8bb859128b2ecd1b0042e22af369eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 16 Jul 2013 14:09:56 +0200 Subject: [PATCH 81/84] unwrap tests: PEP8 fixes. --- skimage/exposure/tests/test_unwrap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/skimage/exposure/tests/test_unwrap.py b/skimage/exposure/tests/test_unwrap.py index 220bb177..1b3ecca3 100644 --- a/skimage/exposure/tests/test_unwrap.py +++ b/skimage/exposure/tests/test_unwrap.py @@ -133,9 +133,9 @@ def test_mask(): # Same tests, but forcing use of the 3D unwrapper by reshaping image_wrapped_3d = image_wrapped.reshape((1,) + image_wrapped.shape) image_unwrapped_3d = unwrap_phase(image_wrapped_3d) - image_unwrapped_3d -= image_unwrapped_3d[0, 0, 0] # remove phase shift + image_unwrapped_3d -= image_unwrapped_3d[0, 0, 0] # remove phase shift assert_array_almost_equal(image_unwrapped_3d[:, :, -1], image[i, -1]) -if __name__=="__main__": +if __name__ == "__main__": run_module_suite() From ccbd3bfcedfa3318d9ec72c2a89aa3938d52ddb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Wed, 17 Jul 2013 13:46:24 +0200 Subject: [PATCH 82/84] unwrap: Do not include debug symbols in extension builds. --- skimage/exposure/setup.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/skimage/exposure/setup.py b/skimage/exposure/setup.py index 1e801088..b90b082c 100644 --- a/skimage/exposure/setup.py +++ b/skimage/exposure/setup.py @@ -21,11 +21,9 @@ def configuration(parent_package='', top_path=None): include_dirs=[get_numpy_include_dirs()]) unwrap_sources_2d = ['_unwrap_2d.c', 'unwrap_2d_ljmu.c'] config.add_extension('_unwrap_2d', sources=unwrap_sources_2d, - extra_compile_args=['-g'], include_dirs=[get_numpy_include_dirs()]) unwrap_sources_3d = ['_unwrap_3d.c', 'unwrap_3d_ljmu.c'] config.add_extension('_unwrap_3d', sources=unwrap_sources_3d, - extra_compile_args=['-g'], include_dirs=[get_numpy_include_dirs()]) return config From 51f94d83a9e66a8d74fab78313700a4dda1a9a26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Fri, 22 Nov 2013 12:29:31 +0100 Subject: [PATCH 83/84] Less verbose entry in CONTRIBUTORS. --- CONTRIBUTORS.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 39a2f988..27e9a042 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -144,8 +144,7 @@ Color separation (color deconvolution) for several stainings. - Jostein Bø Fløystad - Reconstruction circle mode for Radon transform - Simultaneous Algebraic Reconstruction Technique for inverse Radon transform + Tomography: radon/iradon improvements and SART implementation - Matt Terry Color difference functions From 7afae271dd6a44126929eaeab524a1116e947dc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Fri, 22 Nov 2013 12:59:35 +0100 Subject: [PATCH 84/84] Add contributors for phase unwrapping. --- CONTRIBUTORS.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 27e9a042..86463b69 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -145,6 +145,7 @@ - Jostein Bø Fløystad Tomography: radon/iradon improvements and SART implementation + Phase unwrapping integration - Matt Terry Color difference functions @@ -160,3 +161,15 @@ - Michael Hansen novice submodule + +- Munther Gdeisat + Phase unwrapping implementation + +- Miguel Arevallilo Herraez + Phase unwrapping implementation + +- Hussein Abdul-Rahman + Phase unwrapping implementation + +- Gregor Thalhammer + Phase unwrapping integration