00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #define SBA_OPTSSZ 5
00026 #define SBA_INFOSZ 10
00027 #define SBA_ERROR -1
00028 #define SBA_INIT_MU 1E-03
00029 #define SBA_STOP_THRESH 1E-12
00030 #define SBA_CG_NOPREC 0
00031 #define SBA_CG_JACOBI 1
00032 #define SBA_CG_SSOR 2
00033 #define SBA_VERSION "1.6 (Aug. 2009)"
00034
00035 #include <QTime>
00036 #include <qvsfm/laSBA/laSBAWrapper.h>
00037 #include <qvsfm/laSBA/sba-1.6/compiler.h>
00038 #include <qvsfm/laSBA/sba-1.6/sba.h>
00039
00040 const int CAMERA_VECTOR_SIZE=7,
00041 POINT3D_SIZE=3,
00042 POINT2D_SIZE=2;
00043
00044 void initData( const QList<QVEuclideanMapping3> &cameras,
00045 const QList<QV3DPointF> &points3D,
00046 const QList< QHash<int, QPointF> > &pointProjections,
00047 double *motstruct,
00048 double *imgpts,
00049 char *vmask
00050 );
00051
00052 void img_proj2(int numCam, int numPoint, double *cam, double *p3D, double *p2D, void *);
00053
00054 void readData( const double *motstruct,
00055 const int numFrames,
00056 const int numPoints3D,
00057 QList<QVEuclideanMapping3> &refinedCameras,
00058 QList<QV3DPointF> &refinedPoints3D);
00059
00060 double final_reprojection_error, initial_reprojection_error;
00061 int sba_elapsed_milisecs = 0, sba_iterations = 0, sba_stop_condition = -1;
00062
00063
00064
00065 void my_img_proj(int numCam, int numPoint, double *camera, double *p3D, double *p2D, void *)
00066 {
00067 const double camera0 = camera[0],
00068 camera1 = camera[1],
00069 camera2 = camera[2],
00070 camera3 = camera[3],
00071 camera4 = camera[4],
00072 camera5 = camera[5],
00073 camera6 = camera[6];
00074 const double p3D0 = p3D[0],
00075 p3D1 = p3D[1],
00076 p3D2 = p3D[2];
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 const double t1 = camera0 * camera0;
00100 const double t2 = camera1 * camera1;
00101 const double t3 = camera2 * camera2;
00102 const double t4 = camera3 * camera3;
00103 const double t6 = 0.1e1 / (t1 + t2 + t3 + t4);
00104 const double t7 = 0.20e1 * t2;
00105 const double t8 = 0.20e1 * t3;
00106 const double t14 = 0.20e1 * camera0 * camera1;
00107 const double t16 = 0.20e1 * camera2 * camera3;
00108 const double t21 = 0.20e1 * camera2 * camera0;
00109 const double t23 = 0.20e1 * camera1 * camera3;
00110 const double t32 = 0.20e1 * camera1 * camera2;
00111 const double t34 = 0.20e1 * camera0 * camera3;
00112 const double t38 = 0.20e1 * t1;
00113 const double t44 = 0.1e1 / (t6 * (t21 - t23) * p3D0 + t6 * (t32 + t34) * p3D1 + (0.1e1 + t6 * (-t7 - t38)) * p3D2 + camera6);
00114 p2D[0] = ((0.1e1 + t6 * (-t7 - t8)) * p3D0 + t6 * (t14 - t16) * p3D1 + t6 * (t21 + t23) * p3D2 + camera4) * t44;
00115 p2D[1] = (t6 * (t14 + t16) * p3D0 + (0.1e1 + t6 * (-t8 - t38)) * p3D1 + t6 * (t32 - t34) * p3D2 + camera5) * t44;
00116 }
00117
00118 void my_img_proj_jac(int numCam, int numPoint, double *camera, double *p3D, double * jacmRT, double * jacmS, void *)
00119 {
00120 const double camera0 = camera[0],
00121 camera1 = camera[1],
00122 camera2 = camera[2],
00123 camera3 = camera[3],
00124 camera4 = camera[4],
00125 camera5 = camera[5],
00126 camera6 = camera[6];
00127 const double p3D0 = p3D[0],
00128 p3D1 = p3D[1],
00129 p3D2 = p3D[2];
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 const double t1 = camera0 * camera0;
00141 const double t2 = camera1 * camera1;
00142 const double t3 = camera2 * camera2;
00143 const double t4 = camera3 * camera3;
00144 const double t5 = t1 + t2 + t3 + t4;
00145 const double t6 = t5 * t5;
00146 const double t7 = 0.1e1 / t6;
00147 const double t8 = 0.20e1 * t2;
00148 const double t9 = 0.20e1 * t3;
00149 const double t10 = -t8 - t9;
00150 const double t11 = t7 * t10;
00151 const double t12 = camera0 * p3D0;
00152 const double t16 = 0.20e1 * camera0 * camera1;
00153 const double t18 = 0.20e1 * camera2 * camera3;
00154 const double t19 = t16 - t18;
00155 const double t20 = t7 * t19;
00156 const double t21 = p3D1 * camera0;
00157 const double t24 = 0.1e1 / t5;
00158 const double t25 = t24 * camera1;
00159 const double t27 = 0.20e1 * t25 * p3D1;
00160 const double t29 = 0.20e1 * camera2 * camera0;
00161 const double t31 = 0.20e1 * camera1 * camera3;
00162 const double t32 = t29 + t31;
00163 const double t33 = t7 * t32;
00164 const double t34 = p3D2 * camera0;
00165 const double t37 = t24 * camera2;
00166 const double t39 = 0.20e1 * t37 * p3D2;
00167 const double t41 = t29 - t31;
00168 const double t42 = t24 * t41;
00169 const double t45 = 0.20e1 * camera1 * camera2;
00170 const double t47 = 0.20e1 * camera0 * camera3;
00171 const double t48 = t45 + t47;
00172 const double t49 = t24 * t48;
00173 const double t51 = 0.20e1 * t1;
00174 const double t52 = -t8 - t51;
00175 const double t54 = 0.1e1 + t24 * t52;
00176 const double t56 = t42 * p3D0 + t49 * p3D1 + t54 * p3D2 + camera6;
00177 const double t57 = 0.1e1 / t56;
00178 const double t60 = 0.1e1 + t24 * t10;
00179 const double t62 = t24 * t19;
00180 const double t64 = t24 * t32;
00181 const double t67 = t56 * t56;
00182 const double t68 = 0.1e1 / t67;
00183 const double t69 = (t60 * p3D0 + t62 * p3D1 + t64 * p3D2 + camera4) * t68;
00184 const double t70 = t7 * t41;
00185 const double t74 = 0.20e1 * t37 * p3D0;
00186 const double t75 = t7 * t48;
00187 const double t78 = t24 * camera3;
00188 const double t80 = 0.20e1 * t78 * p3D1;
00189 const double t81 = t7 * t52;
00190 const double t84 = t24 * camera0;
00191 const double t85 = 0.40e1 * t84;
00192 const double t88 = -0.2e1 * t70 * t12 + t74 - 0.2e1 * t75 * t21 + t80 + (-0.2e1 * t81 * camera0 - t85) * p3D2;
00193 const double t93 = 0.40e1 * t25;
00194 const double t96 = p3D1 * camera1;
00195 const double t100 = 0.20e1 * t84 * p3D1;
00196 const double t101 = p3D2 * camera1;
00197 const double t105 = 0.20e1 * t78 * p3D2;
00198 const double t108 = p3D0 * camera1;
00199 const double t112 = 0.20e1 * t78 * p3D0;
00200 const double t116 = 0.20e1 * t37 * p3D1;
00201 const double t121 = -0.2e1 * t70 * t108 - t112 - 0.2e1 * t75 * t96 + t116 + (-0.2e1 * t81 * camera1 - t93) * p3D2;
00202 const double t126 = 0.40e1 * t37;
00203 const double t129 = p3D1 * camera2;
00204 const double t132 = p3D2 * camera2;
00205 const double t136 = 0.20e1 * t84 * p3D2;
00206 const double t139 = p3D0 * camera2;
00207 const double t143 = 0.20e1 * t84 * p3D0;
00208 const double t148 = -0.2e1 * t70 * t139 + t143 - 0.2e1 * t75 * t129 + t27 - 0.2e1 * t81 * t132;
00209 const double t151 = camera3 * p3D0;
00210 const double t154 = p3D1 * camera3;
00211 const double t157 = p3D2 * camera3;
00212 const double t161 = 0.20e1 * t25 * p3D2;
00213 const double t167 = 0.20e1 * t25 * p3D0;
00214 const double t172 = -0.2e1 * t70 * t151 - t167 - 0.2e1 * t75 * t154 + t100 - 0.2e1 * t81 * t157;
00215 const double t184 = t16 + t18;
00216 const double t185 = t7 * t184;
00217 const double t188 = -t9 - t51;
00218 const double t189 = t7 * t188;
00219 const double t194 = t45 - t47;
00220 const double t195 = t7 * t194;
00221 const double t200 = t24 * t184;
00222 const double t203 = 0.1e1 + t24 * t188;
00223 const double t205 = t24 * t194;
00224 const double t208 = (t200 * p3D0 + t203 * p3D1 + t205 * p3D2 + camera5) * t68;
00225 jacmRT[0] = (-0.2e1 * t11 * t12 - 0.2e1 * t20 * t21 + t27 - 0.2e1 * t33 * t34 + t39) * t57 - t69 * t88;
00226 jacmRT[1] = ((-0.2e1 * t11 * camera1 - t93) * p3D0 - 0.2e1 * t20 * t96 + t100 - 0.2e1 * t33 * t101 + t105) * t57 - t69 * t121;
00227 jacmRT[2] = ((-0.2e1 * t11 * camera2 - t126) * p3D0 - 0.2e1 * t20 * t129 - t80 - 0.2e1 * t33 * t132 + t136) * t57 - t69 * t148;
00228 jacmRT[3] = (-0.2e1 * t11 * t151 - 0.2e1 * t20 * t154 - t116 - 0.2e1 * t33 * t157 + t161) * t57 - t69 * t172;
00229 jacmRT[4] = t57;
00230 jacmRT[5] = 0.0e0;
00231 jacmRT[6] = -t69;
00232 jacmRT[7] = (-0.2e1 * t185 * t12 + t167 + (-0.2e1 * t189 * camera0 - t85) * p3D1 - 0.2e1 * t195 * t34 - t105) * t57 - t208 * t88;
00233 jacmRT[8] = (-0.2e1 * t185 * t108 + t143 - 0.2e1 * t189 * t96 - 0.2e1 * t195 * t101 + t39) * t57 - t208 * t121;
00234 jacmRT[9] = (-0.2e1 * t185 * t139 + t112 + (-0.2e1 * t189 * camera2 - t126) * p3D1 - 0.2e1 * t195 * t132 + t161) * t57 - t208 * t148;
00235 jacmRT[10] = (-0.2e1 * t185 * t151 + t74 - 0.2e1 * t189 * t154 - 0.2e1 * t195 * t157 - t136) * t57 - t208 * t172;
00236 jacmRT[11] = 0.0e0;
00237 jacmRT[12] = t57;
00238 jacmRT[13] = -t208;
00239 jacmS[0] = t60 * t57 - t69 * t42;
00240 jacmS[1] = t62 * t57 - t69 * t49;
00241 jacmS[2] = t64 * t57 - t69 * t54;
00242 jacmS[3] = t200 * t57 - t208 * t42;
00243 jacmS[4] = t203 * t57 - t208 * t49;
00244 jacmS[5] = t205 * t57 - t208 * t54;
00245 }
00246
00247
00248
00249 bool laSBAOptimization( const QList<QVCameraPose> &cameras,
00250 const QList<QV3DPointF> &points3D,
00251 const QList< QHash<int, QPointF> > &pointProjections,
00252 QList<QVCameraPose> &refinedCameras,
00253 QList<QV3DPointF> &refinedPoints3D,
00254 const unsigned int numIterations,
00255 const unsigned int numFixedFrames,
00256 const unsigned int numFixedPoints,
00257 const double initialMuScaleFactor,
00258 const double stoppingThresholdForJacobian,
00259 const double stoppingThresholdForProjections,
00260 const double stoppingThresholdForReprojectionError,
00261 const double stoppingThresholdForReprojectionErrorIncrement)
00262 {
00263 const int numPoints3D = points3D.size(),
00264 numFrames = cameras.size(),
00265 CAMERA_VECTOR_SIZE=7,
00266 POINT3D_SIZE=3,
00267 POINT2D_SIZE=2;
00268
00269 int n2Dprojs = 0;
00270 for(int i = 0; i < pointProjections.size(); i++)
00271 n2Dprojs += pointProjections[i].size();
00272
00273 double motstruct[numFrames*CAMERA_VECTOR_SIZE + numPoints3D*POINT3D_SIZE],
00274 imgpts[n2Dprojs*POINT2D_SIZE];
00275
00276 char vmask[numPoints3D * numFrames];
00277
00278
00279
00280
00281 for (int i = 0; i < numFrames; i++)
00282 {
00283 const QVVector camera = cameras[i].operator QVEuclideanMapping3();
00284 for(int j = 0; j < CAMERA_VECTOR_SIZE; j++)
00285 motstruct[i*CAMERA_VECTOR_SIZE+j] = camera[j];
00286 }
00287
00288
00289 for (int i = 0; i < numPoints3D; i++)
00290 for(int j = 0; j < POINT3D_SIZE; j++)
00291 (motstruct+numFrames*CAMERA_VECTOR_SIZE)[i*POINT3D_SIZE+j] = points3D[i][j];
00292
00293
00294 for(int j = 0, index = 0; j < numPoints3D; j++)
00295 for(int i = 0; i < numFrames; i++)
00296 if (pointProjections[j].contains(i))
00297 {
00298 imgpts[index*POINT2D_SIZE+0] = pointProjections[j][i].x();
00299 imgpts[index*POINT2D_SIZE+1] = pointProjections[j][i].y();
00300 index++;
00301 vmask[j*numFrames + i] = true;
00302 }
00303 else vmask[j*numFrames + i] = false;
00304
00305 double opts[SBA_OPTSSZ];
00306 opts[0]=initialMuScaleFactor;
00307 opts[1]=stoppingThresholdForJacobian;
00308 opts[2]=stoppingThresholdForProjections;
00309 opts[3]=stoppingThresholdForReprojectionError;
00310 opts[4]=stoppingThresholdForReprojectionErrorIncrement;
00311
00312
00313 double info[SBA_INFOSZ];
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 QTime time;
00331 time.start();
00332 sba_iterations = sba_motstr_levmar( numPoints3D,
00333 numFixedPoints,
00334 numFrames,
00335 numFixedFrames,
00336 vmask,
00337 motstruct,
00338 CAMERA_VECTOR_SIZE,
00339 POINT3D_SIZE,
00340 imgpts,
00341 NULL,
00342 POINT2D_SIZE,
00343 my_img_proj,
00344 my_img_proj_jac,
00345 NULL,
00346 numIterations,
00347 false,
00348 opts,
00349 info
00350 );
00351 sba_elapsed_milisecs = time.elapsed();
00352 refinedPoints3D = points3D;
00353
00354
00355
00356 for (int i = 0; i < numFrames; i++)
00357 {
00358 QVVector cameraVector(CAMERA_VECTOR_SIZE);
00359 for(int j = 0; j < CAMERA_VECTOR_SIZE; j++)
00360 cameraVector[j] = motstruct[i*CAMERA_VECTOR_SIZE+j];
00361 refinedCameras << QVEuclideanMapping3(cameraVector);
00362 }
00363
00364
00365 for (int i = 0; i < numPoints3D; i++)
00366 for(int j = 0; j < POINT3D_SIZE; j++)
00367 refinedPoints3D[i][j] = (motstruct+numFrames*CAMERA_VECTOR_SIZE)[i*POINT3D_SIZE+j];
00368
00369 sba_stop_condition = info[6];
00370 initial_reprojection_error = info[0];
00371 final_reprojection_error = info[1];
00372
00373 return (info[6] > 0 and info[6] < 6);
00374 }
00375
00376