/*********************************************************/ /* program 17: unsharp masking filter */ /*********************************************************/ #define XSIZE 640 #define YSIZE 480 #define RED 0 #define GREEN 1 #define BLUE 2 #define LPASS 3 /* 3, 5, 7, 9, ... */ #define WEIGHT 0.7 /* between 0.6 and 0.9 */ main() { unsigned char *ir,*ig,*ib; unsigned char *lr,*lg,*lb; unsigned char *or,*og,*ob; unsigned char *i,*i1,*i2,*i3; unsigned char *l,*l1; unsigned char *o; long int x,y,c; long int xm,ym; long int val; float cp,cl,fval; /* allocate input and output memory buffers */ ir = (unsigned char *) malloc (XSIZE*YSIZE); ig = (unsigned char *) malloc (XSIZE*YSIZE); ib = (unsigned char *) malloc (XSIZE*YSIZE); lr = (unsigned char *) malloc (XSIZE*YSIZE); lg = (unsigned char *) malloc (XSIZE*YSIZE); lb = (unsigned char *) malloc (XSIZE*YSIZE); or = (unsigned char *) malloc (XSIZE*YSIZE); og = (unsigned char *) malloc (XSIZE*YSIZE); ob = (unsigned char *) malloc (XSIZE*YSIZE); /* read the input image */ read_image("input",ir,ig,ib); /* create low-pass filtered image */ for (c = RED; c <= BLUE; c++) { if (c == RED ) i = ir; if (c == GREEN) i = ig; if (c == BLUE ) i = ib; if (c == RED ) l = lr; if (c == GREEN) l = lg; if (c == BLUE ) l = lb; for (y = (LPASS/2); y < (YSIZE-(LPASS/2)); y++) { i1 = i + (y*XSIZE) + (LPASS/2); l1 = l + (y*XSIZE) + (LPASS/2); for (x = (LPASS/2); x < (XSIZE-(LPASS/2)); x++) { i2 = i1 - ((LPASS/2)*XSIZE) - (LPASS/2); val = 0; for (ym = 0; ym < LPASS; ym++) { i3 = i2 + (ym*XSIZE); for (xm = 0; xm < LPASS; xm++) { val = val + ((long int)*i3++ & 0xff); } } *l1++ = (unsigned char)(val / (LPASS*LPASS)); i1++; } } } /* calculate constants for image merge */ cp = WEIGHT / ((2.0 * WEIGHT) - 1.0); cl = (1.0 - WEIGHT) / ((2.0 * WEIGHT) - 1.0); /* process the red, green, and blue planes one at a time */ for (c = RED; c <= BLUE; c++) { /* initialize pointers for current color plane */ if (c == RED ) i = ir; if (c == GREEN) i = ig; if (c == BLUE ) i = ib; if (c == RED ) l = lr; if (c == GREEN) l = lg; if (c == BLUE ) l = lb; if (c == RED ) o = or; if (c == GREEN) o = og; if (c == BLUE ) o = ob; /* merge the original and low-pass images */ for (y = 0; y < YSIZE; y++) { for (x = 0; x < XSIZE; x++) { fval = (cp * (float)*i++) - (cl * (float)*l++); if (fval < 0.0) fval = 0.0; if (fval > 255.0) fval = 255.0; *o++ = (unsigned char)fval; } } } /* write the output image */ write_image("output",or,og,ob); /* free memory buffers */ free(ir); free(ig); free(ib); free(lr); free(lg); free(lb); free(or); free(og); free(ob); }