/* * hw07.c: * * Apply 3x3 MF, OPEN, and CLOSE to a gray scale byte image. * Handle edge effects by making the output zero. * * The input image is assumed square. * * * 04/25/2006 jph * */ #include #include #include #include #include #define BYTE unsigned char /* * Function prototypes */ void disk2byte(); void byte2disk(); /*----------------------------------------------------------------------*/ /* MAIN */ /*----------------------------------------------------------------------*/ main(argc,argv) int argc; char *argv[]; { int size; /* num rows/cols in image */ char *infile; /* input filename */ char *MFoutfile; /* output filename for median filtered image */ char *Ooutfile; /* output filename for OPENed image */ char *Coutfile; /* output filename for CLOSEed image */ BYTE *x; /* input image */ BYTE *yMF; /* median filtered output image */ BYTE *yO; /* OPENed output image */ BYTE *yC; /* CLOSEed output image */ BYTE *yD; /* DILATEed image */ BYTE *yE; /* ERODEed image */ BYTE *W; /* the windowed set of pixels */ int wsize; /* window size */ int wsizeo2; /* window size divided by 2 */ int Max; /* max element of window set */ int middle; /* index in sort(W) of the median */ int min; /* min element of window set */ BYTE temp; /* temporary place holder for sorting */ int i,j; /* loop counters */ int row,col; /* loop counters for image rows and cols */ /* * Parse args and check for proper invocation */ if (argc != 7) { printf("\n%s: Apply w x w MF, OPEN, and CLOSE to a BYTE image.", argv[0]); printf("\nUsage: %s size w infile MFoutfile Ooutfile Coutfile\n",argv[0]); exit(0); } size = atoi(argv[1]); wsize = atoi(argv[2]); infile = argv[3]; MFoutfile = argv[4]; Ooutfile = argv[5]; Coutfile = argv[6]; if (!(wsize%2)) { printf("\n%s: w (window size) must be ODD!\n",argv[0]); exit(0); } wsizeo2 = wsize >> 1; middle = (wsize*wsize) >> 1; /* * Allocate image arrays */ if ((x = (BYTE *)malloc(size*size*sizeof(BYTE))) == NULL) { printf("\n%s: free store exhausted.\n",argv[0]); exit(-1); } if ((yMF = (BYTE *)malloc(size*size*sizeof(BYTE))) == NULL) { printf("\n%s: free store exhausted.\n",argv[0]); exit(-1); } if ((yO = (BYTE *)malloc(size*size*sizeof(BYTE))) == NULL) { printf("\n%s: free store exhausted.\n",argv[0]); exit(-1); } if ((yC = (BYTE *)malloc(size*size*sizeof(BYTE))) == NULL) { printf("\n%s: free store exhausted.\n",argv[0]); exit(-1); } if ((yD = (BYTE *)malloc(size*size*sizeof(BYTE))) == NULL) { printf("\n%s: free store exhausted.\n",argv[0]); exit(-1); } if ((yE = (BYTE *)malloc(size*size*sizeof(BYTE))) == NULL) { printf("\n%s: free store exhausted.\n",argv[0]); exit(-1); } if ((W = (BYTE *)malloc(wsize*wsize*sizeof(BYTE))) == NULL) { printf("\n%s: free store exhausted.\n",argv[0]); exit(-1); } /* * Initialize images */ for (i=0; i < size*size; i++) { yMF[i] = yO[i] = yC[i] = yD[i] = yE[i] = 0; } /* * Read the input image from disk */ disk2byte(x,size,size,infile); /* * Apply Median Filter, Erode, and Dilate */ for (row=wsizeo2; row < size-wsizeo2; row++) { for (col=wsizeo2; col < size-wsizeo2; col++) { for (j=-wsizeo2; j <= wsizeo2; j++) { for (i=-wsizeo2; i <= wsizeo2; i++) { W[(j+wsizeo2)*wsize + i + wsizeo2] = x[(row+j)*size + col+i]; } /* for i */ } /* for j */ /* * Sort the window set (full sort needed for OPEN and CLOSE) */ for (i=0; i < wsize*wsize; i++) { for (j=i+1; j < wsize*wsize; j++) { if (W[j] < W[i]) { temp = W[j]; W[j] = W[i]; W[i] = temp; } } /* for j */ } /* for i */ /* * Median Filter */ yMF[row*size + col] = W[middle]; /* * Dilate */ yD[row*size + col] = W[wsize*wsize - 1]; /* * Erode */ yE[row*size + col] = W[0]; } /* for col */ } /* for row */ /* * Finish the OPEN by applying DILATE to yE */ for (row=wsizeo2+1; row < size-wsizeo2-1; row++) { for (col=wsizeo2+1; col < size-wsizeo2-1; col++) { for (j=-wsizeo2; j <= wsizeo2; j++) { for (i=-wsizeo2; i <= wsizeo2; i++) { W[(j+wsizeo2)*wsize + i +wsizeo2] = yE[(row+j)*size + col+i]; } /* for i */ } /* for j */ /* * Find MAX of the window set */ Max = W[0]; for (i=1; i < wsize*wsize; i++) { if (Max < W[i]) { Max = W[i]; } } /* for i */ /* * DILATE */ yO[row*size + col] = Max; } /* for col */ } /* for row */ /* * Finish the CLOSE by applying ERODE to yD */ for (row=wsizeo2+1; row < size-wsizeo2-1; row++) { for (col=wsizeo2+1; col < size-wsizeo2-1; col++) { for (j=-wsizeo2; j <= wsizeo2; j++) { for (i=-wsizeo2; i <= wsizeo2; i++) { W[(j+wsizeo2)*wsize + i +wsizeo2] = yD[(row+j)*size + col+i]; } /* for i */ } /* for j */ /* * Find min of the window set */ min = W[0]; for (i=1; i < wsize*wsize; i++) { if (min > W[i]) { min = W[i]; } } /* for i */ /* * ERODE */ yC[row*size + col] = min; } /* for col */ } /* for row */ /* * Write the output images to disk */ byte2disk(yMF,size,size,MFoutfile); byte2disk(yO,size,size,Ooutfile); byte2disk(yC,size,size,Coutfile); return; } /*---------------- MAIN -------------------------------------------*/ /*---------------------------------------------------------------------- * disk2byte.c * * function reads an unsigned char (byte) image from disk * * * jph 15 June 1992 * ------------------------------------------------------------------------*/ void disk2byte(x,row_dim,col_dim,fn) BYTE *x; /* image to be read */ int row_dim; /* row dimension of x */ int col_dim; /* col dimension of x */ char *fn; /* filename */ { int fd; /* file descriptor */ int n_bytes; /* number of bytes to read */ /* * detect zero dimension input */ if ((row_dim==0) || (col_dim==0)) return; /* * create and open the file */ if ((fd = open(fn, O_RDONLY))==-1) { printf("\ndisk2byte.c : could not open %s !",fn); return; } /* * read image data from the file */ n_bytes = row_dim * col_dim * sizeof(unsigned char); if (read(fd,x,n_bytes) != n_bytes) { printf("\ndisk2byte.c : complete read of %s did not succeed.",fn); } /* * close file and return */ if (close(fd) == -1) printf("\ndisk2byte.c : error closing %s.",fn); return; } /*--------------------- disk2byte ----------------------------------*/ /*---------------------------------------------------------------------- * byte2disk.c * * function writes an unsigned char (byte) image to disk * * * jph 15 June 1992 * ------------------------------------------------------------------------*/ void byte2disk(x,row_dim,col_dim,fn) BYTE *x; /* image to be written */ int row_dim; /* row dimension of x */ int col_dim; /* col dimension of x */ char *fn; /* filename */ { int fd; /* file descriptor */ int n_bytes; /* number of bytes to read */ /* * detect zero dimension input */ if ((row_dim==0) || (col_dim==0)) return; /* * create and open the file */ if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0644))==-1) { printf("\nbyte2disk.c : could not open %s !",fn); return; } /* * write image data to the file */ n_bytes = row_dim * col_dim * sizeof(unsigned char); if (write(fd,x,n_bytes) != n_bytes) { printf("\nbyte2disk.c : complete write of %s did not succeed.",fn); } /* * close file and return */ if (close(fd) == -1) printf("\nbyte2disk.c : error closing %s.",fn); return; } /*------------------------- byte2disk ---------------------------------*/