/********************************************** * * file ed.c * * Functions: This file contains * erosion * dilation * mask_erosion * mask_dilation * interior_outline * exterior_outline * copy_3_x_3 * opening * closing * get_shape_options * * Purpose: * These functions perform the erosion, * dilation, outlining, opening and * closing operations. * * External Calls: * none * * Modifications: * 14 March 1993 - created * 21 August 1998 - modified to work on entire * images at once. * ************************************************/ #include "cips.h" short edmask1[3][3] = {{0, 1, 0}, {0, 1, 0}, {0, 1, 0}}; short edmask2[3][3] = {{0, 0, 0}, {1, 1, 1}, {0, 0, 0}}; short edmask3[3][3] = {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}}; short edmask4[3][3] = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}; /******************************************* * * erosion(... * * This function performs the erosion * operation. If a value pixel has more * than the threshold number of 0 * neighbors, you erode it by setting it * to 0. * *******************************************/ erosion(the_image, out_image, value, threshold, rows, cols) int threshold; short **the_image, **out_image, value; long cols, rows; { int a, b, count, i, j, k; /*************************** * * Loop over image array * ****************************/ for(i=0; i= 0){ if(the_image[i+a][j+b] == 0) count++; } } /* ends loop over b */ } /* ends loop over a */ if(count > threshold){ out_image[i][j] = 0; } } /* ends if the_image == value */ } /* ends loop over j */ } /* ends loop over i */ /***** fix_edges(out_image, 3, rows, cols); ***/ } /* ends erosion */ /******************************************* * * dilation(... * * This function performs the dilation * operation. If a 0 pixel has more than * threshold number of value neighbors, * you dilate it by setting it to value. * *******************************************/ dilation(the_image, out_image, value, threshold, rows, cols) int threshold; short **the_image, **out_image, value; long cols, rows; { int a, b, count, i, j, k; int three = 3; /*************************** * * Loop over image array * ****************************/ for(i=0; i threshold) out_image[i][j] = value; } /* ends if the_image == 0 */ } /* ends loop over j */ } /* ends loop over i */ /***** fix_edges(out_image, three, rows, cols); ***/ } /* ends dilation */ /******************************************* * * mask_dilation(... * * This function performs the dilation * operation using the erosion-dilation * 3x3 masks given above. It works on * 0-value images. * *******************************************/ mask_dilation(the_image, out_image, value, mask_type, rows, cols) int mask_type; short **the_image, **out_image, value; long cols, rows; { int a, b, count, i, j, k; short mask[3][3], max; /************************************** * * Copy the 3x3 erosion-dilation mask * specified by the mask_type. * ***************************************/ switch(mask_type){ case 1: copy_3_x_3(mask, edmask1); break; case 2: copy_3_x_3(mask, edmask2); break; case 3: copy_3_x_3(mask, edmask3); break; case 4: copy_3_x_3(mask, edmask4); break; default: printf("\nInvalid mask type, using mask 4"); copy_3_x_3(mask, edmask4); break; } /*************************** * * Loop over image array * ****************************/ printf("\n"); for(i=1; i max) max = the_image[i+a][j+b]; } /* ends if mask == 1 */ } /* ends loop over b */ } /* ends loop over a */ out_image[i][j] = max; } /* ends loop over j */ } /* ends loop over i */ /***** fix_edges(out_image, 3, rows, cols); ***/ } /* ends mask_dilation */ /******************************************* * * mask_erosion(... * * This function performs the erosion * operation using the erosion-dilation * 3x3 masks given above. It works on * 0-value images. * *******************************************/ mask_erosion(the_image, out_image, value, mask_type, rows, cols) int mask_type; short **the_image, **out_image, value; long cols, rows; { int a, b, count, i, j, k; short mask[3][3], min; /************************************** * * Copy the 3x3 erosion-dilation mask * specified by the mask_type. * ***************************************/ switch(mask_type){ case 1: copy_3_x_3(mask, edmask1); break; case 2: copy_3_x_3(mask, edmask2); break; case 3: copy_3_x_3(mask, edmask3); break; case 4: copy_3_x_3(mask, edmask4); break; default: printf("\nInvalid mask type, using mask 4"); copy_3_x_3(mask, edmask4); break; } /*************************** * * Loop over image array * ****************************/ printf("\n"); for(i=1; i 1){ count = 1; while(count < number){ count++; mask_erosion(the_image, out_image, value, mask_type, rows, cols); } /* ends while */ } /* ends if number > 1 */ mask_dilation(the_image, out_image, value, mask_type, rows, cols); } /* ends opening */ /******************************************* * * closing(... * * Closing is dilation followed by erosion. * This routine will use the mask erosion * and dilation. You could use the other * types and you could mix the two types. * * The number parameter specifies how * dilations to perform before doing one * erosion. * *******************************************/ closing(the_image, out_image, value, mask_type, number, rows, cols) int number; int mask_type; short **the_image, **out_image, value; long cols, rows; { int a, b, count, i, j, k; short mask[3][3], max; printf("\nCLOSING> value=%d mask=%d number=%d",value,mask_type,number); /************************************** * * Copy the 3x3 erosion-dilation mask * specified by the mask_type. * ***************************************/ switch(mask_type){ case 1: copy_3_x_3(mask, edmask1); break; case 2: copy_3_x_3(mask, edmask2); break; case 3: copy_3_x_3(mask, edmask3); break; case 4: copy_3_x_3(mask, edmask4); break; default: printf("\nInvalid mask type, using mask 4"); copy_3_x_3(mask, edmask4); break; } for(i=0; i 1){ count = 1; while(count < number){ count++; mask_dilation(the_image, out_image, value, mask_type, rows, cols); } /* ends while */ } /* ends if number > 1 */ mask_erosion(the_image, out_image, value, mask_type, rows, cols); } /* ends closing */ /******************************************* * * interior_outline(... * * This function produces the outline of * any "holes" inside an object. The * method is: * output = erosion of input * final output = input - output * *******************************************/ interior_outline(the_image, out_image, value, mask_type, rows, cols) int mask_type; short **the_image, **out_image, value; long cols, rows; { int a, b, count, i, j, k; short mask[3][3], max; /************************************** * * Copy the 3x3 erosion-dilation mask * specified by the mask_type. * ***************************************/ switch(mask_type){ case 1: copy_3_x_3(mask, edmask1); break; case 2: copy_3_x_3(mask, edmask2); break; case 3: copy_3_x_3(mask, edmask3); break; case 4: copy_3_x_3(mask, edmask4); break; default: printf("\nInvalid mask type, using mask 4"); copy_3_x_3(mask, edmask4); break; } mask_erosion(the_image, out_image, value, mask_type, rows, cols); for(i=0; i