/* * usage: dilate * * performs dilation or erosion on the binary PGM image, also producing a * binary PGM image as output. uses either a box or disc as the * structuring element, where size is the length of a side of the * box or the radius of the disc */ #include #include #include #include #include #include #include using namespace std; #define I(x,y) (input_image[(y)*(width)+(x)]) #define O(x,y) (output_image[(y)*(width)+(x)]) unsigned char* read_pgm( char* filename, int* width, int* height); void write_pgm( FILE* f, int width, int height, unsigned char* data ); void mat_pgm(FILE* f,int** mat,int width, int height); int** pgm_mat( char* filename, int& width, int& height ); int** imatrix(int row, int col); int main(int argc, char **argv) { int width, height; int i,j; int** image_input; int** image_output; int** structure_element; int disk8[15][15]={{0,0,0,0,1,1,1,1,1,1,1,0,0,0,0},{0,0,0,1,1,1,1,1,1,1,1,1,0,0,0},\ {0,0,1,1,1,1,1,1,1,1,1,1,1,0,0},{0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},\ {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},\ {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},\ {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},\ {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{0,1,1,1,1,1,1,1,1,1,1,1,1,1,0},\ {0,0,1,1,1,1,1,1,1,1,1,1,1,0,0},{0,0,0,1,1,1,1,1,1,1,1,1,0,0,0},\ {0,0,0,0,1,1,1,1,1,1,1,0,0,0,0}}; int disk1[3][3]={{0,1,0},{1,1,1},{0,1,0}}; int sel_size,sel_type; if ( argc != 4 ) { fprintf( stderr, "usage: %s b|d size imagefile\n", argv[0] ); exit( 1 ); } switch ( argv[1][0] ) { case 'b': case 'B': sel_type = 1; break; case 'd': case 'D': sel_type = 2; break; default: fprintf( stderr, "b|d argument must be b or d.\n" ); exit( 1 ); } image_input=pgm_mat(argv[3],width,height); //read image into a matrix // use a structuring element of size sel_size. if sel_type is 1, // use a box. if sel_type is 2, use a disc. creating the // structuring element is the first thing you should do. // You may use the following hard coded structure elements (disks) or creat your own sel_size=atoi(argv[2]); if (sel_type==2) switch (sel_size) { case 1: { structure_element=imatrix(3,3); for (i=0;i<3;i++) for (j=0;j<3;j++) structure_element[i][j]=disk1[i][j]; break; } case 8: { structure_element=imatrix(15,15); for (i=0;i<15;i++) for (j=0;j<15;j++) structure_element[i][j]=disk8[i][j]; break; } default: fprintf( stderr, "The disk of radius %d is not supported.\n", sel_size );exit(1); } image_output=imatrix(height,width); image_output=image_input; // write your code here. you should perform dilation or erosion on // input_image and put the result in output_image. // If you run the skeleton code without any modification, output image will be the same as input image. mat_pgm(stdout,image_output,width,height);//write matrix to image } unsigned char* read_pgm( char* filename, int* width, int* height) { char buffer[80]; int phase = 0; int type, maxval; int j; unsigned char* data; FILE* f; if ( strcmp( filename, "-" ) == 0 ) { f = stdin; } else { f = fopen( filename, "rb" ); if ( f == NULL ) return NULL; } while ( phase < 4 ) { fgets( buffer, 80, f ); if ( buffer[0] == '#' ) continue; switch( phase ) { case 0: j = sscanf( buffer, "P%d %d %d %d\n", &type, width, height, &maxval ); break; case 1: j = sscanf( buffer, "%d %d %d\n", width, height, &maxval ); break; case 2: j = sscanf( buffer, "%d %d\n", height, &maxval ); break; case 3: j = sscanf( buffer, "%d\n", &maxval ); break; case 4: j = 0; break; } phase += j; } if ( type != 5 ) { fprintf( stderr, "bad input image format.\n" ); return NULL; } data = (unsigned char*)malloc ( *width * *height ); fread( data, *width * *height, 1, f ); fclose( f ); return data; } void write_pgm( FILE* f, int width, int height, unsigned char* data ) { fprintf( f, "P5\n%d %d\n%d\n", width, height, 255 ); fwrite( data, width*height, 1, f ); fclose( f ); } /***************************************************************************** * Write integer matrix to pgm image *****************************************************************************/ void mat_pgm(FILE* f,int** mat,int width, int height) { int i,j; unsigned char* output; output=new unsigned char [width*height]; for (i=0;i