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: