/* Author: Jonathan Hardy file: roberts.cc This file reads in a PGM image file and processes it with the Roberts edge detector algorithm. The processed image is then written out to a new PGM image file with "_rbts" appended to the original filename. The arguments are as follows: roberts . */ #include #include #include #include FILE *ptr; // Image File FILE *rbtsptr; // Output File void main(int argc, char**argv) { char fname[13]; // Image filename char rbtsname[18]; // Output filename char width[4], height[4], numcol[4]; // Image information char Type[3]; // Image type (P5) int r, c, data; // Counters and image data variable char temp[100]; // Variable for input comment lines char comment[17]; // Variable for output comment /* The following section reads the image file */ strcpy(fname, argv[1]); // Get filename from command line strcat(fname, ".pgm"); // Append filename with ".pgm" const int ulimit = atoi(argv[2]); // Get upper threshold const int llimit = atoi(argv[3]); // Get lower threshold int thresh = atoi(argv[4]); // Get output threshold ptr = fopen(fname, "rb"); // Open image file fread(&Type, 3, 1, ptr); // Get image type fread(&width, 4, 1, ptr); // If no comment lines, get width while (width[0] == '#'){ // Otherwise, ignore comment lines fgets(temp, 100, ptr); // and get width fread(&width, 4, 1, ptr); } fread(&height, 4, 1, ptr); // Get height const int WIDTH = atoi(width); const int HEIGHT = atoi(height); int ImgArray[HEIGHT][WIDTH]; // Create image array fread(&numcol, 4, 1, ptr); // Get number of colors (255) for (r = 0; r < HEIGHT; r++){ // Get image data and threshold it for (c = 0; c < WIDTH; c++){ data = fgetc(ptr); if ((data < llimit) || (data > ulimit)) ImgArray[r][c] = 0; else ImgArray[r][c] = data; } } fclose(ptr); // Close image file /* The following section processes the image data */ strcpy(rbtsname, argv[1]); strcat(rbtsname, "_rbts.pgm"); int RbtsArray[HEIGHT][WIDTH]; // Create array for processed data int dx, dy; // Mask response variables float maxResp = 1; // Variable for maximum response float factor = 1; // Variable for scaling factor /* The following iteration scans the image array and performs the mask convolutions for the Roberts algorithm. It calculates the magnitude response by summing the absolute values of the dx and dy responses. */ for (r = 0; r < HEIGHT - 1; r++){ RbtsArray[r][WIDTH-1] = 0; for (c = 0; c < WIDTH - 1; c++){ dx = ImgArray[r][c] - ImgArray[r+1][c+1]; dy = ImgArray[r][c+1] - ImgArray[r+1][c]; RbtsArray[r][c] = (abs(dx) + abs(dy)); if (int((abs(dx) + abs(dy))) >= maxResp) maxResp = (abs(dx) + abs(dy)); } } /* This section takes care of the edges */ for (c = 0; c < WIDTH - 1; c++){ RbtsArray[HEIGHT-1][c] = 0; } /* This section scales the output array for writing to a 255-level grayscale image */ factor = maxResp / 255; for (r = 0; r < HEIGHT; r++){ for (c = 0; c < WIDTH; c++){ RbtsArray[r][c] = (int)(floor(RbtsArray[r][c] / factor)); } } /* This section thresholds out small responses */ for (r = 0; r < HEIGHT; r++){ for (c = 0; c < WIDTH; c++){ if (RbtsArray[r][c] < thresh){RbtsArray[r][c] = 0;} } } /* This section writes the output to a new PGM file */ printf("%s\n", Type); rbtsptr = fopen(rbtsname, "wb"); fwrite(&Type, 3, 1, rbtsptr); comment = "# New pgm file.\n"; fwrite(&comment, 16, 1, rbtsptr); fwrite(&width, 4, 1, rbtsptr); fwrite(&height, 4, 1, rbtsptr); fwrite(&numcol, 4, 1, rbtsptr); for (r = 0; r < HEIGHT; r++){ for (c = 0; c < WIDTH; c++){ fputc(RbtsArray[r][c], rbtsptr); } } fclose(rbtsptr); }