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