Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 204 | chris | 1 | /******************************************************* |
| 2 | * |
||
| 3 | * Author: Hirokazu Kato |
||
| 4 | * |
||
| 5 | * kato@sys.im.hiroshima-cu.ac.jp |
||
| 6 | * |
||
| 7 | * Revision: 3.1 |
||
| 8 | * Date: 01/12/07 |
||
| 9 | * |
||
| 10 | *******************************************************/ |
||
| 11 | |||
| 12 | #include <stdio.h> |
||
| 13 | #include <math.h> |
||
| 14 | #include <string.h> |
||
| 15 | #ifdef _WIN32 |
||
| 16 | #include <sys/timeb.h> |
||
| 17 | #include <windows.h> |
||
| 18 | #else |
||
| 19 | #include <sys/time.h> |
||
| 20 | #endif |
||
| 21 | #include <AR/param.h> |
||
| 22 | #include <AR/matrix.h> |
||
| 23 | #include <AR/ar.h> |
||
| 24 | |||
| 25 | |||
| 26 | int arDebug = 0; |
||
| 27 | ARUint8* arImage = NULL; |
||
| 28 | int arFittingMode = DEFAULT_FITTING_MODE; |
||
| 29 | int arImageProcMode = DEFAULT_IMAGE_PROC_MODE; |
||
| 30 | ARParam arParam; |
||
| 31 | int arImXsize, arImYsize; |
||
| 32 | int arTemplateMatchingMode = DEFAULT_TEMPLATE_MATCHING_MODE; |
||
| 33 | int arMatchingPCAMode = DEFAULT_MATCHING_PCA_MODE; |
||
| 34 | |||
| 35 | ARUint8* arImageL = NULL; |
||
| 36 | ARUint8* arImageR = NULL; |
||
| 37 | ARSParam arsParam; |
||
| 38 | double arsMatR2L[3][4]; |
||
| 39 | |||
| 40 | ARUint32 arGetVersion(char **versionStringRef) |
||
| 41 | { |
||
| 42 | const char version[] = AR_HEADER_VERSION_STRING; |
||
| 43 | char *s; |
||
| 44 | |||
| 45 | if (versionStringRef) { |
||
| 46 | arMalloc(s, char, sizeof(version)); |
||
| 47 | strncpy(s, version, sizeof(version)); |
||
| 48 | *versionStringRef = s; |
||
| 49 | } |
||
| 50 | // Represent full version number (major, minor, tiny, build) in |
||
| 51 | // binary coded decimal. N.B: Integer division. |
||
| 52 | return (0x10000000u * ((unsigned int)AR_HEADER_VERSION_MAJOR / 10u) + |
||
| 53 | 0x01000000u * ((unsigned int)AR_HEADER_VERSION_MAJOR % 10u) + |
||
| 54 | 0x00100000u * ((unsigned int)AR_HEADER_VERSION_MINOR / 10u) + |
||
| 55 | 0x00010000u * ((unsigned int)AR_HEADER_VERSION_MINOR % 10u) + |
||
| 56 | 0x00001000u * ((unsigned int)AR_HEADER_VERSION_TINY / 10u) + |
||
| 57 | 0x00000100u * ((unsigned int)AR_HEADER_VERSION_TINY % 10u) + |
||
| 58 | 0x00000010u * ((unsigned int)AR_HEADER_VERSION_BUILD / 10u) + |
||
| 59 | 0x00000001u * ((unsigned int)AR_HEADER_VERSION_BUILD % 10u) |
||
| 60 | ); |
||
| 61 | } |
||
| 62 | |||
| 63 | static int arGetLine2(int x_coord[], int y_coord[], int coord_num, |
||
| 64 | int vertex[], double line[4][3], double v[4][2], double *dist_factor); |
||
| 65 | |||
| 66 | int arInitCparam( ARParam *param ) |
||
| 67 | { |
||
| 68 | arImXsize = param->xsize; |
||
| 69 | arImYsize = param->ysize; |
||
| 70 | arParam = *param; |
||
| 71 | |||
| 72 | return(0); |
||
| 73 | } |
||
| 74 | |||
| 75 | int arsInitCparam( ARSParam *sparam ) |
||
| 76 | { |
||
| 77 | arImXsize = sparam->xsize; |
||
| 78 | arImYsize = sparam->ysize; |
||
| 79 | arsParam = *sparam; |
||
| 80 | |||
| 81 | arUtilMatInv( arsParam.matL2R, arsMatR2L ); |
||
| 82 | |||
| 83 | return(0); |
||
| 84 | } |
||
| 85 | |||
| 86 | int arGetLine(int x_coord[], int y_coord[], int coord_num, |
||
| 87 | int vertex[], double line[4][3], double v[4][2]) |
||
| 88 | { |
||
| 89 | return arGetLine2( x_coord, y_coord, coord_num, vertex, line, v, arParam.dist_factor ); |
||
| 90 | } |
||
| 91 | |||
| 92 | int arsGetLine(int x_coord[], int y_coord[], int coord_num, |
||
| 93 | int vertex[], double line[4][3], double v[4][2], int LorR) |
||
| 94 | { |
||
| 95 | if( LorR ) |
||
| 96 | return arGetLine2( x_coord, y_coord, coord_num, vertex, line, v, arsParam.dist_factorL ); |
||
| 97 | else |
||
| 98 | return arGetLine2( x_coord, y_coord, coord_num, vertex, line, v, arsParam.dist_factorR ); |
||
| 99 | } |
||
| 100 | |||
| 101 | static int arGetLine2(int x_coord[], int y_coord[], int coord_num, |
||
| 102 | int vertex[], double line[4][3], double v[4][2], double *dist_factor) |
||
| 103 | { |
||
| 104 | ARMat *input, *evec; |
||
| 105 | ARVec *ev, *mean; |
||
| 106 | double w1; |
||
| 107 | int st, ed, n; |
||
| 108 | int i, j; |
||
| 109 | |||
| 110 | ev = arVecAlloc( 2 ); |
||
| 111 | mean = arVecAlloc( 2 ); |
||
| 112 | evec = arMatrixAlloc( 2, 2 ); |
||
| 113 | for( i = 0; i < 4; i++ ) { |
||
| 114 | w1 = (double)(vertex[i+1]-vertex[i]+1) * 0.05 + 0.5; |
||
| 115 | st = (int)(vertex[i] + w1); |
||
| 116 | ed = (int)(vertex[i+1] - w1); |
||
| 117 | n = ed - st + 1; |
||
| 118 | input = arMatrixAlloc( n, 2 ); |
||
| 119 | for( j = 0; j < n; j++ ) { |
||
| 120 | arParamObserv2Ideal( dist_factor, x_coord[st+j], y_coord[st+j], |
||
| 121 | &(input->m[j*2+0]), &(input->m[j*2+1]) ); |
||
| 122 | } |
||
| 123 | if( arMatrixPCA(input, evec, ev, mean) < 0 ) { |
||
| 124 | arMatrixFree( input ); |
||
| 125 | arMatrixFree( evec ); |
||
| 126 | arVecFree( mean ); |
||
| 127 | arVecFree( ev ); |
||
| 128 | return(-1); |
||
| 129 | } |
||
| 130 | line[i][0] = evec->m[1]; |
||
| 131 | line[i][1] = -evec->m[0]; |
||
| 132 | line[i][2] = -(line[i][0]*mean->v[0] + line[i][1]*mean->v[1]); |
||
| 133 | arMatrixFree( input ); |
||
| 134 | } |
||
| 135 | arMatrixFree( evec ); |
||
| 136 | arVecFree( mean ); |
||
| 137 | arVecFree( ev ); |
||
| 138 | |||
| 139 | for( i = 0; i < 4; i++ ) { |
||
| 140 | w1 = line[(i+3)%4][0] * line[i][1] - line[i][0] * line[(i+3)%4][1]; |
||
| 141 | if( w1 == 0.0 ) return(-1); |
||
| 142 | v[i][0] = ( line[(i+3)%4][1] * line[i][2] |
||
| 143 | - line[i][1] * line[(i+3)%4][2] ) / w1; |
||
| 144 | v[i][1] = ( line[i][0] * line[(i+3)%4][2] |
||
| 145 | - line[(i+3)%4][0] * line[i][2] ) / w1; |
||
| 146 | } |
||
| 147 | |||
| 148 | return(0); |
||
| 149 | } |
||
| 150 | |||
| 151 | int arUtilMatMul( double s1[3][4], double s2[3][4], double d[3][4] ) |
||
| 152 | { |
||
| 153 | int i, j; |
||
| 154 | |||
| 155 | for( j = 0; j < 3; j++ ) { |
||
| 156 | for( i = 0; i < 4; i++) { |
||
| 157 | d[j][i] = s1[j][0] * s2[0][i] |
||
| 158 | + s1[j][1] * s2[1][i] |
||
| 159 | + s1[j][2] * s2[2][i]; |
||
| 160 | } |
||
| 161 | d[j][3] += s1[j][3]; |
||
| 162 | } |
||
| 163 | |||
| 164 | return 0; |
||
| 165 | } |
||
| 166 | |||
| 167 | int arUtilMatInv( double s[3][4], double d[3][4] ) |
||
| 168 | { |
||
| 169 | ARMat *mat; |
||
| 170 | int i, j; |
||
| 171 | |||
| 172 | mat = arMatrixAlloc( 4, 4 ); |
||
| 173 | for( j = 0; j < 3; j++ ) { |
||
| 174 | for( i = 0; i < 4; i++ ) { |
||
| 175 | mat->m[j*4+i] = s[j][i]; |
||
| 176 | } |
||
| 177 | } |
||
| 178 | mat->m[3*4+0] = 0; mat->m[3*4+1] = 0; |
||
| 179 | mat->m[3*4+2] = 0; mat->m[3*4+3] = 1; |
||
| 180 | arMatrixSelfInv( mat ); |
||
| 181 | for( j = 0; j < 3; j++ ) { |
||
| 182 | for( i = 0; i < 4; i++ ) { |
||
| 183 | d[j][i] = mat->m[j*4+i]; |
||
| 184 | } |
||
| 185 | } |
||
| 186 | arMatrixFree( mat ); |
||
| 187 | |||
| 188 | return 0; |
||
| 189 | } |
||
| 190 | |||
| 191 | int arUtilMat2QuatPos( double m[3][4], double q[4], double p[3] ) |
||
| 192 | { |
||
| 193 | double w; |
||
| 194 | |||
| 195 | w = m[0][0] + m[1][1] + m[2][2] + 1; |
||
| 196 | if( w < 0.0 ) return -1; |
||
| 197 | |||
| 198 | w = sqrt( w ); |
||
| 199 | q[0] = (m[1][2] - m[2][1]) / (w*2.0); |
||
| 200 | q[1] = (m[2][0] - m[0][2]) / (w*2.0); |
||
| 201 | q[2] = (m[0][1] - m[1][0]) / (w*2.0); |
||
| 202 | q[3] = w / 2.0; |
||
| 203 | |||
| 204 | p[0] = m[0][3]; |
||
| 205 | p[1] = m[1][3]; |
||
| 206 | p[2] = m[2][3]; |
||
| 207 | |||
| 208 | return 0; |
||
| 209 | } |
||
| 210 | |||
| 211 | int arUtilQuatPos2Mat( double q[4], double p[3], double m[3][4] ) |
||
| 212 | { |
||
| 213 | double x2, y2, z2; |
||
| 214 | double xx, xy, xz; |
||
| 215 | double yy, yz, zz; |
||
| 216 | double wx, wy, wz; |
||
| 217 | |||
| 218 | x2 = q[0] * 2.0; |
||
| 219 | y2 = q[1] * 2.0; |
||
| 220 | z2 = q[2] * 2.0; |
||
| 221 | xx = q[0] * x2; |
||
| 222 | xy = q[0] * y2; |
||
| 223 | xz = q[0] * z2; |
||
| 224 | yy = q[1] * y2; |
||
| 225 | yz = q[1] * z2; |
||
| 226 | zz = q[2] * z2; |
||
| 227 | wx = q[3] * x2; |
||
| 228 | wy = q[3] * y2; |
||
| 229 | wz = q[3] * z2; |
||
| 230 | |||
| 231 | m[0][0] = 1.0 - (yy + zz); |
||
| 232 | m[1][1] = 1.0 - (xx + zz); |
||
| 233 | m[2][2] = 1.0 - (xx + yy); |
||
| 234 | m[1][0] = xy - wz; |
||
| 235 | m[0][1] = xy + wz; |
||
| 236 | m[2][0] = xz + wy; |
||
| 237 | m[0][2] = xz - wy; |
||
| 238 | m[2][1] = yz - wx; |
||
| 239 | m[1][2] = yz + wx; |
||
| 240 | |||
| 241 | m[0][3] = p[0]; |
||
| 242 | m[1][3] = p[1]; |
||
| 243 | m[2][3] = p[2]; |
||
| 244 | |||
| 245 | return 0; |
||
| 246 | } |
||
| 247 | |||
| 248 | |||
| 249 | static int ss, sms; |
||
| 250 | |||
| 251 | double arUtilTimer(void) |
||
| 252 | { |
||
| 253 | #ifdef _WIN32 |
||
| 254 | struct _timeb sys_time; |
||
| 255 | double tt; |
||
| 256 | int s1, s2; |
||
| 257 | |||
| 258 | _ftime(&sys_time); |
||
| 259 | s1 = sys_time.time - ss; |
||
| 260 | s2 = sys_time.millitm - sms; |
||
| 261 | #else |
||
| 262 | struct timeval time; |
||
| 263 | double tt; |
||
| 264 | int s1, s2; |
||
| 265 | |||
| 266 | #if defined(__linux) || defined(__APPLE__) |
||
| 267 | gettimeofday( &time, NULL ); |
||
| 268 | #else |
||
| 269 | gettimeofday( &time ); |
||
| 270 | #endif |
||
| 271 | s1 = time.tv_sec - ss; |
||
| 272 | s2 = time.tv_usec/1000 - sms; |
||
| 273 | #endif |
||
| 274 | |||
| 275 | tt = (double)s1 + (double)s2 / 1000.0; |
||
| 276 | |||
| 277 | return( tt ); |
||
| 278 | } |
||
| 279 | |||
| 280 | void arUtilTimerReset(void) |
||
| 281 | { |
||
| 282 | #ifdef _WIN32 |
||
| 283 | struct _timeb sys_time; |
||
| 284 | |||
| 285 | _ftime(&sys_time); |
||
| 286 | ss = sys_time.time; |
||
| 287 | sms = sys_time.millitm; |
||
| 288 | #else |
||
| 289 | struct timeval time; |
||
| 290 | |||
| 291 | #if defined(__linux) || defined(__APPLE__) |
||
| 292 | gettimeofday( &time, NULL ); |
||
| 293 | #else |
||
| 294 | gettimeofday( &time ); |
||
| 295 | #endif |
||
| 296 | ss = time.tv_sec; |
||
| 297 | sms = time.tv_usec / 1000; |
||
| 298 | #endif |
||
| 299 | } |
||
| 300 | |||
| 301 | void arUtilSleep( int msec ) |
||
| 302 | { |
||
| 303 | #ifndef _WIN32 |
||
| 304 | struct timespec req; |
||
| 305 | |||
| 306 | req.tv_sec = 0; |
||
| 307 | req.tv_nsec = msec* 1000; |
||
| 308 | nanosleep( &req, NULL ); |
||
| 309 | #else |
||
| 310 | Sleep(msec); |
||
| 311 | #endif |
||
| 312 | return; |
||
| 313 | } |
||
| 314 |