arMultiGetTransMat.c
Go to the documentation of this file.
00001 /*******************************************************
00002  *
00003  * Author: Hirokazu Kato
00004  *
00005  *         kato@sys.im.hiroshima-cu.ac.jp
00006  *
00007  * Revision: 1.0
00008  * Date: 01/09/05
00009  *
00010 *******************************************************/
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <math.h>
00014 #include <AR/ar.h>
00015 #include <AR/matrix.h>
00016 #include <AR/arMulti.h>
00017 
00018 #define  debug  0
00019 
00020 #define  THRESH_1            2.0
00021 #define  THRESH_2           20.0
00022 #define  THRESH_3           10.0
00023 #define  AR_MULTI_GET_TRANS_MAT_MAX_LOOP_COUNT   2
00024 #define  AR_MULTI_GET_TRANS_MAT_MAX_FIT_ERROR    10.0
00025 
00026 typedef struct {
00027     double   pos[4][2];
00028     double   thresh;
00029     double   err;
00030     int      marker;
00031     int      dir;
00032 } arMultiEachMarkerInternalInfoT;
00033 
00034 static int verify_markers(ARMarkerInfo *marker_info, int marker_num,
00035                           ARMultiMarkerInfoT *config);
00036 
00037 
00038 double arMultiGetTransMat(ARMarkerInfo *marker_info, int marker_num,
00039                           ARMultiMarkerInfoT *config)
00040 {
00041     double                *pos2d, *pos3d;
00042     double                rot[3][3], trans1[3][4], trans2[3][4];
00043     double                err, err2;
00044     int                   max, max_area, max_marker, vnum;
00045     int                   dir;
00046     int                   i, j, k;
00047 
00048     if( config->prevF ) {
00049         verify_markers( marker_info, marker_num, config );
00050     }
00051 
00052     max = -1;
00053     vnum = 0;
00054     for( i = 0; i < config->marker_num; i++ ) {
00055         k = -1;
00056         for( j = 0; j < marker_num; j++ ) {
00057             if( marker_info[j].id != config->marker[i].patt_id ) continue;
00058             if( marker_info[j].cf < 0.70 ) continue;
00059 
00060             if( k == -1 ) k = j;
00061             else if( marker_info[k].cf < marker_info[j].cf ) k = j;
00062         }
00063         if( (config->marker[i].visible=k) == -1) continue;
00064 
00065         err = arGetTransMat(&marker_info[k], config->marker[i].center,
00066                             config->marker[i].width, trans1);
00067 #if debug
00068 printf("##err = %10.5f %d %10.5f %10.5f\n", err, marker_info[k].dir, marker_info[k].pos[0], marker_info[k].pos[1]);
00069 #endif
00070         if( err > THRESH_1 ) {
00071             config->marker[i].visible = -1;
00072             continue;
00073         }
00074 
00075         vnum++;
00076         if( max == -1 
00077          || marker_info[k].area > max_area ) {
00078             max = i;
00079             max_marker = k;
00080             max_area   = marker_info[k].area;
00081             for( j = 0; j < 3; j++ ) {
00082                 for( k = 0; k < 4; k++ ) {
00083                     trans2[j][k] = trans1[j][k];
00084                 }
00085             }
00086         }
00087     }
00088     if( max == -1 ) {
00089         config->prevF = 0;
00090         return -1;
00091     }
00092 
00093     arMalloc(pos2d, double, vnum*4*2);
00094     arMalloc(pos3d, double, vnum*4*3);
00095 
00096     j = 0;
00097     for( i = 0; i < config->marker_num; i++ ) {
00098         if( (k=config->marker[i].visible) < 0 ) continue;
00099 
00100         dir = marker_info[k].dir;
00101         pos2d[j*8+0] = marker_info[k].vertex[(4-dir)%4][0];
00102         pos2d[j*8+1] = marker_info[k].vertex[(4-dir)%4][1];
00103         pos2d[j*8+2] = marker_info[k].vertex[(5-dir)%4][0];
00104         pos2d[j*8+3] = marker_info[k].vertex[(5-dir)%4][1];
00105         pos2d[j*8+4] = marker_info[k].vertex[(6-dir)%4][0];
00106         pos2d[j*8+5] = marker_info[k].vertex[(6-dir)%4][1];
00107         pos2d[j*8+6] = marker_info[k].vertex[(7-dir)%4][0];
00108         pos2d[j*8+7] = marker_info[k].vertex[(7-dir)%4][1];
00109         pos3d[j*12+0] = config->marker[i].pos3d[0][0];
00110         pos3d[j*12+1] = config->marker[i].pos3d[0][1];
00111         pos3d[j*12+2] = config->marker[i].pos3d[0][2];
00112         pos3d[j*12+3] = config->marker[i].pos3d[1][0];
00113         pos3d[j*12+4] = config->marker[i].pos3d[1][1];
00114         pos3d[j*12+5] = config->marker[i].pos3d[1][2];
00115         pos3d[j*12+6] = config->marker[i].pos3d[2][0];
00116         pos3d[j*12+7] = config->marker[i].pos3d[2][1];
00117         pos3d[j*12+8] = config->marker[i].pos3d[2][2];
00118         pos3d[j*12+9] = config->marker[i].pos3d[3][0];
00119         pos3d[j*12+10] = config->marker[i].pos3d[3][1];
00120         pos3d[j*12+11] = config->marker[i].pos3d[3][2];
00121         j++;
00122     }
00123 
00124     if( config->prevF ) {
00125         for( j = 0; j < 3; j++ ) {
00126             for( i = 0; i < 3; i++ ) {
00127                 rot[j][i] = config->trans[j][i];
00128             }
00129         }
00130         for( i = 0; i < AR_MULTI_GET_TRANS_MAT_MAX_LOOP_COUNT; i++ ) {
00131             err = arGetTransMat4( rot, (double (*)[2])pos2d,
00132                                        (double (*)[3])pos3d,
00133                                         vnum*4, config->trans );
00134             if( err < AR_MULTI_GET_TRANS_MAT_MAX_FIT_ERROR ) break;
00135         }
00136 
00137         if( err < THRESH_2 ) {
00138             config->prevF = 1;
00139             free(pos3d);
00140             free(pos2d);
00141             return err;
00142         }
00143     }
00144 
00145     arUtilMatMul( trans2, config->marker[max].itrans, trans1 );
00146     for( j = 0; j < 3; j++ ) {
00147         for( i = 0; i < 3; i++ ) {
00148             rot[j][i] = trans1[j][i];
00149         }
00150     }
00151 
00152     for( i = 0; i < AR_MULTI_GET_TRANS_MAT_MAX_LOOP_COUNT; i++ ) {
00153         err2 = arGetTransMat4( rot, (double (*)[2])pos2d, (double (*)[3])pos3d,
00154                               vnum*4, trans2 );
00155         if( err2 < AR_MULTI_GET_TRANS_MAT_MAX_FIT_ERROR ) break;
00156     }
00157 
00158     if( config->prevF == 0 || err2 < err ) {
00159         for( j = 0; j < 3; j++ ) {
00160             for( i = 0; i < 4; i++ ) {
00161                 config->trans[j][i] = trans2[j][i];
00162             }
00163         }
00164         err = err2;
00165     }
00166 
00167     if( err < THRESH_3 ) {
00168         config->prevF = 1;
00169     }
00170     else {
00171         config->prevF = 0;
00172     }
00173 
00174     free(pos3d);
00175     free(pos2d);
00176     return err;
00177 }
00178 
00179 static int verify_markers(ARMarkerInfo *marker_info, int marker_num,
00180                           ARMultiMarkerInfoT *config)
00181 {
00182     arMultiEachMarkerInternalInfoT *winfo;
00183     double                         wtrans[3][4];
00184     double                         pos3d[4][2];
00185     double                         wx, wy, wz, hx, hy, h;
00186     int                            dir1, dir2, marker2;
00187     double                         err, err1, err2;
00188     double                         x1, x2, y1, y2;
00189     int                            w1, w2;
00190     int                            i, j, k;
00191 
00192     arMalloc(winfo,arMultiEachMarkerInternalInfoT,config->marker_num);
00193 
00194     for( i = 0; i < config->marker_num; i++ ) {
00195         arUtilMatMul(config->trans, config->marker[i].trans, wtrans);
00196         pos3d[0][0] = config->marker[i].center[0] - config->marker[i].width/2.0;
00197         pos3d[0][1] = config->marker[i].center[1] + config->marker[i].width/2.0;
00198         pos3d[1][0] = config->marker[i].center[0] + config->marker[i].width/2.0;
00199         pos3d[1][1] = config->marker[i].center[1] + config->marker[i].width/2.0;
00200         pos3d[2][0] = config->marker[i].center[0] + config->marker[i].width/2.0;
00201         pos3d[2][1] = config->marker[i].center[1] - config->marker[i].width/2.0;
00202         pos3d[3][0] = config->marker[i].center[0] - config->marker[i].width/2.0;
00203         pos3d[3][1] = config->marker[i].center[1] - config->marker[i].width/2.0;
00204         for( j = 0; j < 4; j++ ) {
00205             wx = wtrans[0][0] * pos3d[j][0]
00206                + wtrans[0][1] * pos3d[j][1]
00207                + wtrans[0][3];
00208             wy = wtrans[1][0] * pos3d[j][0]
00209                + wtrans[1][1] * pos3d[j][1]
00210                + wtrans[1][3];
00211             wz = wtrans[2][0] * pos3d[j][0]
00212                + wtrans[2][1] * pos3d[j][1]
00213                + wtrans[2][3];
00214             hx = arParam.mat[0][0] * wx
00215                + arParam.mat[0][1] * wy
00216                + arParam.mat[0][2] * wz
00217                + arParam.mat[0][3];
00218             hy = arParam.mat[1][0] * wx
00219                + arParam.mat[1][1] * wy
00220                + arParam.mat[1][2] * wz
00221                + arParam.mat[1][3];
00222             h  = arParam.mat[2][0] * wx
00223                + arParam.mat[2][1] * wy
00224                + arParam.mat[2][2] * wz
00225                + arParam.mat[2][3];
00226             winfo[i].pos[j][0] = hx / h;
00227             winfo[i].pos[j][1] = hy / h;
00228 
00229             if(j ==0) {x1=x2=winfo[i].pos[j][0]; y1=y2=winfo[i].pos[j][1];}
00230             else {
00231                 if( winfo[i].pos[j][0] < x1 ) x1 = winfo[i].pos[j][0];
00232                 if( winfo[i].pos[j][0] > x2 ) x2 = winfo[i].pos[j][0];
00233                 if( winfo[i].pos[j][1] < y1 ) y1 = winfo[i].pos[j][1];
00234                 if( winfo[i].pos[j][1] > y2 ) y2 = winfo[i].pos[j][1];
00235             }
00236         }
00237         winfo[i].thresh = (x2 - x1 + 1)*(y2 - y1 + 1) / 2;
00238     }
00239 
00240 #if debug
00241 printf("\n");
00242 printf("================================================================\n");
00243 for( i = 0; i < config->marker_num; i++) {
00244 printf("%3d: ", i+1);
00245 for( j = 0; j < 4; j++ ) {
00246     printf("(%5.1f %5.1f) ", winfo[i].pos[j][0], winfo[i].pos[j][1]);
00247 }
00248 printf("\n");
00249 }
00250 printf("--------\n");
00251 for( i = 0; i < marker_num; i++) {
00252 printf("%3d: ", i+1);
00253 for( j = 0; j < 4; j++ ) {
00254     printf("(%5.1f %5.1f) ", marker_info[i].vertex[j][0], marker_info[i].vertex[j][1]);
00255 }
00256 printf("\n");
00257 }
00258 #endif
00259 
00260     w1 = w2 = 0;
00261     for( i = 0; i < config->marker_num; i++ ) {
00262         marker2 = -1;
00263         err2 = winfo[i].thresh;
00264         for( j = 0; j < marker_num; j++ ) {
00265             if( marker_info[j].id != -1
00266              && marker_info[j].id != config->marker[i].patt_id
00267              && marker_info[j].cf > 0.7 ) continue;
00268 
00269             dir1 = -1;
00270             for( k = 0; k < 4; k++ ) {
00271                 err = (winfo[i].pos[0][0] - marker_info[j].vertex[(k+0)%4][0])
00272                     * (winfo[i].pos[0][0] - marker_info[j].vertex[(k+0)%4][0])
00273                     + (winfo[i].pos[0][1] - marker_info[j].vertex[(k+0)%4][1])
00274                     * (winfo[i].pos[0][1] - marker_info[j].vertex[(k+0)%4][1])
00275                     + (winfo[i].pos[1][0] - marker_info[j].vertex[(k+1)%4][0])
00276                     * (winfo[i].pos[1][0] - marker_info[j].vertex[(k+1)%4][0])
00277                     + (winfo[i].pos[1][1] - marker_info[j].vertex[(k+1)%4][1])
00278                     * (winfo[i].pos[1][1] - marker_info[j].vertex[(k+1)%4][1])
00279                     + (winfo[i].pos[2][0] - marker_info[j].vertex[(k+2)%4][0])
00280                     * (winfo[i].pos[2][0] - marker_info[j].vertex[(k+2)%4][0])
00281                     + (winfo[i].pos[2][1] - marker_info[j].vertex[(k+2)%4][1])
00282                     * (winfo[i].pos[2][1] - marker_info[j].vertex[(k+2)%4][1])
00283                     + (winfo[i].pos[3][0] - marker_info[j].vertex[(k+3)%4][0])
00284                     * (winfo[i].pos[3][0] - marker_info[j].vertex[(k+3)%4][0])
00285                     + (winfo[i].pos[3][1] - marker_info[j].vertex[(k+3)%4][1])
00286                     * (winfo[i].pos[3][1] - marker_info[j].vertex[(k+3)%4][1]);
00287                 if( dir1 == -1 || err < err1 ) {
00288                     err1 = err;
00289                     dir1 = k;
00290                 }
00291             }
00292 #if debug
00293 printf("%f\n", err1);
00294 #endif
00295             if( err1 < err2 ) {
00296                 err2 = err1;
00297                 dir2 = dir1;
00298                 marker2 = j;
00299             }
00300         }
00301 
00302 #if debug
00303 printf("%3d<=>%3d, err = %f(%f)\n", i+1, marker2+1, err2, winfo[i].thresh);
00304 #endif
00305         if( marker2 != -1 ) {
00306             winfo[i].marker = marker2;
00307             winfo[i].dir    = dir2;
00308             winfo[i].err    = err2;
00309 
00310             if( marker_info[marker2].id == config->marker[i].patt_id ) w1++;
00311             else if( marker_info[marker2].id != -1 )                   w2++;
00312         }
00313         else {
00314             winfo[i].marker = -1;
00315         }
00316     }
00317 #if debug
00318 printf("w1,w2 = %d,%d\n", w1, w2);
00319 #endif
00320     if( w2 >= w1 ) {
00321         free(winfo);
00322         return -1;
00323     }
00324 
00325     for( i = 0; i < config->marker_num; i++ ) {
00326         for( j = 0; j < marker_num; j++ ) {
00327                 if( marker_info[j].id == config->marker[i].patt_id ) marker_info[j].id = -1;
00328         }
00329         if( winfo[i].marker != -1 ) {
00330             marker_info[winfo[i].marker].id  = config->marker[i].patt_id;
00331             marker_info[winfo[i].marker].dir = (4-winfo[i].dir)%4;
00332             marker_info[winfo[i].marker].cf  = 1.0;
00333         }
00334     }
00335 
00336     free(winfo);
00337 
00338     return 0;
00339 }
 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