1: #include < GL/glut.h > 2: #include < stdlib.h > 3: #include < stdio.h > 4: #include < string.h > 5: #include < math.h > 6: #include < pthread.h > 7: #include < sched.h > 8: #include < iostream.h > 9: 10: #define Round(v) ((int)(v+0.5)) 11: #define MAX 800 12: #define MAX_FILE_LENGTH 256 13: 14: #define LOW_VALUE 0 15: #define HIGH_VALUE 255 16: 17: #define TRUE 1 18: #define FALSE 0 19: 20: /*cartesian coordinate type*/ 21: typedef struct {int x; 22: int y;}coord; 23: 24: /*RGB color struct*/ 25: typedef struct {float red; 26: float green; 27: float blue; 28: }RGB; 29: 30: /*RGB color struct*/ 31: typedef struct {int red; 32: int green; 33: int blue; 34: }RGB_INT; 35: 36: struct PGMstructure 37: { 38: int maxVal; 39: int width; 40: int height; 41: RGB_INT data[MAX][MAX]; 42: }; 43: 44: typedef struct PGMstructure PGMImage; 45: 46: /*Evil globals, but not do-able otherwise.*/ 47: static PGMImage *img_cur; 48: static PGMImage *img0; /*original*/ 49: static PGMImage *img1; /*current*/ 50: static PGMImage *img2; /*current*/ 51: static int HSIZE; 52: static int VSIZE; 53: 54: /**************Drawing funcitions************************************/ 55: /********************************************************************/ 56: 57: void setCPixel(int ix, int iy, RGB color) 58: /*Same as setIPixel except that the last parameter is an RGB color*/ 59: { 60: float x = (ix*2.0)/HSIZE - 1.0; 61: float y = (iy*2.0)/VSIZE - 1.0; 62: glColor3f(color.red, color.green, color.blue); 63: glBegin(GL_POINTS); 64: glVertex2f (x, y); 65: glEnd(); 66: } 67: 68: void pxlcpy(PGMImage *dest, int dest_row, int dest_col, 69: PGMImage *src, int src_row, int src_col) 70: { 71: /*make sure values are within bounds*/ 72: if(dest_col > 0 && dest_col < (*dest).width 73: && dest_row > 0 && dest_row < (*dest).height 74: && src_col > 0 && src_col < (*src).width 75: && src_row > 0 && src_row < (*src).height) 76: { 77: (*dest).data[dest_row][dest_col].red = 78: (*src).data[src_row][src_col].red; 79: 80: (*dest).data[dest_row][dest_col].green = 81: (*src).data[src_row][src_col].green; 82: 83: (*dest).data[dest_row][dest_col].blue = 84: (*src).data[src_row][src_col].blue; 85: } 86: } 87: 88: 89: /**********************File I/O functions*******************************/ 90: /***********************************************************************/ 91: 92: /*Gets an ascii color pgm image file (type P3).*/ 93: void getPGMfile (char filename[], PGMImage *img) 94: { 95: FILE *in_file; 96: char ch; 97: int row, col; 98: 99: in_file = fopen(filename, "r"); 100: if (in_file == NULL) 101: { 102: fprintf(stderr, "Error: Unable to open file %s\n\n", filename); 103: exit(8); 104: } 105: 106: printf("\nReading image file: %s", filename); 107: 108: do /* skip header identifier */ 109: ch = getc(in_file); 110: while (ch != '\n'); 111: 112: do /* skip comments lines */ 113: { 114: while (ch != '\n') ch = getc(in_file); /* flush to end of line */ 115: ch = getc(in_file); 116: } while (ch == '#'); 117: 118: fseek(in_file, -1, SEEK_CUR); /* backup one character */ 119: 120: fscanf(in_file,"%d", &((*img).width)); 121: fscanf(in_file,"%d", &((*img).height)); 122: fscanf(in_file,"%d", &((*img).maxVal)); 123: 124: printf("\n width = %d",(*img).width); 125: printf("\n height = %d",(*img).height); 126: printf("\n maxVal = %d",(*img).maxVal); 127: printf("\n"); 128: 129: if (((*img).width > MAX) || ((*img).height > MAX)) 130: { 131: printf("\n\n***ERROR - image too big for current image structure***\n\n"); 132: exit(0); 133: } 134: 135: for (row=(*img).height-1; row >=0; row--) 136: for (col=0; col< (*img).width; col++) 137: { 138: fscanf(in_file,"%d", &((*img).data[row][col].red) ); 139: fscanf(in_file,"%d", &((*img).data[row][col].green)); 140: fscanf(in_file,"%d", &((*img).data[row][col].blue)); 141: } 142: fclose(in_file); 143: printf("\nDone reading file.\n"); 144: } 145: 146: 147: void save(PGMImage *img) 148: { 149: int i, j, nr, nc, k; 150: int red, green, blue; 151: FILE *iop; 152: 153: nr = img- >height; 154: nc = img- >width; 155: 156: iop = fopen("image1.pgm", "w"); 157: fprintf(iop, "P3\n"); 158: fprintf(iop, "%d %d\n", nc, nr); 159: fprintf(iop, "255\n"); 160: 161: k = 1; 162: for(i = nr - 1; i >= 0; i--) 163: { 164: for(j = 0; j < nc; j++) 165: { 166: red = img- >data[i][j].red; 167: green = img- >data[i][j].green; 168: blue = img- >data[i][j].blue; 169: if(red < 0) 170: { 171: printf("IMG_WRITE: Found value %d at row %d col %d\n", red, i, j); 172: printf(" Setting red to zero\n"); 173: red = 0; 174: } 175: if(green < 0) 176: { 177: printf("IMG_WRITE: Found value %d at row %d col %d\n", green,i, j); 178: printf(" Setting green to zero\n"); 179: green = 0; 180: } 181: if(blue < 0) 182: { 183: printf("IMG_WRITE: Found value %d at row %d col %d\n", blue, i, j); 184: printf(" Setting green to zero\n"); 185: blue = 0; 186: } 187: if(red > 255) 188: { 189: printf("IMG_WRITE: Found value %d at row %d col %d\n", red, i, j); 190: printf(" Setting red to 255\n"); 191: red = 255; 192: } 193: if(green > 255) 194: { 195: printf("IMG_WRITE: Found value %d at row %d col %d\n", green,i, j); 196: printf(" Setting green to 255\n"); 197: green = 255; 198: } 199: if(blue > 255) 200: { 201: printf("IMG_WRITE: Found value %d at row %d col %d\n", blue, i, j); 202: printf(" Setting blue to 255\n"); 203: blue = 255; 204: } 205: 206: if(k % 10) 207: { 208: fprintf(iop, "%d ", red); 209: fprintf(iop, "%d ", green); 210: fprintf(iop, "%d ", blue); 211: } 212: else /*for newline*/ 213: { 214: fprintf(iop, "%d\n", red); 215: fprintf(iop, "%d\n", green); 216: fprintf(iop, "%d\n", blue); 217: } 218: k++; 219: } 220: } 221: fprintf(iop, "\n"); 222: fclose(iop); 223: } 224: 225: 226: /****Calculation & drawing functions of the image translations********** 227: ***********************************************************************/ 228: 229: 230: void showColor (PGMImage *img) 231: { 232: int row, col; /*y, x*/ 233: RGB pixel_color; /*valid between 0 and 1?*/ 234: for (row=(*img).height-1; row >=0; row--) 235: for (col=0; col< (*img).width; col++) 236: { 237: pixel_color.red = 238: (float)(*img).data[row][col].red/(float)(*img).maxVal; 239: pixel_color.green = 240: (float)(*img).data[row][col].green/(float)(*img).maxVal; 241: pixel_color.blue = 242: (float)(*img).data[row][col].blue/(float)(*img).maxVal; 243: setCPixel(col, row, pixel_color); 244: } 245: glFlush (); 246: } 247: 248: void camera_correction(PGMImage* new_img, PGMImage* org_img) 249: { 250: int row, col, img_row, img_col; /*loop counting*/ 251: 252: /*camera parameters*/ 253: float height = 30; /*height of camera in cm*/ 254: float gamma = 0, theta = .698; /*camera angles = 40 degrees in rad*/ 255: float aperture = 1.1968, alpha = .598; /*aperature = 2 * alpha*/ 256: 257: /*temporary varaibles*/ 258: float angular_height_corr; 259: float angular_side_corr; 260: int x_coord, y_coord; 261: 262: memset(new_img, 0, sizeof(PGMImage)); 263: (*new_img).height = (*org_img).height; 264: (*new_img).width = (*org_img).width; 265: (*new_img).maxVal = (*org_img).maxVal; 266: 267: for (row=(*org_img).height-1; row >=0; row--) 268: for (col=0; col< (*org_img).width; col++) 269: { 270: /*img_row -= (*org_img).height / 2; 271: img_col = col - (*org_img).width / 2;*/ 272: 273: angular_height_corr = 274: (theta - alpha) + col * (aperture / ((float)((*org_img).width) - 1)); 275: angular_side_corr = 276: (gamma - alpha) + row * (aperture / ((float)((*org_img).height) - 1)); 277: 278: angular_height_corr /= 2; 279: /*angular_side_corr /= 2;*/ 280: /*height *= 2;*/ 281: height = 150; 282: 283: x_coord = (int) 284: height * (1 / tan(angular_height_corr)) * cos(angular_side_corr); 285: y_coord = (int) 286: height * (1 / tan(angular_height_corr)) * sin(angular_side_corr); 287: 288: /*x_coord += (*org_img).width / 2;*/ 289: y_coord += (*org_img).height / 2; 290: 291: /*printf("org: (%d, %d) new: (%d, %d)\n\n", row, col, y_coord, x_coord);*/ 292: 293: pxlcpy(new_img, y_coord, x_coord, org_img, row, col); 294: } 295: } 296: 297: void new_corr(PGMImage* new_img, PGMImage* org_img) 298: { 299: int rsw, ins; /*row shift width*/ 300: int i, j, k, l, row, col; /*loop counting*/ 301: int col_skip = 53, ins_skip = 207; 302: 303: 304: memset(new_img, 0, sizeof(PGMImage)); 305: (*new_img).height = (*org_img).height; 306: (*new_img).width = (*org_img).width; 307: (*new_img).maxVal = (*org_img).maxVal; 308: 309: for(row = ((*new_img).height - 1); row >= 0; row--) 310: { 311: k = ((*new_img).width / 2) - 1; 312: rsw = ((*new_img).height - row) / col_skip; 313: ins = (row / ins_skip); 314: cout < < "row: " < < row < < "rsw: " < < rsw < < endl; 315: for(i = ((*new_img).width / 2) - 1; i > 0 && k > 0; ) 316: { 317: for(l = rsw; l >= 0 && k >= 0 && i >= 0; i--, k--, l--) 318: { 319: pxlcpy(new_img, row, k, org_img, row, i); 320: //cout < < "new: (" < < row < < ", " < < k < < ") (" < < row < < ", " < < i < < ")" < < endl; 321: } 322: 323: for(j = 0; j < ins && k >= 0; j++, k--) 324: { 325: pxlcpy(new_img, row, k, org_img, row, i); 326: //cout < < "new: (" < < row < < ", " < < k < < ") (" < < row < < ", " < < i < < ") ins" < < endl; 327: } 328: } 329: } 330: } 331: 332: /* ================================================================= 333: * Callback functions. 334: * 335: * color = displayed graphics in window 336: * menu = menu event handling 337: * keyboard = deyboard event handling 338: * ----------------------------------------------------------------- */ 339: void color(void) 340: { 341: /*glClear (GL_COLOR_BUFFER_BIT);*/ 342: 343: /* printf("\nDrawing Original image...\n");*/ 344: showColor(img_cur); 345: 346: /*glFlush();*/ 347: } 348: 349: #define RESTART 0 350: #define CAMERA_CORRECTION 1 351: #define X2_C_CORR 2 352: #define NEW_CORR 3 353: 354: void menu(int selection) 355: { 356: if(selection == RESTART) 357: { 358: memcpy(img1, img0, sizeof(PGMImage)); 359: img_cur = img0; 360: } 361: if(selection == CAMERA_CORRECTION) 362: { 363: printf("Starting camera correction\n"); 364: camera_correction(img1, img0); 365: img_cur = img1; 366: } 367: if(selection == X2_C_CORR) 368: { 369: printf("Starting camera correction\n"); 370: camera_correction(img1, img0); 371: camera_correction(img2, img1); 372: img_cur = img2; 373: } 374: if(selection == NEW_CORR) 375: { 376: new_corr(img1, img0); 377: img_cur = img1; 378: } 379: /*glClear (GL_COLOR_BUFFER_BIT);*/ 380: showColor(img_cur); 381: glutPostRedisplay(); 382: } 383: 384: void keyboard(unsigned char key, int x, int y) 385: { 386: switch (key) 387: { 388: case 27: 389: exit(0); 390: break; 391: } 392: } 393: 394: /* ================================================================= 395: * init - initializes graphics viewport 396: * 397: * You should not have to change this function for the first few 398: * projects we have. It will become more important when we move to 399: * 3D graphics. 400: * ----------------------------------------------------------------- */ 401: void init (void) 402: { 403: 404: /* 405: * select clearing color - white 406: */ 407: glClearColor (1.0, 1.0, 1.0, 0.0); 408: 409: /* 410: * initialize viewport values 411: */ 412: glMatrixMode(GL_PROJECTION); 413: glLoadIdentity(); 414: glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); 415: 416: /*add menus*/ 417: glutCreateMenu(menu); 418: glutAddMenuEntry("Restart", RESTART); 419: glutAddMenuEntry("Camera Correction", CAMERA_CORRECTION); 420: glutAddMenuEntry("2x C. Corr.", X2_C_CORR); 421: glutAddMenuEntry("new corr", NEW_CORR); 422: glutAttachMenu(GLUT_RIGHT_BUTTON); 423: } 424: 425: int main(int argc, char** argv) 426: { 427: char PGMfileName[MAX_FILE_LENGTH]; 428: 429: int WindowID; 430: 431: int i; /*looping variable*/ 432: 433: /*parse the command line*/ 434: if(argc == 1) 435: { 436: printf("To few parameters.\n"); 437: printf("Usage: research < file.pgm >\n"); 438: exit(1); 439: } 440: else if(argc == 2) 441: strcpy(PGMfileName, argv[1]); 442: else 443: { 444: printf("To many parameters.\n"); 445: printf("Usage: research < file.pgm >\n"); 446: exit(1); 447: } 448: /* 449: * Read in image file. - note: sets our global values, too. 450: * ----------------------------------------------------------------- */ 451: 452: img0 = (PGMImage*) malloc(sizeof(PGMImage)); 453: getPGMfile(PGMfileName, img0); 454: HSIZE = (*img0).width; 455: VSIZE = (*img0).height; 456: 457: img_cur = img0; /*VERY IMPORTANT to set this*/ 458: 459: /*allocate memory for second image*/ 460: img1 = (PGMImage*) malloc(sizeof(PGMImage)); 461: memcpy(img1, img0, sizeof(PGMImage)); 462: /*(*img1).width = HSIZE; 463: (*img1).height = VSIZE; 464: (*img1).maxVal = 255;*/ 465: 466: img2 = (PGMImage*) malloc(sizeof(PGMImage)); 467: memcpy(img2, img0, sizeof(PGMImage)); 468: 469: /* 470: * Initialize the glut package. 471: * ----------------------------------------------------------------- */ 472: glutInit(&argc, argv); 473: glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); 474: /* 475: * Define a new window (its size, position and title). 476: * ----------------------------------------------------------------- */ 477: glutInitWindowSize (HSIZE, VSIZE); /*size*/ 478: glutInitWindowPosition (10, 10); /*position*/ 479: WindowID = glutCreateWindow (PGMfileName); /*title*/ 480: glutSetWindow(WindowID); 481: glutDisplayFunc(color); 482: 483: /* 484: * Call our init function to define viewing parameters. 485: * ----------------------------------------------------------------- */ 486: init (); 487: 488: glutKeyboardFunc(keyboard); 489: glutMainLoop(); 490: 491: /* 492: * When we reach here, we've left the event loop and are ready to 493: * exit. 494: * ----------------------------------------------------------------- */ 495: return 0; 496: } 497: 498: 499: 500: 501: 502: 503: 504: 505: 506: 507: 508: 509: