main.c
Go to the documentation of this file.
00001 /*
00002  * 
00003  * This file is part of ARToolKit.
00004  * 
00005  * ARToolKit is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * ARToolKit is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with ARToolKit; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  * 
00019  */
00020 
00021 // ============================================================================
00022 //      Includes
00023 // ============================================================================
00024 
00025 #ifdef _WIN32
00026 #  include <windows.h>
00027 #endif
00028 #include <math.h>
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 #ifndef __APPLE__
00033 #  include <GL/glut.h>
00034 #  ifdef GL_VERSION_1_2
00035 #    include <GL/glext.h>
00036 #  endif
00037 #else
00038 #  include <GLUT/glut.h>
00039 #  include <OpenGL/glext.h>
00040 #endif
00041 #include <AR/config.h>
00042 #include <AR/video.h>
00043 #include <AR/param.h>
00044 #include <AR/matrix.h>
00045 #include <AR/gsub_lite.h>
00046 #include "calib_camera.h"
00047 
00048 // ============================================================================
00049 //      Constants
00050 // ============================================================================
00051 
00052 #define CALIB_CAMERA2_DEBUG 0
00053 
00054 // ============================================================================
00055 //      Global variables
00056 // ============================================================================
00057 
00058 /* set up the video format globals */
00059 
00060 #if defined(__sgi)
00061 static char            *vconf = "-size=FULL";
00062 #elif defined(__linux)
00063 #  if defined(AR_INPUT_GSTREAMER)
00064 char                    *vconf = "videotestsrc ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink";
00065 #  elif defined(AR_INPUT_V4L)
00066 static char            *vconf = "-width=640 -height=480";
00067 #  elif defined(AR_INPUT_1394CAM)
00068 static char            *vconf = "-mode=640x480_YUV411";
00069 #  elif defined(AR_INPUT_DV)
00070 static char            *vconf = "";
00071 #  endif
00072 #elif defined(_WIN32)
00073 static char                     *vconf = "Data\\WDM_camera_flipV.xml";
00074 #elif defined(__APPLE__)
00075 static char                     *vconf = "-width=640 -height=480";
00076 #else
00077 static char                     *vconf = "";
00078 #endif
00079 
00080 static ARUint8          *gARTImage = NULL;
00081 static ARParam          gARTCparam; // Dummy parameter, to supply to gsub_lite.
00082 static ARGL_CONTEXT_SETTINGS_REF gArglSettings = NULL;
00083 
00084 
00085 static int             gWin;
00086 static int             gXsize = 0;
00087 static int             gYsize = 0;
00088 static int             gThresh = THRESH;
00089 static unsigned char   *gClipImage = NULL;
00090 
00091 static CALIB_PATT_T    gPatt;          
00092 static double          dist_factor[4];
00093 static double          mat[3][4];
00094 
00095 static int             point_num;
00096 static int             gDragStartX = -1, gDragStartY = -1, gDragEndX = -1, gDragEndY = -1;      // x and y coordinates of start and end of mouse drag.
00097 
00098 static int             gStatus; // 0 = Waiting to grab image, 1 = Drawing bounding boxes, 2 = Placing warp lines.
00099 static int             check_num;
00100 
00101 // ============================================================================
00102 //      Functions
00103 // ============================================================================
00104 
00105 int             main(int argc, char *argv[]);
00106 static int      init(int argc, char *argv[]);
00107 static void     Mouse(int button, int state, int x, int y);
00108 static void     Motion(int x, int y);
00109 static void     Keyboard(unsigned char key, int x, int y);
00110 static void     Quit(void);
00111 static void     Idle(void);
00112 static void     Visibility(int visible);
00113 static void     Reshape(int w, int h);
00114 static void     Display(void);
00115 static void     draw_warp_line(double a, double b , double c);
00116 static void     draw_line(void);
00117 static void     draw_line2(double *x, double *y, int num);
00118 static void     draw_warp_line(double a, double b , double c);
00119 static void     print_comment(int status);
00120 static void     save_param(void);
00121 
00122 int main(int argc, char *argv[])
00123 {
00124         glutInit(&argc, argv);
00125     if (!init(argc, argv)) exit(-1);
00126         
00127     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
00128     glutInitWindowSize(gXsize, gYsize);
00129     glutInitWindowPosition(100,100);
00130     gWin = glutCreateWindow("Calibrate camera parameters");
00131         
00132         // Setup argl library for current context.
00133         // Turn off distortion compensation.. we don't know distortion yet!
00134         if ((gArglSettings = arglSetupForCurrentContext()) == NULL) {
00135                 fprintf(stderr, "main(): arglSetupForCurrentContext() returned error.\n");
00136                 exit(-1);
00137         }
00138         arglDistortionCompensationSet(gArglSettings, FALSE);
00139         
00140         // Make a dummy camera parameter to supply when calling arglDispImage().
00141         gARTCparam.xsize = gXsize;
00142         gARTCparam.ysize = gYsize;
00143         
00144         // Register GLUT event-handling callbacks.
00145         // NB: Idle() is registered by Visibility.
00146     glutDisplayFunc(Display);
00147         glutReshapeFunc(Reshape);
00148         glutVisibilityFunc(Visibility);
00149         glutKeyboardFunc(Keyboard);
00150     glutMouseFunc(Mouse);
00151     glutMotionFunc(Motion);
00152         
00153         // Start grabbing.
00154         if (arVideoCapStart() != 0) {
00155         fprintf(stderr, "init(): Unable to begin camera data capture.\n");
00156                 return (FALSE);         
00157         }
00158         point_num = 0;
00159     gStatus = 0;
00160     print_comment(0);
00161         
00162     glutMainLoop();
00163         
00164         return (0);
00165 }
00166 
00167 static int init(int argc, char *argv[])
00168 {
00169     double  length;
00170     char    line[512];
00171     int     i, j;
00172 
00173     gPatt.h_num    = H_NUM;
00174     gPatt.v_num    = V_NUM;
00175     gPatt.loop_num = 0;
00176     if (gPatt.h_num < 3 || gPatt.v_num < 3) exit(0);
00177 
00178     printf("Input the distance between each marker dot, in millimeters: ");
00179     scanf("%lf", &length);
00180         while (getchar() != '\n');
00181 
00182     gPatt.world_coord = (CALIB_COORD_T *)malloc(sizeof(CALIB_COORD_T) * gPatt.h_num * gPatt.v_num);
00183     for (j = 0; j < gPatt.v_num; j++) {
00184         for (i = 0; i < gPatt.h_num; i++) {
00185             gPatt.world_coord[j*gPatt.h_num+i].x_coord = length * i;
00186             gPatt.world_coord[j*gPatt.h_num+i].y_coord = length * j;
00187         }
00188     }
00189                 
00190         // Add command-line arguments to vconf string.
00191     strcpy(line, vconf);
00192     for (i = 1; i < argc; i++) {
00193         strcat(line, " ");
00194         strcat(line, argv[i]);
00195     }
00196         
00197         // Open the video path.
00198     if (arVideoOpen(line) < 0) {
00199         fprintf(stderr, "init(): Unable to open connection to camera.\n");
00200         return (FALSE);
00201         }
00202         
00203         // Find the size of the window.
00204     if (arVideoInqSize(&gXsize, &gYsize) < 0) return (FALSE);
00205     fprintf(stdout, "Camera image size (x,y) = (%d,%d)\n", gXsize, gYsize);
00206         
00207         // Allocate space for a clipping image (luminance only).
00208         arMalloc(gClipImage, unsigned char, gXsize * gYsize);
00209 
00210         return (TRUE);
00211 }
00212 
00213 static void grabImage(void) {
00214         ARUint8 *image;
00215         
00216         // Processing a new image.
00217         // Copy an image to saved image buffer.
00218         do {
00219                 image = arVideoGetImage();
00220         } while (image == NULL);
00221         gPatt.loop_num++;
00222         if ((gPatt.arglSettings[gPatt.loop_num-1] = arglSetupForCurrentContext()) == NULL) {
00223                 fprintf(stderr, "grabImage(): arglSetupForCurrentContext() returned error.\n");
00224                 exit(-1);
00225         }
00226         arglDistortionCompensationSet(gPatt.arglSettings[gPatt.loop_num-1], FALSE);
00227         arMalloc((gPatt.savedImage)[gPatt.loop_num-1], unsigned char, gXsize*gYsize*AR_PIX_SIZE_DEFAULT);
00228         memcpy((gPatt.savedImage)[gPatt.loop_num-1], image, gXsize*gYsize*AR_PIX_SIZE_DEFAULT);
00229         printf("Grabbed image %d.\n", gPatt.loop_num);
00230         arMalloc(gPatt.point[gPatt.loop_num-1], CALIB_COORD_T, gPatt.h_num*gPatt.v_num);
00231 }
00232 
00233 static void ungrabImage(void) {
00234         if (gPatt.loop_num == 0) {printf("error!!\n"); exit(0);}
00235         free(gPatt.point[gPatt.loop_num-1]);
00236         gPatt.point[gPatt.loop_num-1] = NULL;
00237         free(gPatt.savedImage[gPatt.loop_num-1]);
00238         gPatt.savedImage[gPatt.loop_num-1] = NULL;
00239         arglCleanup(gPatt.arglSettings[gPatt.loop_num-1]);
00240         gPatt.loop_num--;                       
00241 }
00242 
00243 void checkFit(void) {
00244     printf("\n-----------\n");
00245         if (check_num < gPatt.loop_num) {
00246                 printf("Checking fit on image %3d of %3d.\n", check_num + 1, gPatt.loop_num);
00247                 if (check_num + 1 < gPatt.loop_num) {
00248                         printf("Press mouse button to check fit of next image.\n");
00249                 } else {
00250                         printf("Press mouse button to calculate parameter.\n");
00251                 }
00252                 glutPostRedisplay();
00253         } else {
00254                 if (gPatt.loop_num > 1) {
00255                         if (calc_inp(&gPatt, dist_factor, gXsize, gYsize, mat) < 0) {
00256                                 printf("Calibration failed. Exiting.\n");
00257                                 exit(0);
00258                         } else {
00259                                 printf("Calibration succeeded. Enter filename to save camera parameter to below.\n");
00260                                 save_param();
00261                         }
00262                 } else {
00263                         printf("Not enough images to proceed with calibration. Exiting.\n");
00264                 }
00265                 Quit();
00266         }                               
00267 }
00268 
00269 static void eventCancel(void) {
00270         // What was cancelled?
00271         if (gStatus == 0) {
00272                 // Cancelled grabbing.
00273                 // Live video will not be needed from here on.
00274                 arVideoCapStop();
00275                 if (gPatt.loop_num == 0) {
00276                         // No images with all features identified, so quit.
00277                         Quit();
00278                 } else {
00279                         // At least one image with all features identified,
00280                         // so calculate distortion.
00281                         calc_distortion(&gPatt, gXsize, gYsize, dist_factor);
00282                         printf("--------------\n");
00283                         printf("Center X: %f\n", dist_factor[0]);
00284                         printf("       Y: %f\n", dist_factor[1]);
00285                         printf("Dist Factor: %f\n", dist_factor[2]);
00286                         printf("Size Adjust: %f\n", dist_factor[3]);
00287                         printf("--------------\n");
00288                         // Distortion calculation done. Check fit.
00289                         gStatus = 2;
00290                         check_num = 0;
00291                         checkFit();
00292                 }
00293         } else if (gStatus == 1) {
00294                 // Cancelled rubber-bounding.
00295                 ungrabImage();
00296                 // Restart grabbing.
00297                 point_num = 0;
00298                 arVideoCapStart();
00299                 gStatus = 0;
00300                 if (gPatt.loop_num == 0) print_comment(0);
00301                 else                     print_comment(4);      
00302         }
00303 }
00304 
00305 static void Mouse(int button, int state, int x, int y)
00306 {
00307     unsigned char   *p;
00308     int             ssx, ssy, eex, eey;
00309     int             i, j, k;
00310 
00311         if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
00312                 eventCancel();
00313         } else if (button == GLUT_LEFT_BUTTON) {
00314                 if (state == GLUT_DOWN) {
00315                         if (gStatus == 0 && gPatt.loop_num < LOOP_MAX) {
00316                                 // End grabbing.
00317                                 // Begin waiting for drag for rubber-bounding of a feature.
00318                                 grabImage();
00319                                 gDragStartX = gDragStartY = gDragEndX = gDragEndY = -1;
00320                                 arVideoCapStop();
00321                                 gStatus = 1;
00322                                 print_comment(1);                               
00323                         } else if (gStatus == 1) {
00324                                 if (point_num < gPatt.h_num*gPatt.v_num) {
00325                                         // Drag for rubber-bounding of a feature has begun.
00326                                         gDragStartX = gDragEndX = x;
00327                                         gDragStartY = gDragEndY = y;
00328                                 } else {
00329                                         // Feature point locations have been accepted.
00330                                         printf("### Image no.%d ###\n", gPatt.loop_num);
00331                                         for( j = 0; j < gPatt.v_num; j++ ) {
00332                                                 for( i = 0; i < gPatt.h_num; i++ ) {
00333                                                         printf("%2d, %2d: %6.2f, %6.2f\n", i+1, j+1,
00334                                                                    gPatt.point[gPatt.loop_num-1][j*gPatt.h_num+i].x_coord,
00335                                                                    gPatt.point[gPatt.loop_num-1][j*gPatt.h_num+i].y_coord);
00336                                                 }
00337                                         }
00338                                         printf("\n\n");
00339                                         // Restart grabbing.
00340                                         point_num = 0;
00341                                         arVideoCapStart();
00342                                         gStatus = 0;
00343                                         if (gPatt.loop_num < LOOP_MAX) print_comment(4);
00344                                         else                           print_comment(5);
00345                                 }
00346                         } else if (gStatus == 2) {
00347                                 check_num++;
00348                                 checkFit();
00349                         }
00350                 } else if (state == GLUT_UP) {
00351                         if (gStatus == 1
00352                                  && gDragStartX != -1 && gDragStartY != -1
00353                                  && gDragEndX != -1 && gDragEndY != -1
00354                                  && point_num < gPatt.h_num*gPatt.v_num) {
00355                                 // Drag for rubber-bounding of a feature has finished. Begin identification
00356                                 // of center of white region in gClipImage.
00357                                 if (gDragStartX < gDragEndX) { ssx = gDragStartX; eex = gDragEndX; }
00358                                 else         { ssx = gDragEndX; eex = gDragStartX; }
00359                                 if (gDragStartY < gDragEndY) { ssy = gDragStartY; eey = gDragEndY; }
00360                                 else         { ssy = gDragEndY; eey = gDragStartY; }
00361                                 
00362                                 gPatt.point[gPatt.loop_num-1][point_num].x_coord = 0.0;
00363                                 gPatt.point[gPatt.loop_num-1][point_num].y_coord = 0.0;
00364                                 p = gClipImage;
00365                                 k = 0;
00366                                 for (j = 0; j < (eey-ssy+1); j++) {
00367                                         for (i = 0; i < (eex-ssx+1); i++) {
00368                                                 gPatt.point[gPatt.loop_num-1][point_num].x_coord += i * *p;
00369                                                 gPatt.point[gPatt.loop_num-1][point_num].y_coord += j * *p;
00370                                                 k += *p;
00371                                                 p++;
00372                                         }
00373                                 }
00374                                 if (k != 0) {
00375                                         gPatt.point[gPatt.loop_num-1][point_num].x_coord /= k;
00376                                         gPatt.point[gPatt.loop_num-1][point_num].y_coord /= k;
00377                                         gPatt.point[gPatt.loop_num-1][point_num].x_coord += ssx;
00378                                         gPatt.point[gPatt.loop_num-1][point_num].y_coord += ssy;
00379                                         point_num++;
00380                                         printf("Marked feature position %3d of %3d\n", point_num, gPatt.h_num*gPatt.v_num);
00381                                         if (point_num == gPatt.h_num*gPatt.v_num) print_comment(2);
00382                                 }
00383                                 gDragStartX = gDragStartY = gDragEndX = gDragEndY = -1;
00384                                 glutPostRedisplay();
00385                         }
00386                 }
00387         }
00388 }
00389 
00390 static void Motion(int x, int y)
00391 {
00392     unsigned char   *p, *p1;
00393     int             ssx, ssy, eex, eey;
00394     int             i, j;
00395         
00396         // During mouse drag.
00397     if (gStatus == 1 && gDragStartX != -1 && gDragStartY != -1) {
00398                 
00399                 // Set x,y of end of mouse drag region.
00400         gDragEndX = x;
00401         gDragEndY = y;
00402                 
00403                 // Check that start is above and to left of end.
00404                 if (gDragStartX < gDragEndX) { ssx = gDragStartX; eex = gDragEndX; }
00405                 else         { ssx = gDragEndX; eex = gDragStartX; }
00406                 if (gDragStartY < gDragEndY) { ssy = gDragStartY; eey = gDragEndY; }
00407                 else         { ssy = gDragEndY; eey = gDragStartY; }
00408                 
00409                 // Threshold clipping area, copy it into gClipImage.
00410         p1 = gClipImage;
00411         for (j = ssy; j <= eey; j++) {
00412             p = &(gPatt.savedImage[gPatt.loop_num-1][(j*gXsize+ssx)*AR_PIX_SIZE_DEFAULT]);
00413             for (i = ssx; i <= eex; i++) {
00414 #if (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGRA)
00415                 *p1 = (((255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3) < gThresh ? 0 : 255);
00416 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_ABGR)
00417                 *p1 = (((255*3 - (*(p+1) + *(p+2) + *(p+3))) / 3) < gThresh ? 0 : 255);
00418 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_ARGB)
00419                 *p1 = (((255*3 - (*(p+1) + *(p+2) + *(p+3))) / 3) < gThresh ? 0 : 255);
00420 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_BGR)
00421                 *p1 = (((255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3) < gThresh ? 0 : 255);
00422 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_RGBA)
00423                 *p1 = (((255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3) < gThresh ? 0 : 255);
00424 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_RGB)
00425                 *p1 = (((255*3 - (*(p+0) + *(p+1) + *(p+2))) / 3) < gThresh ? 0 : 255);
00426 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_2vuy)
00427                 *p1 = ((255 - *(p+1)) < gThresh ? 0 : 255);
00428 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_yuvs)
00429                 *p1 = ((255 - *(p+0)) < gThresh ? 0 : 255);
00430 #elif (AR_DEFAULT_PIXEL_FORMAT == AR_PIXEL_FORMAT_MONO)
00431                 *p1 = ((255 - *(p)) < gThresh ? 0 : 255);
00432 #else
00433 #  error Unknown default pixel format defined in config.h
00434 #endif
00435                 p  += AR_PIX_SIZE_DEFAULT;
00436                 p1++;
00437             }
00438         }
00439                 // Tell GLUT the display has changed.
00440                 glutPostRedisplay();
00441     }
00442 }
00443 
00444 static void Keyboard(unsigned char key, int x, int y)
00445 {
00446         switch (key) {
00447                 case 0x1B:
00448                         eventCancel();
00449                         break;
00450                 case 'T':
00451                 case 't':
00452                         printf("Enter new threshold value (now = %d): ", gThresh);
00453                         scanf("%d",&gThresh); while( getchar()!='\n' );
00454                         printf("\n");
00455                         break;
00456                 case '1':
00457                         gThresh -= 5;
00458                         if (gThresh < 0) gThresh = 0;
00459                         break;
00460                 case '2':
00461                         gThresh += 5;
00462                         if (gThresh > 255) gThresh = 255;
00463                         break;
00464                 default:
00465                         break;
00466         }
00467 }
00468 
00469 static void Quit(void)
00470 {
00471         if (gClipImage) {
00472                 free(gClipImage);
00473                 gClipImage = NULL;
00474         }
00475         if (gArglSettings) arglCleanup(gArglSettings);
00476         if (gWin) glutDestroyWindow(gWin);
00477         arVideoClose();
00478         exit(0);
00479 }
00480 
00481 static void Idle(void)
00482 {
00483         static int ms_prev;
00484         int ms;
00485         float s_elapsed;
00486         ARUint8 *image;
00487         
00488         // Find out how long since Idle() last ran.
00489         ms = glutGet(GLUT_ELAPSED_TIME);
00490         s_elapsed = (float)(ms - ms_prev) * 0.001;
00491         if (s_elapsed < 0.01f) return; // Don't update more often than 100 Hz.
00492         ms_prev = ms;
00493         
00494         // Grab a video frame.
00495         if (gStatus == 0) {
00496                 if ((image = arVideoGetImage()) != NULL) {
00497                         gARTImage = image;
00498                         // Tell GLUT the display has changed.
00499                         glutPostRedisplay();
00500                 }       
00501         }
00502 }
00503 
00504 //
00505 //      This function is called on events when the visibility of the
00506 //      GLUT window changes (including when it first becomes visible).
00507 //
00508 static void Visibility(int visible)
00509 {
00510         if (visible == GLUT_VISIBLE) {
00511                 glutIdleFunc(Idle);
00512         } else {
00513                 glutIdleFunc(NULL);
00514         }
00515 }
00516 
00517 //
00518 //      This function is called when the
00519 //      GLUT window is resized.
00520 //
00521 static void Reshape(int w, int h)
00522 {
00523         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00524         glViewport(0, 0, (GLsizei) w, (GLsizei) h);
00525         
00526         glMatrixMode(GL_PROJECTION);
00527         glLoadIdentity();
00528         glMatrixMode(GL_MODELVIEW);
00529         glLoadIdentity();
00530         
00531         // Call through to anyone else who needs to know about window sizing here.
00532 }
00533 
00534 static void beginOrtho2D(int xsize, int ysize) {
00535         glMatrixMode(GL_PROJECTION);
00536         glPushMatrix();
00537         glLoadIdentity();
00538         gluOrtho2D(0.0, xsize, 0.0, ysize);
00539         glMatrixMode(GL_MODELVIEW);
00540         glPushMatrix();
00541         glLoadIdentity();       
00542 }
00543 
00544 static void endOrtho2D(void) {
00545         glMatrixMode(GL_PROJECTION);
00546         glPopMatrix();
00547         glMatrixMode(GL_MODELVIEW);
00548         glPopMatrix();
00549 }
00550 
00551 static void Display(void)
00552 {
00553     double         x, y;
00554     int            ssx, eex, ssy, eey;
00555     int            i;
00556 
00557         // Select correct buffer for this context.
00558         glDrawBuffer(GL_BACK);
00559         glClear(GL_COLOR_BUFFER_BIT);
00560     glDisable(GL_DEPTH_TEST);
00561         glDisable(GL_LIGHTING);
00562         glDisable(GL_TEXTURE_2D);
00563         beginOrtho2D(gXsize, gYsize);
00564 
00565     if (gStatus == 0) {
00566                 
00567                 arglDispImage(gARTImage, &gARTCparam, 1.0, gArglSettings);      // zoom = 1.0.
00568                 arVideoCapNext();
00569                 gARTImage = NULL;
00570                 
00571     } else if (gStatus == 1) {
00572                 
00573         arglDispImage(gPatt.savedImage[gPatt.loop_num-1], &gARTCparam, 1.0, gPatt.arglSettings[gPatt.loop_num-1]);
00574                 // Draw red crosses on the points in the image.
00575         for (i = 0; i < point_num; i++) {
00576             x = gPatt.point[gPatt.loop_num-1][i].x_coord;
00577             y = gPatt.point[gPatt.loop_num-1][i].y_coord;
00578             glColor3f(1.0f, 0.0f, 0.0f);
00579             glBegin(GL_LINES);
00580               glVertex2d(x-10.0, (GLdouble)(gYsize-1)-y);
00581               glVertex2d(x+10.0, (GLdouble)(gYsize-1)-y);
00582               glVertex2d(x, (GLdouble)(gYsize-1)-(y-10.0));
00583               glVertex2d(x, (GLdouble)(gYsize-1)-(y+10.0));
00584             glEnd();
00585         }
00586                 
00587                 // Draw the current mouse drag clipping area.
00588         if (gDragStartX != -1 && gDragStartY != -1
00589                         && gDragEndX != -1 && gDragEndY != -1) {
00590                         if (gDragStartX < gDragEndX) { ssx = gDragStartX; eex = gDragEndX; }
00591                         else         { ssx = gDragEndX; eex = gDragStartX; }
00592                         if (gDragStartY < gDragEndY) { ssy = gDragStartY; eey = gDragEndY; }
00593                         else         { ssy = gDragEndY; eey = gDragStartY; }
00594 #if 1
00595                         if (gClipImage) {
00596                                 glPixelZoom(1.0f, -1.0f);       // ARToolKit bitmap 0.0 is at upper-left, OpenGL bitmap 0.0 is at lower-left.
00597                                 glRasterPos2f((GLfloat)(ssx), (GLfloat)(gYsize-1-ssy));
00598                                 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00599                                 glDrawPixels(eex-ssx+1, eey-ssy+1, GL_LUMINANCE, GL_UNSIGNED_BYTE, gClipImage);
00600                         }
00601 #else
00602             glColor3f(0.0f, 0.0f, 1.0f);
00603             glBegin(GL_LINE_LOOP);
00604               glVertex2i(gDragStartX, (gYsize-1)-gDragStartY);
00605               glVertex2i(gDragEndX, (gYsize-1)-gDragStartY);
00606               glVertex2i(gDragEndX, (gYsize-1)-gDragEndY);
00607               glVertex2i(gDragStartX, (gYsize-1)-gDragEndY);
00608             glEnd();
00609 #endif
00610         }
00611                 
00612     } else if (gStatus == 2) {
00613                 
00614         arglDispImage(gPatt.savedImage[check_num], &gARTCparam, 1.0, gPatt.arglSettings[check_num]);
00615         for (i = 0; i < gPatt.h_num*gPatt.v_num; i++) {
00616             x = gPatt.point[check_num][i].x_coord;
00617             y = gPatt.point[check_num][i].y_coord;
00618             glColor3f(1.0f, 0.0f, 0.0f);
00619             glBegin(GL_LINES);
00620                         glVertex2d(x-10.0, (GLdouble)(gYsize-1)-y);
00621                         glVertex2d(x+10.0, (GLdouble)(gYsize-1)-y);
00622                         glVertex2d(x, (GLdouble)(gYsize-1)-(y-10.0));
00623                         glVertex2d(x, (GLdouble)(gYsize-1)-(y+10.0));
00624             glEnd();
00625         }
00626         draw_line();
00627                 
00628     }
00629 
00630         endOrtho2D();
00631     glutSwapBuffers();
00632 }
00633 
00634 static void draw_line(void)
00635 {
00636     double   *x, *y;
00637     int      max;
00638     // int      num; // unreferenced
00639     int      i, j, k, l;
00640     int      p;
00641 
00642     max = (gPatt.v_num > gPatt.h_num) ? gPatt.v_num : gPatt.h_num;
00643     arMalloc(x, double, max);
00644     arMalloc(y, double, max);
00645 
00646     i = check_num;
00647 
00648     for (j = 0; j < gPatt.v_num; j++) {
00649         for (k = 0; k < gPatt.h_num; k++) {
00650             x[k] = gPatt.point[i][j*gPatt.h_num+k].x_coord;
00651             y[k] = gPatt.point[i][j*gPatt.h_num+k].y_coord;
00652         }
00653         draw_line2(x, y, gPatt.h_num);
00654     }
00655 
00656     for (j = 0; j < gPatt.h_num; j++) {
00657         for (k = 0; k < gPatt.v_num; k++) {
00658             x[k] = gPatt.point[i][k*gPatt.h_num+j].x_coord;
00659             y[k] = gPatt.point[i][k*gPatt.h_num+j].y_coord;
00660         }
00661         draw_line2(x, y, gPatt.v_num);
00662     }
00663 
00664     for (j = 3 - gPatt.v_num; j < gPatt.h_num - 2; j++) {
00665         p = 0;
00666         for (k = 0; k < gPatt.v_num; k++) {
00667             l = j+k;
00668             if (l < 0 || l >= gPatt.h_num) continue;
00669             x[p] = gPatt.point[i][k*gPatt.h_num+l].x_coord;
00670             y[p] = gPatt.point[i][k*gPatt.h_num+l].y_coord;
00671             p++;
00672         }
00673         draw_line2(x, y, p);
00674     }
00675 
00676     for (j = 2; j < gPatt.h_num + gPatt.v_num - 3; j++) {
00677         p = 0;
00678         for (k = 0; k < gPatt.v_num; k++) {
00679             l = j-k;
00680             if (l < 0 || l >= gPatt.h_num) continue;
00681             x[p] = gPatt.point[i][k*gPatt.h_num+l].x_coord;
00682             y[p] = gPatt.point[i][k*gPatt.h_num+l].y_coord;
00683             p++;
00684         }
00685         draw_line2(x, y, p);
00686     }
00687 
00688     free(x);
00689     free(y);
00690 }
00691 
00692 static void draw_line2( double *x, double *y, int num )
00693 {
00694     ARMat    *input, *evec;
00695     ARVec    *ev, *mean;
00696     double   a, b, c;
00697     int      i;
00698 
00699     ev     = arVecAlloc(2);
00700     mean   = arVecAlloc(2);
00701     evec   = arMatrixAlloc(2, 2);
00702 
00703     input  = arMatrixAlloc(num, 2);
00704     for (i = 0; i < num; i++) {
00705         arParamObserv2Ideal(dist_factor, x[i], y[i],
00706                              &(input->m[i*2+0]), &(input->m[i*2+1]));
00707     }
00708     if (arMatrixPCA(input, evec, ev, mean) < 0) exit(0);
00709     a =  evec->m[1];
00710     b = -evec->m[0];
00711     c = -(a*mean->v[0] + b*mean->v[1]);
00712 
00713     arMatrixFree(input);
00714     arMatrixFree(evec);
00715     arVecFree(mean);
00716     arVecFree(ev);
00717 
00718     draw_warp_line(a, b, c);
00719 }
00720 
00721 static void draw_warp_line(double a, double b , double c)
00722 {
00723     double   x, y;
00724     double   x1, y1;
00725     int      i;
00726 
00727     glLineWidth(1.0f);
00728     glBegin(GL_LINE_STRIP);
00729     if (a*a >= b*b) {
00730         for (i = -20; i <= gYsize+20; i+=10) {
00731             x = -(b*i + c)/a;
00732             y = i;
00733 
00734             arParamIdeal2Observ(dist_factor, x, y, &x1, &y1);
00735             glVertex2f(x1, gYsize-1-y1);
00736         }
00737     } else {
00738         for(i = -20; i <= gXsize+20; i+=10) {
00739             x = i;
00740             y = -(a*i + c)/b;
00741 
00742             arParamIdeal2Observ(dist_factor, x, y, &x1, &y1);
00743             glVertex2f(x1, gYsize-1-y1);
00744         }
00745     }
00746     glEnd();
00747 }
00748 
00749 static void print_comment(int status)
00750 {
00751     printf("\n-----------\n");
00752     switch(status) {
00753         case 0:
00754                         printf("Press mouse button to grab first image,\n");
00755                         printf("or press right mouse button or [esc] to quit.\n");
00756                         break;
00757         case 1:
00758                         printf("Press mouse button and drag mouse to rubber-bound features (%d x %d),\n", gPatt.h_num, gPatt.v_num);
00759                         printf("or press right mouse button or [esc] to cancel rubber-bounding & retry grabbing.\n");
00760                         break;
00761         case 2:
00762                         printf("Press mouse button to save feature positions,\n");
00763                         printf("or press right mouse button or [esc] to discard feature positions & retry grabbing.\n");
00764                         break;
00765         case 4:
00766                         printf("Press mouse button to grab next image,\n");
00767                         printf("or press right mouse button or [esc] to calculate distortion parameter.\n");
00768                         break;
00769         case 5:
00770                         printf("Press right mouse button or [esc] to calculate distortion parameter.\n");
00771                         break;
00772     }
00773 }
00774 
00775 static void save_param(void)
00776 {
00777     char     name[256];
00778     ARParam  param;
00779     int      i, j;
00780         
00781     param.xsize = gXsize;
00782     param.ysize = gYsize;
00783     for (i = 0; i < 4; i++) param.dist_factor[i] = dist_factor[i];
00784     for (j = 0; j < 3; j++) {
00785         for (i = 0; i < 4; i++) {
00786             param.mat[j][i] = mat[j][i];
00787         }
00788     }
00789     arParamDisp( &param );
00790         
00791     printf("Filename: ");
00792     scanf( "%s", name );
00793     arParamSave( name, 1, &param );
00794         
00795     return;
00796 }
00797 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


ar_recog
Author(s): Graylin Trevor Jay and Christopher Crick
autogenerated on Fri Jan 25 2013 12:15:00