/* sample PGM reader/writer for 24-354 General Robotics Lab 2 fall 2000: amperez * original version) spring 2002: bstolt * updated file reader * removed hard-coded filenames (segfaults!) * handle comments in headers * added some basic error checking * misc clean-up fall 2003: spieper * made it simpler to do all three operations in one shot. * improved names on output files. spring 2011: cwyu * cleaned up a bit, took out some typos * moved the PGM code to a separate file * wrote a Makefile */ /* Dear reader, instead of reading in characters, read in ints. Your life will be a lot better. If you insist on reading in chars, then read in unsigned chars. Note that ints are bigger than chars */ #include #include #include #include #include "lab2.h" /* We'll give you this one for free */ void Thresh (pgm *image, pgm *target, int n) { int *imageBuff,*targetBuff; int size; size = image->w * image->h; imageBuff = image->pData; targetBuff = target->pData; while( size-- ) { if( *imageBuff < n ) { *targetBuff = 0; } else { *targetBuff = 255; } imageBuff++; targetBuff++; } } void Contrast (pgm *in, pgm *out, int *hist) { int *imageBuff, *targetBuff; int i,size,high,low,margin,counter; size = in->w*in->h; imageBuff = in->pData; targetBuff = out->pData; margin = size/2500; //uses histogram array from histogram function to //determine high and low values i=0; counter=0; while(counter<=margin) { counter+=hist[i]; i++; } low = i; i=0; counter=0; while(counter<=margin) { counter+=hist[255-i]; i++; } high = 255-i; i=0; printf("\n %i %i %i \n",margin,high,low); for(i=0; ihigh) targetBuff[i]=255; /* math explanation: a) imageBuff[i]-low darkens the image so that values of 0 exist. b) /(float)(high-low) gives us a number between 0 and 1 that represents the pixel's position relative to the high and low c) *255 takes that floating point value and stretches it to place it on the full range of 255 that we need. */ else targetBuff[i]=(int)(((imageBuff[i]-low)/((float)(high-low)))*255); } } void Histogram (pgm *image, pgm *output, int *hist) { int *imageBuff, *outBuff; int size, weighted, index; float max; int i,j; size = image->w * image->h; imageBuff = image->pData; outBuff = output->pData; max = 0; //initialize values in histogram pixels for(i=0; ih*output->w; i++) outBuff[i] = 255; //initialize values in histogram array for(i=0; i<256; i++) hist[i] = 0; //counts how many pixels have a certain value and puts that into an array for(i=0; imax) max = hist[imageBuff[i]]; } //iterates histogram array and draws black lines on the histogram image for(i=0; i<256; i++) { weighted = (int)((hist[i]/max)*255-1); for(j=0; j<=weighted; j++) { index = i+(output->h-j-1)*output->w; outBuff[index]=0; } } } int main(int argc, char * argv[]) { pgm *image, *threshed, *contrasted, *histogram; char filename[256]; char outfilename[256]; int val; int errchk; int *histArray; //check if a filename was given, if not, ask for one if (argc > 1) { strcpy(filename, argv[1]); } else { printf ("Enter filename: "); scanf ("%s", filename); } if(strlen(filename)>220) { printf("filename too long\n"); exit(0); } //allocate memory for the pgm struct threshed = (pgm *) malloc (sizeof(pgm)); histogram = (pgm *) malloc (sizeof(pgm)); contrasted = (pgm *) malloc (sizeof(pgm)); image = (pgm *) malloc (sizeof(pgm)); //read the file LoadPGM(filename, image); //set the output files to have the same size as the input file contrasted->max=image->max; contrasted->w=image->w; contrasted->h=image->h; contrasted->pData=malloc(sizeof(int)*contrasted->w*contrasted->h); threshed->max=image->max; threshed->w=image->w; threshed->h=image->h; threshed->pData=malloc(sizeof(int)*threshed->w*threshed->h); //allocate memory for histogram array, used later in threshhold histArray = malloc(sizeof(int)*256); //except for the histogram - make it as big as you want histogram->h=256; histogram->w=256; histogram->max=255; histogram->pData=malloc(sizeof(int)*histogram->w*histogram->h); // --- now do something with the data --- //thresholding for instance... //get thresholding value if (argc > 2) { errchk = sscanf (argv[2], "%d", &val); } else { printf ("Enter threshold value: "); errchk = scanf ("%d", &val); } // make sure it's not really screwed up if (!errchk || val >= 255 || val < 0) { printf("Error: Bad thresholding value\n\n"); exit(1); } // Process the files // run thresholding Thresh(image, threshed, val); // create your histogram Histogram(image,histogram,histArray); // run contrasting Contrast(image,contrasted,histArray); // Write out the processed files strcpy(outfilename, filename); strcpy(&outfilename[strcspn(filename, ".")], "_threshed.pgm"); WritePGM(outfilename, threshed); strcpy(outfilename, filename); strcpy(&outfilename[strcspn(filename, ".")], "_contrasted.pgm"); WritePGM(outfilename, contrasted); strcpy(outfilename, filename); strcpy(&outfilename[strcspn(filename, ".")], "_histogram.pgm"); WritePGM(outfilename, histogram); return 0; }