00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00050
00051
00052 #define CALIB_CAMERA2_DEBUG 0
00053
00054
00055
00056
00057
00058
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;
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;
00097
00098 static int gStatus;
00099 static int check_num;
00100
00101
00102
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
00133
00134 if ((gArglSettings = arglSetupForCurrentContext()) == NULL) {
00135 fprintf(stderr, "main(): arglSetupForCurrentContext() returned error.\n");
00136 exit(-1);
00137 }
00138 arglDistortionCompensationSet(gArglSettings, FALSE);
00139
00140
00141 gARTCparam.xsize = gXsize;
00142 gARTCparam.ysize = gYsize;
00143
00144
00145
00146 glutDisplayFunc(Display);
00147 glutReshapeFunc(Reshape);
00148 glutVisibilityFunc(Visibility);
00149 glutKeyboardFunc(Keyboard);
00150 glutMouseFunc(Mouse);
00151 glutMotionFunc(Motion);
00152
00153
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
00191 strcpy(line, vconf);
00192 for (i = 1; i < argc; i++) {
00193 strcat(line, " ");
00194 strcat(line, argv[i]);
00195 }
00196
00197
00198 if (arVideoOpen(line) < 0) {
00199 fprintf(stderr, "init(): Unable to open connection to camera.\n");
00200 return (FALSE);
00201 }
00202
00203
00204 if (arVideoInqSize(&gXsize, &gYsize) < 0) return (FALSE);
00205 fprintf(stdout, "Camera image size (x,y) = (%d,%d)\n", gXsize, gYsize);
00206
00207
00208 arMalloc(gClipImage, unsigned char, gXsize * gYsize);
00209
00210 return (TRUE);
00211 }
00212
00213 static void grabImage(void) {
00214 ARUint8 *image;
00215
00216
00217
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
00271 if (gStatus == 0) {
00272
00273
00274 arVideoCapStop();
00275 if (gPatt.loop_num == 0) {
00276
00277 Quit();
00278 } else {
00279
00280
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
00289 gStatus = 2;
00290 check_num = 0;
00291 checkFit();
00292 }
00293 } else if (gStatus == 1) {
00294
00295 ungrabImage();
00296
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
00317
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
00326 gDragStartX = gDragEndX = x;
00327 gDragStartY = gDragEndY = y;
00328 } else {
00329
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
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
00356
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
00397 if (gStatus == 1 && gDragStartX != -1 && gDragStartY != -1) {
00398
00399
00400 gDragEndX = x;
00401 gDragEndY = y;
00402
00403
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
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
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
00489 ms = glutGet(GLUT_ELAPSED_TIME);
00490 s_elapsed = (float)(ms - ms_prev) * 0.001;
00491 if (s_elapsed < 0.01f) return;
00492 ms_prev = ms;
00493
00494
00495 if (gStatus == 0) {
00496 if ((image = arVideoGetImage()) != NULL) {
00497 gARTImage = image;
00498
00499 glutPostRedisplay();
00500 }
00501 }
00502 }
00503
00504
00505
00506
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
00519
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
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
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);
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
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
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);
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
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( ¶m );
00790
00791 printf("Filename: ");
00792 scanf( "%s", name );
00793 arParamSave( name, 1, ¶m );
00794
00795 return;
00796 }
00797