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_dist.h"
00047
00048
00049
00050
00051
00052 #define CALIB_DIST_DEBUG 0
00053
00054
00055
00056
00057
00058
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;
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;
00095
00096 static int gStatus;
00097 static int check_num;
00098
00099
00100
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
00130
00131 if ((gArglSettings = arglSetupForCurrentContext()) == NULL) {
00132 fprintf(stderr, "main(): arglSetupForCurrentContext() returned error.\n");
00133 exit(-1);
00134 }
00135 arglDistortionCompensationSet(gArglSettings, FALSE);
00136
00137
00138 gARTCparam.xsize = gXsize;
00139 gARTCparam.ysize = gYsize;
00140
00141
00142
00143 glutDisplayFunc(Display);
00144 glutReshapeFunc(Reshape);
00145 glutVisibilityFunc(Visibility);
00146 glutKeyboardFunc(Keyboard);
00147 glutMouseFunc(Mouse);
00148 glutMotionFunc(Motion);
00149
00150
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
00175 strcpy(line, vconf);
00176 for (i = 1; i < argc; i++) {
00177 strcat(line, " ");
00178 strcat(line, argv[i]);
00179 }
00180
00181
00182 if (arVideoOpen(line) < 0) {
00183 fprintf(stderr, "init(): Unable to open connection to camera.\n");
00184 return (FALSE);
00185 }
00186
00187
00188 if (arVideoInqSize(&gXsize, &gYsize) < 0) return (FALSE);
00189 fprintf(stdout, "Camera image size (x,y) = (%d,%d)\n", gXsize, gYsize);
00190
00191
00192 arMalloc(gClipImage, unsigned char, gXsize * gYsize);
00193
00194 return (TRUE);
00195 }
00196
00197 static void grabImage(void) {
00198 ARUint8 *image;
00199
00200
00201
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
00244 if (gStatus == 0) {
00245
00246
00247 arVideoCapStop();
00248 if (gPatt.loop_num == 0) {
00249
00250 Quit();
00251 } else {
00252
00253
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
00262 gStatus = 2;
00263 check_num = 0;
00264 checkFit();
00265 }
00266 } else if (gStatus == 1) {
00267
00268 ungrabImage();
00269
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
00290
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
00299 gDragStartX = gDragEndX = x;
00300 gDragStartY = gDragEndY = y;
00301 } else {
00302
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
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
00329
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
00370 if (gStatus == 1 && gDragStartX != -1 && gDragStartY != -1) {
00371
00372
00373 gDragEndX = x;
00374 gDragEndY = y;
00375
00376
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
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
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
00462 ms = glutGet(GLUT_ELAPSED_TIME);
00463 s_elapsed = (float)(ms - ms_prev) * 0.001;
00464 if (s_elapsed < 0.01f) return;
00465 ms_prev = ms;
00466
00467
00468 if (gStatus == 0) {
00469 if ((image = arVideoGetImage()) != NULL) {
00470 gARTImage = image;
00471
00472 glutPostRedisplay();
00473 }
00474 }
00475 }
00476
00477
00478
00479
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
00492
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
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
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);
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
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
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);
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
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 }