GSoC2011SfM
0.1
Google Summer of Code 2011: Structure from motion
|
00001 00002 #include "bundle_related.h" 00003 00004 #include "opencv2/core/eigen.hpp" 00005 00006 #include "SequenceAnalyzer.h" 00007 #include "CameraPinholeDistor.h" 00008 #include "PointsToTrack.h" 00009 #include "PointOfView.h" 00010 00011 00012 namespace OpencvSfM{ 00013 00014 using std::vector; 00015 using cv::Ptr; 00016 00017 00018 //TODO: intra parameters are badly integrated: 00019 //1) when multiple cameras share the same intra parameters, computation is not optimized 00020 //2) Skew and ratio of focal are not correctly estimated... See how this can be improved! 00021 void full_bundle( SequenceAnalyzer &sequence, 00022 std::vector<PointOfView>& cameras) 00023 { 00024 //wrap the lourakis SBA... 00025 //everything should be adjusted! 00026 std::vector< TrackOfPoints > point_computed_ = 00027 sequence.getTracks(); 00028 //what should we compute? 00029 unsigned int n = point_computed_.size( ), // number of points 00030 ncon = 0,// number of points (starting from the 1st) whose parameters should not be modified. 00031 m = 0, // number of images (or camera) 00032 mcon = 0,// number of cameras (starting from the 1st) whose parameters should not be modified. 00033 cnp = cameras[0].getNbMissingParams(),// number of parameters for ONE camera; 00034 pnp = 3,// number of parameters for ONE 3D point; e.g. 3 for Euclidean points 00035 mnp = 2;// number of parameters for ONE projected point; e.g. 2 for Euclidean points 00036 00037 unsigned int i = 0, j = 0, 00038 nb_cam = cameras.size( ); 00039 vector< Ptr< PointsToTrack > > &points_to_track = sequence.getPoints( ); 00040 00041 //because some points are sometime not visible: 00042 vector<int> idx_cameras; 00043 00044 std::vector<bool> pointOK; 00045 int nbPoints = 0; 00046 for ( j = 0; j < n; ++j ) 00047 {//for each 3D point: 00048 //test if at least 2 views see this point: 00049 int nbCam = 0; 00050 for(size_t k =0; k<nb_cam; ++k) 00051 { 00052 if( point_computed_[ j ].containImage( k ) ) 00053 nbCam++; 00054 } 00055 pointOK.push_back( nbCam>=2 ); 00056 if( pointOK[j] ) 00057 nbPoints++; 00058 } 00059 00060 int nz_count = 0; 00061 for ( i = 0; i < nb_cam; ++i ) 00062 {//for each camera: 00063 00064 int nb_projection = 0; 00065 for ( j = 0; j < n; ++j ) 00066 {//for each 3D point: 00067 if( pointOK[j]) 00068 { 00069 if( point_computed_[ j ].containImage( i ) ) 00070 nb_projection++; 00071 } 00072 } 00073 if( nb_projection>30 )//a camera should see at least 10 points 00074 { 00075 nz_count += nb_projection; 00076 idx_cameras.push_back(i); 00077 m++;//increament of camera count 00078 } 00079 else 00080 std::clog<<"remove camera "<<i<<" from bundle"<<std::endl; 00081 } 00082 n=nbPoints; 00083 nb_cam = m; 00084 00085 //2D points: 00086 char *vmask = new char[ n*m ];//visibility mask: vmask[i, j]=1 if point i visible in image j, 0 otherwise. 00087 double *p = new double[m*cnp + n*pnp];//initial parameter vector p0: (a1, ..., am, b1, ..., bn). 00088 // aj are the image j parameters, bi are the i-th point parameters 00089 00090 double *x = new double[ 2*nz_count ];// measurements vector: (x_11^T, .. x_1m^T, ..., x_n1^T, .. x_nm^T)^T where 00091 // x_ij is the projection of the i-th point on the j-th image. 00092 // NOTE: some of the x_ij might be missing, if point i is not visible in image j; 00093 // see vmask[i, j], max. size n*m*mnp 00094 00095 libmv::vector< Eigen::Quaterniond > init_rotation; 00096 libmv::vector< libmv::Vec3 > init_translat; 00097 libmv::vector< libmv::Mat3 > intra_p; 00098 libmv::vector< int > idx_intra; 00099 //update each variable: 00100 int idx_visible = 0; 00101 double *p_local = p; 00102 for ( i=0; i < m; ++i ) 00103 {//for each camera: 00104 int idx_cam = idx_cameras[i]; 00105 libmv::Mat3 intra_param, rotation_mat; 00106 libmv::Vec3 translation_vec; 00107 cv::Ptr<Camera> intra=cameras[ idx_cam ].getIntraParameters( ); 00108 //is this camera shared? 00109 const std::vector<PointOfView*> & relV = intra->getRelatedViews(); 00110 00111 int idx_cam_intra = -1; 00112 for(size_t cpt = 0; cpt<relV.size() && idx_cam_intra<0; cpt++) 00113 { 00114 for(int cpt1 = 0; (cpt1<intra_p.size()) && (idx_cam_intra<0); cpt1++) 00115 { 00116 int idx_cam_bis = idx_intra[ cpt1 ]; 00117 if ( idx_cam_bis!=idx_cam && (&cameras[ idx_cam_bis ]) == relV[ cpt ] ) 00118 { 00119 std::clog<<"intra params for camera "<< i << 00120 " are the same params than camera: "<<idx_cam_bis<<std::endl; 00121 idx_cam_intra = idx_cam_bis; 00122 } 00123 } 00124 } 00125 00126 cv::cv2eigen( intra->getIntraMatrix( ).t(), intra_param ); 00127 if( idx_cam_intra<0 ) 00128 { 00129 idx_intra.push_back( intra_p.size() ); 00130 intra_p.push_back( intra_param ); 00131 } 00132 else 00133 {//as this intra parameter is shared, it will not being updated during bundle! 00134 idx_intra.push_back( idx_cam_intra ); 00135 } 00136 00137 cv::cv2eigen( cameras[ idx_cam ].getRotationMatrix( ), rotation_mat ); 00138 cv::cv2eigen( cameras[ idx_cam ].getTranslationVector( ), translation_vec ); 00139 00140 init_rotation.push_back( (Eigen::Quaterniond)rotation_mat ); 00141 init_translat.push_back( translation_vec ); 00142 00143 for(size_t i=0; i<cnp; ++i) 00144 p_local[i] = 0; 00145 00146 p_local[3] = intra_param(1,1) / intra_param(0,0); 00147 00148 p_local+=cnp; 00149 } 00150 00151 //now add the projections and 3D points: 00152 idx_visible = 0; 00153 int j_real = 0; 00154 for ( j = 0; j < point_computed_.size(); ++j ) 00155 {//for each 3D point: 00156 if( pointOK[j]) 00157 { 00158 for ( i=0; i < m; ++i ) 00159 {//for each camera: 00160 int idx_cam = idx_cameras[i]; 00161 vmask[ i+j_real*m ] = point_computed_[ j ].containImage( idx_cam ); 00162 if( vmask[ i+j_real*m ] ) 00163 { 00164 cv::KeyPoint pt = points_to_track[ idx_cam ]->getKeypoint( 00165 point_computed_[ j ].getPointIndex( idx_cam ) ); 00166 x[ idx_visible++ ] = pt.pt.x; 00167 x[ idx_visible++ ] = pt.pt.y; 00168 } 00169 } 00170 j_real++; 00171 } 00172 } 00173 double* points3D_values = p_local; 00174 for ( j = 0; j < point_computed_.size(); ++j ) 00175 {//for each 3D point: 00176 if( pointOK[j]) 00177 { 00178 cv::Ptr<cv::Vec3d> cv3DPoint = point_computed_[ j ].get3DPosition(); 00179 if(cv3DPoint.empty()) 00180 { 00181 *(p_local++) = 0; 00182 *(p_local++) = 0; 00183 *(p_local++) = 0; 00184 } 00185 else 00186 { 00187 *(p_local++) = (*cv3DPoint)[ 0 ]; 00188 *(p_local++) = (*cv3DPoint)[ 1 ]; 00189 *(p_local++) = (*cv3DPoint)[ 2 ]; 00190 } 00191 } 00192 } 00193 00194 bundle_datas data(idx_intra,intra_p,init_rotation,init_translat, 00195 cnp, pnp, mnp,ncon, mcon); 00196 data.points3D = points3D_values; 00197 00198 //TUNING PARAMETERS: 00199 int itmax = 10000; //max iterations 00200 int verbose = 1; 00201 double opts[SBA_OPTSSZ] = { 00202 0.1, //Tau 00203 1e-20, //E1 00204 1e-20, //E2 00205 0, //E3 average reprojection error 00206 0 //E4 relative reduction in the RMS reprojection error 00207 }; 00208 00209 double info[SBA_INFOSZ]; 00210 00211 //use sba library 00212 int iter = sba_motstr_levmar_x(n, ncon, m, mcon, vmask, p, cnp, pnp, x, NULL, mnp, 00213 img_projsKRTS_x, NULL, (void*)&data, itmax, 0, opts, info); 00214 std::cout<<"SBA ("<<nz_count<<") returned in "<<iter<<" iter, reason "<<info[6] 00215 <<", error "<<info[1]<<" [initial "<< info[0]<<"]\n"; 00216 if(iter>1) 00217 { 00218 //set new values: 00219 idx_visible = 0; 00220 p_local = p; 00221 for ( i=0; i < m; ++i ) 00222 {//for each camera: 00223 int idx_cam = idx_cameras[i]; 00224 //intra parameters first: 00225 libmv::Mat3 rotation_mat; 00226 libmv::Vec3 translation_vec; 00227 cv::Ptr<Camera> intra=cameras[ idx_cam ].getIntraParameters( ); 00228 cv::cv2eigen( cameras[ idx_cam ].getRotationMatrix( ), rotation_mat ); 00229 cv::cv2eigen( cameras[ idx_cam ].getTranslationVector( ), translation_vec ); 00230 00231 int idx_intra = data.idx[i]; 00232 libmv::Mat3& K = data.intraParams[ idx_intra ]; 00233 double* pIntra=p+idx_intra*cnp; 00234 double Kparms[] = {K( 0,0 ) + pIntra[0], K( 2,0 ) + pIntra[1], 00235 K( 2,1 ) + pIntra[2], pIntra[3], K( 1,0 ) + pIntra[4] }; 00236 /* 00237 std::cout<<std::endl<<"old intra : "<<intra->getIntraMatrix()<<std::endl; 00238 std::cout<<idx_intra<<"; "<< 00239 pIntra[0]<<" "<<pIntra[1]<<" "<<pIntra[2]<<" "<<pIntra[3]<<std::endl; 00240 intra->updateIntrinsic( Kparms, 5, false ); 00241 std::cout<<"new intra : "<<intra->getIntraMatrix()<<std::endl;*/ 00242 00243 Eigen::Quaterniond rot_init = data.rotations[i]; 00244 double c1 = p_local[5]; 00245 double c2 = p_local[6]; 00246 double c3 = p_local[7]; 00247 double coef=(1.0 - c1*c1 - c2*c2 - c3*c3 ); 00248 if( coef>0 ) 00249 coef = sqrt( coef ); 00250 else//problem with this rotation... 00251 { 00252 coef = 0; 00253 Eigen::Quaterniond quat_delta( coef, c1, c2, c3 ); 00254 quat_delta.normalize(); 00255 c1=quat_delta.x(); c2=quat_delta.y(); c3=quat_delta.z(); 00256 coef = quat_delta.w(); 00257 } 00258 00259 Eigen::Quaterniond quat_delta( coef, c1, c2, c3 ); 00260 Eigen::Quaterniond rot_total = quat_delta * rot_init; 00261 //add camera parameters to p: 00262 rotation_mat = rot_total.toRotationMatrix(); 00263 00264 translation_vec(0) += p_local[8]; 00265 translation_vec(1) += p_local[9]; 00266 translation_vec(2) += p_local[10]; 00267 00268 //update camera's structure: 00269 cv::Mat newRotation,newTranslation; 00270 cv::eigen2cv( rotation_mat, newRotation ); 00271 cv::eigen2cv( translation_vec, newTranslation ); 00272 cameras[ idx_cam ].setRotationMatrix( newRotation ); 00273 cameras[ idx_cam ].setTranslationVector( newTranslation ); 00274 00275 p_local+=cnp; 00276 } 00277 for ( j = 0; j < point_computed_.size(); ++j ) 00278 {//for each 3D point: 00279 if( pointOK[j]) 00280 { 00281 cv::Vec3d cv3DPoint; 00282 cv3DPoint[ 0 ] = *(p_local++); 00283 cv3DPoint[ 1 ] = *(p_local++); 00284 cv3DPoint[ 2 ] = *(p_local++); 00285 point_computed_[ j ].set3DPosition( cv3DPoint ); 00286 } 00287 } 00288 00289 } 00290 00291 delete [] vmask;//visibility mask 00292 delete [] p;//initial parameter vector p0: (a1, ..., am, b1, ..., bn). 00293 delete [] x;// measurement vector 00294 } 00295 00296 void calcImgProjFullR(double a[5],double qr0[4],double t[3],double M[3], 00297 double n[2]) 00298 { 00299 double t1; 00300 double t11; 00301 double t13; 00302 double t17; 00303 double t2; 00304 double t22; 00305 double t27; 00306 double t3; 00307 double t38; 00308 double t46; 00309 double t49; 00310 double t5; 00311 double t6; 00312 double t8; 00313 double t9; 00314 { 00315 t1 = a[0]; 00316 t2 = qr0[1]; 00317 t3 = M[0]; 00318 t5 = qr0[2]; 00319 t6 = M[1]; 00320 t8 = qr0[3]; 00321 t9 = M[2]; 00322 t11 = -t3*t2-t5*t6-t8*t9; 00323 t13 = qr0[0]; 00324 t17 = t13*t3+t5*t9-t8*t6; 00325 t22 = t6*t13+t8*t3-t9*t2; 00326 t27 = t13*t9+t6*t2-t5*t3; 00327 t38 = -t5*t11+t13*t22-t27*t2+t8*t17+t[1]; 00328 t46 = -t11*t8+t13*t27-t5*t17+t2*t22+t[2]; 00329 t49 = 1/t46; 00330 n[0] = (t1*(-t2*t11+t13*t17-t22*t8+t5*t27+t[0])+a[4]*t38+a[1]*t46)*t49; 00331 n[1] = (t1*a[3]*t38+a[2]*t46)*t49; 00332 return; 00333 } 00334 } 00335 00336 void img_projsRTS_x(/*cameras and points*/ double *p, 00337 /*sparse matrix of 2D points*/ struct sba_crsm *idxij, 00338 /*tmp vector*/int *rcidxs, /*tmp vector*/int *rcsubs, 00339 /*out vect*/double *hx, 00340 void *adata) 00341 { 00342 //as we do an euclidean bundle adjustement, the adata contain constant params. 00343 bundle_datas* datas = ((bundle_datas*)adata); 00344 register int i, j; 00345 int cnp = datas->cnp, pnp = datas->pnp, mnp = datas->mnp; 00346 double *pa, *pb, *pqr, *pt, *ppt, *pmeas, lrot[4], trot[4]; 00347 //int n; 00348 int m, nnz; 00349 00350 m=idxij->nc; 00351 pa=p; pb=p+m*cnp; 00352 00353 for(j=0; j<m; ++j){ 00354 /* j-th camera parameters */ 00355 libmv::Mat3 rotation; 00356 00357 int idx_intra = datas->idx[j]; 00358 libmv::Mat3& K = datas->intraParams[ idx_intra ]; 00359 double Kparms[] = {K( 0,0 ),K( 2,0 ),K( 2,1 ),K( 1,1 )/K( 0,0 ),K( 1,0 )}; 00360 00361 Eigen::Quaterniond rot_init = datas->rotations[j]; 00362 // full quat for initial rotation estimate: 00363 double pr0[] = {rot_init.w(), rot_init.x(), rot_init.y(), rot_init.z()}; 00364 libmv::Mat34 proj; 00365 00366 pqr=pa+j*cnp; 00367 pt=pqr+3; // quaternion vector part has 3 elements 00368 libmv::Vec3 translat = datas->translations[j]; 00369 double trans[3] = { 00370 pt[0] + translat(0), 00371 pt[1] + translat(1), 00372 pt[2] + translat(2)}; 00373 lrot[1]=pqr[0]; lrot[2]=pqr[1]; lrot[3]=pqr[2]; 00374 lrot[0]=(1.0 - lrot[1]*lrot[1] - lrot[2]*lrot[2]- lrot[3]*lrot[3]); 00375 if( lrot[0]>0 ) 00376 lrot[0] = sqrt( lrot[0] ); 00377 else{//problem with this rotation... 00378 lrot[0] = 0; 00379 Eigen::Quaterniond quat_delta( lrot[0], lrot[1], lrot[2], lrot[3] ); 00380 quat_delta.normalize(); 00381 lrot[1]=quat_delta.x(); lrot[2]=quat_delta.y(); lrot[3]=quat_delta.z(); 00382 lrot[0] = quat_delta.w(); 00383 } 00384 00385 quatMultFast(lrot, pr0, trot); // trot=lrot*pr0 00386 00387 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs); /* find nonzero hx_ij, i=0...n-1 */ 00388 00389 for(i=0; i<nnz; ++i){ 00390 ppt=pb + rcsubs[i]*pnp; 00391 pmeas=hx + idxij->val[rcidxs[i]]*mnp; // set pmeas to point to hx_ij 00392 00393 calcImgProjFullR(Kparms, trot, trans, ppt, pmeas); // evaluate Q in pmeas 00394 } 00395 } 00396 } 00397 00398 void img_projsKRTS_x(/*cameras and points*/ double *p, 00399 /*sparse matrix of 2D points*/ struct sba_crsm *idxij, 00400 /*tmp vector*/int *rcidxs, /*tmp vector*/int *rcsubs, 00401 /*out vect*/double *hx, 00402 void *adata) 00403 { 00404 //as we do an euclidean bundle adjustement, the adata contain constant params. 00405 bundle_datas* datas = ((bundle_datas*)adata); 00406 register int i, j; 00407 int cnp = datas->cnp, pnp = datas->pnp, mnp = datas->mnp; 00408 double *pa, *pb, *pqr, *pt, *ppt, *pmeas, lrot[4], trot[4]; 00409 //int n; 00410 int m, nnz; 00411 00412 m=idxij->nc; 00413 pa=p; pb=p+m*cnp; 00414 00415 for(j=0; j<m; ++j){ 00416 /* j-th camera parameters */ 00417 libmv::Mat3 rotation; 00418 00419 int idx_intra = datas->idx[j]; 00420 libmv::Mat3& K = datas->intraParams[ idx_intra ]; 00421 double* pIntra=p+idx_intra*cnp; 00422 double Kparms[] = {K( 0,0 ) + pIntra[0], K( 2,0 ) + pIntra[1], 00423 K( 2,1 ) + pIntra[2], 1, 0};//pIntra[3], K( 1,0 ) + pIntra[4] }; 00424 00425 Eigen::Quaterniond rot_init = datas->rotations[j]; 00426 00427 // full quat for initial rotation estimate: 00428 double pr0[] = {rot_init.w(), rot_init.x(), rot_init.y(), rot_init.z()}; 00429 libmv::Mat34 proj; 00430 00431 pqr=pa + j*cnp + 5;//skip the intra parameters... 00432 pt=pqr + 3; // quaternion vector part has 3 elements 00433 libmv::Vec3 translat = datas->translations[j]; 00434 double trans[3] = { 00435 pt[0] + translat(0), 00436 pt[1] + translat(1), 00437 pt[2] + translat(2)}; 00438 lrot[1]=pqr[0]; lrot[2]=pqr[1]; lrot[3]=pqr[2]; 00439 lrot[0]=(1.0 - lrot[1]*lrot[1] - lrot[2]*lrot[2]- lrot[3]*lrot[3]); 00440 if( lrot[0]>0 ) 00441 lrot[0] = sqrt( lrot[0] ); 00442 else{//problem with this rotation... 00443 lrot[0] = 0; 00444 Eigen::Quaterniond quat_delta( lrot[0], lrot[1], lrot[2], lrot[3] ); 00445 quat_delta.normalize(); 00446 lrot[1]=quat_delta.x(); lrot[2]=quat_delta.y(); lrot[3]=quat_delta.z(); 00447 lrot[0] = quat_delta.w(); 00448 } 00449 00450 quatMultFast(lrot, pr0, trot); // trot=lrot*pr0 00451 00452 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs); /* find nonzero hx_ij, i=0...n-1 */ 00453 00454 for(i=0; i<nnz; ++i){ 00455 ppt=pb + rcsubs[i]*pnp; 00456 pmeas=hx + idxij->val[rcidxs[i]]*mnp; // set pmeas to point to hx_ij 00457 00458 calcImgProjFullR(Kparms, trot, trans, ppt, pmeas); // evaluate Q in pmeas 00459 } 00460 } 00461 } 00462 00463 void img_projsRT_x(/*cameras and points*/ double *p, 00464 /*sparse matrix of 2D points*/ struct sba_crsm *idxij, 00465 /*tmp vector*/int *rcidxs, /*tmp vector*/int *rcsubs, 00466 /*out vect*/double *hx, 00467 void *adata) 00468 { 00469 //as we do an euclidean bundle adjustement, the adata contain constant params. 00470 bundle_datas* datas = ((bundle_datas*)adata); 00471 register int i, j; 00472 int cnp = datas->cnp, pnp = datas->pnp, mnp = datas->mnp; 00473 double *pa, *pb, *pqr, *pt, *ppt, *pmeas, lrot[4], trot[4]; 00474 //int n; 00475 int m, nnz; 00476 00477 m=idxij->nc; 00478 pa=p; 00479 00480 pb = datas->points3D; 00481 00482 for(j=0; j<m; ++j){ 00483 /* j-th camera parameters */ 00484 libmv::Mat3 rotation; 00485 00486 int idx_intra = datas->idx[j]; 00487 libmv::Mat3& K = datas->intraParams[ idx_intra ]; 00488 double Kparms[] = {K( 0,0 ),K( 2,0 ),K( 2,1 ),K( 1,1 )/K( 0,0 ),K( 1,0 )}; 00489 00490 Eigen::Quaterniond rot_init = datas->rotations[j]; 00491 00492 // full quat for initial rotation estimate: 00493 double pr0[] = {rot_init.w(), rot_init.x(), rot_init.y(), rot_init.z()}; 00494 libmv::Mat34 proj; 00495 00496 pqr=pa+j*cnp; 00497 pt=pqr+3; // quaternion vector part has 3 elements 00498 libmv::Vec3 translat = datas->translations[j]; 00499 double trans[3] = { 00500 pt[0] + translat(0), 00501 pt[1] + translat(1), 00502 pt[2] + translat(2)}; 00503 lrot[1]=pqr[0]; lrot[2]=pqr[1]; lrot[3]=pqr[2]; 00504 lrot[0]=(1.0 - lrot[1]*lrot[1] - lrot[2]*lrot[2]- lrot[3]*lrot[3]); 00505 if( lrot[0]>0 ) 00506 lrot[0] = sqrt( lrot[0] ); 00507 else{//problem with this rotation... 00508 lrot[0] = 0; 00509 Eigen::Quaterniond quat_delta( lrot[0], lrot[1], lrot[2], lrot[3] ); 00510 quat_delta.normalize(); 00511 lrot[1]=quat_delta.x(); lrot[2]=quat_delta.y(); lrot[3]=quat_delta.z(); 00512 lrot[0] = quat_delta.w(); 00513 } 00514 00515 quatMultFast(lrot, pr0, trot); // trot=lrot*pr0 00516 00517 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs); /* find nonzero hx_ij, i=0...n-1 */ 00518 00519 for(i=0; i<nnz; ++i){ 00520 ppt=pb + rcsubs[i]*pnp; 00521 pmeas=hx + idxij->val[rcidxs[i]]*mnp; // set pmeas to point to hx_ij 00522 calcImgProjFullR(Kparms, trot, trans, ppt, pmeas); // evaluate Q in pmeas 00523 } 00524 } 00525 } 00526 void calcImgProjJacRTS(double a[5],double qr0[4],double v[3],double t[3], 00527 double M[3],double jacmRT[2][6],double jacmS[2][3]) 00528 { 00529 double t1; 00530 double t10; 00531 double t107; 00532 double t109; 00533 double t11; 00534 double t118; 00535 double t12; 00536 double t126; 00537 double t127; 00538 double t14; 00539 double t141; 00540 double t145; 00541 double t146; 00542 double t147; 00543 double t15; 00544 double t150; 00545 double t152; 00546 double t159; 00547 double t16; 00548 double t162; 00549 double t165; 00550 double t168; 00551 double t170; 00552 double t172; 00553 double t175; 00554 double t18; 00555 double t180; 00556 double t185; 00557 double t187; 00558 double t19; 00559 double t192; 00560 double t194; 00561 double t2; 00562 double t206; 00563 double t21; 00564 double t216; 00565 double t22; 00566 double t227; 00567 double t23; 00568 double t230; 00569 double t233; 00570 double t235; 00571 double t237; 00572 double t240; 00573 double t245; 00574 double t25; 00575 double t250; 00576 double t252; 00577 double t257; 00578 double t259; 00579 double t27; 00580 double t271; 00581 double t28; 00582 double t281; 00583 double t293; 00584 double t294; 00585 double t296; 00586 double t299; 00587 double t3; 00588 double t30; 00589 double t302; 00590 double t303; 00591 double t305; 00592 double t306; 00593 double t309; 00594 double t324; 00595 double t325; 00596 double t327; 00597 double t330; 00598 double t331; 00599 double t347; 00600 double t35; 00601 double t350; 00602 double t37; 00603 double t4; 00604 double t43; 00605 double t49; 00606 double t5; 00607 double t51; 00608 double t52; 00609 double t54; 00610 double t56; 00611 double t6; 00612 double t61; 00613 double t65; 00614 double t7; 00615 double t70; 00616 double t75; 00617 double t76; 00618 double t81; 00619 double t82; 00620 double t87; 00621 double t88; 00622 double t9; 00623 double t93; 00624 double t94; 00625 double t98; 00626 { 00627 t1 = a[0]; 00628 t2 = v[0]; 00629 t3 = t2*t2; 00630 t4 = v[1]; 00631 t5 = t4*t4; 00632 t6 = v[2]; 00633 t7 = t6*t6; 00634 t9 = sqrt(1.0-t3-t5-t7); 00635 t10 = 1/t9; 00636 t11 = qr0[1]; 00637 t12 = t11*t10; 00638 t14 = qr0[0]; 00639 t15 = -t12*t2+t14; 00640 t16 = M[0]; 00641 t18 = qr0[2]; 00642 t19 = t18*t10; 00643 t21 = qr0[3]; 00644 t22 = -t19*t2-t21; 00645 t23 = M[1]; 00646 t25 = t10*t21; 00647 t27 = -t25*t2+t18; 00648 t28 = M[2]; 00649 t30 = -t15*t16-t22*t23-t27*t28; 00650 t35 = -t9*t11-t2*t14-t4*t21+t6*t18; 00651 t37 = -t35; 00652 t43 = t9*t18+t4*t14+t6*t11-t2*t21; 00653 t49 = t9*t21+t6*t14+t2*t18-t11*t4; 00654 t51 = -t37*t16-t43*t23-t49*t28; 00655 t52 = -t15; 00656 t54 = t10*t14; 00657 t56 = -t54*t2-t11; 00658 t61 = t9*t14-t2*t11-t4*t18-t6*t21; 00659 t65 = t61*t16+t43*t28-t23*t49; 00660 t70 = t56*t16+t22*t28-t23*t27; 00661 t75 = t56*t23+t27*t16-t28*t15; 00662 t76 = -t49; 00663 t81 = t61*t23+t49*t16-t37*t28; 00664 t82 = -t27; 00665 t87 = t56*t28+t23*t15-t22*t16; 00666 t88 = -t43; 00667 t93 = t61*t28+t37*t23-t43*t16; 00668 t94 = -t22; 00669 t98 = a[4]; 00670 t107 = t30*t88+t94*t51+t56*t81+t61*t75+t87*t35+t93*t52-t70*t76-t82*t65; 00671 t109 = a[1]; 00672 t118 = t30*t76+t82*t51+t56*t93+t61*t87+t70*t88+t65*t94-t35*t75-t81*t52; 00673 t126 = t76*t51+t61*t93+t65*t88-t81*t35+t[2]; 00674 t127 = 1/t126; 00675 t141 = t51*t88+t61*t81+t93*t35-t65*t76+t[1]; 00676 t145 = t126*t126; 00677 t146 = 1/t145; 00678 t147 = (t1*(t35*t51+t61*t65+t81*t76-t93*t88+t[0])+t98*t141+t126*t109)*t146; 00679 jacmRT[0][0] = (t1*(t30*t35+t52*t51+t56*t65+t61*t70+t76*t75+t81*t82-t88*t87 00680 -t93*t94)+t98*t107+t109*t118)*t127-t118*t147; 00681 t150 = t1*a[3]; 00682 t152 = a[2]; 00683 t159 = (t150*t141+t126*t152)*t146; 00684 jacmRT[1][0] = (t107*t150+t152*t118)*t127-t159*t118; 00685 t162 = -t12*t4+t21; 00686 t165 = -t19*t4+t14; 00687 t168 = -t25*t4-t11; 00688 t170 = -t162*t16-t165*t23-t168*t28; 00689 t172 = -t162; 00690 t175 = -t54*t4-t18; 00691 t180 = t175*t16+t165*t28-t168*t23; 00692 t185 = t175*t23+t168*t16-t162*t28; 00693 t187 = -t168; 00694 t192 = t175*t28+t162*t23-t165*t16; 00695 t194 = -t165; 00696 t206 = t170*t88+t51*t194+t175*t81+t61*t185+t192*t35+t93*t172-t76*t180-t65* 00697 t187; 00698 t216 = t170*t76+t51*t187+t93*t175+t61*t192+t180*t88+t65*t194-t185*t35-t81* 00699 t172; 00700 jacmRT[0][1] = (t1*(t170*t35+t172*t51+t175*t65+t180*t61+t185*t76+t81*t187- 00701 t192*t88-t93*t194)+t98*t206+t109*t216)*t127-t147*t216; 00702 jacmRT[1][1] = (t150*t206+t152*t216)*t127-t159*t216; 00703 t227 = -t12*t6-t18; 00704 t230 = -t19*t6+t11; 00705 t233 = -t25*t6+t14; 00706 t235 = -t227*t16-t23*t230-t233*t28; 00707 t237 = -t227; 00708 t240 = -t54*t6-t21; 00709 t245 = t240*t16+t230*t28-t233*t23; 00710 t250 = t23*t240+t233*t16-t227*t28; 00711 t252 = -t233; 00712 t257 = t240*t28+t227*t23-t230*t16; 00713 t259 = -t230; 00714 t271 = t235*t88+t51*t259+t81*t240+t61*t250+t257*t35+t93*t237-t245*t76-t65* 00715 t252; 00716 t281 = t235*t76+t51*t252+t240*t93+t61*t257+t245*t88+t259*t65-t250*t35-t81* 00717 t237; 00718 jacmRT[0][2] = (t1*(t235*t35+t237*t51+t240*t65+t61*t245+t250*t76+t81*t252- 00719 t257*t88-t93*t259)+t271*t98+t281*t109)*t127-t147*t281; 00720 jacmRT[1][2] = (t150*t271+t281*t152)*t127-t159*t281; 00721 jacmRT[0][3] = t127*t1; 00722 jacmRT[1][3] = 0.0; 00723 jacmRT[0][4] = t98*t127; 00724 jacmRT[1][4] = t150*t127; 00725 jacmRT[0][5] = t109*t127-t147; 00726 jacmRT[1][5] = t152*t127-t159; 00727 t293 = t35*t35; 00728 t294 = t61*t61; 00729 t296 = t88*t88; 00730 t299 = t35*t88; 00731 t302 = t61*t76; 00732 t303 = 2.0*t299+t61*t49-t302; 00733 t305 = t35*t76; 00734 t306 = t61*t88; 00735 t309 = t305+2.0*t306-t49*t35; 00736 jacmS[0][0] = (t1*(t293+t294+t49*t76-t296)+t98*t303+t109*t309)*t127-t147* 00737 t309; 00738 jacmS[1][0] = (t150*t303+t152*t309)*t127-t159*t309; 00739 t324 = t76*t76; 00740 t325 = t296+t294+t35*t37-t324; 00741 t327 = t76*t88; 00742 t330 = t61*t35; 00743 t331 = 2.0*t327+t61*t37-t330; 00744 jacmS[0][1] = (t1*(t299+2.0*t302-t37*t88)+t98*t325+t109*t331)*t127-t147* 00745 t331; 00746 jacmS[1][1] = (t150*t325+t152*t331)*t127-t159*t331; 00747 t347 = t327+2.0*t330-t43*t76; 00748 t350 = t324+t294+t43*t88-t293; 00749 jacmS[0][2] = (t1*(2.0*t305+t61*t43-t306)+t98*t347+t350*t109)*t127-t147* 00750 t350; 00751 jacmS[1][2] = (t150*t347+t152*t350)*t127-t159*t350; 00752 return; 00753 } 00754 } 00755 00756 void img_projsRTS_jac_x(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata) 00757 { 00758 bundle_datas* datas = ((bundle_datas*)adata); 00759 register int i, j; 00760 int cnp = datas->cnp, pnp = datas->pnp, mnp = datas->mnp; 00761 00762 double *pa, *pb, *pqr, *pt, *ppt, *pA, *pB; 00763 //int n; 00764 int m, nnz, Asz, Bsz, ABsz; 00765 00766 //n=idxij->nr; 00767 m=idxij->nc; 00768 pa=p; pb=p+m*cnp; 00769 Asz=mnp*cnp; Bsz=mnp*pnp; ABsz=Asz+Bsz; 00770 00771 for(j=0; j<m; ++j){ 00772 /* j-th camera parameters */ 00773 pqr=pa+j*cnp; 00774 pt=pqr+3; // quaternion vector part has 3 elements 00775 libmv::Vec3 translat = datas->translations[j]; 00776 double vec_translat[3] = { 00777 pt[0] + translat(0), 00778 pt[1] + translat(1), 00779 pt[2] + translat(2)}; 00780 libmv::Mat3 rotation; 00781 libmv::Mat3& K = datas->intraParams[j]; 00782 Eigen::Quaterniond rot_init = datas->rotations[j]; 00783 00784 double Kparms[] = {K( 0,0 ),K( 2,0 ),K( 2,1 ),K( 1,1 )/K( 0,0 ),K( 1,0 )}; 00785 // full quat for initial rotation estimate: 00786 double pr0[] = {rot_init.w(), rot_init.x(), rot_init.y(), rot_init.z()}; 00787 libmv::Mat34 proj; 00788 00789 nnz=sba_crsm_col_elmidxs(idxij, j, rcidxs, rcsubs); /* find nonzero hx_ij, i=0...n-1 */ 00790 00791 for(i=0; i<nnz; ++i){ 00792 ppt=pb + rcsubs[i]*pnp; 00793 pA=jac + idxij->val[rcidxs[i]]*ABsz; // set pA to point to A_ij 00794 pB=pA + Asz; // set pB to point to B_ij 00795 00796 calcImgProjJacRTS(Kparms, pr0, pqr, vec_translat, ppt, (double (*)[6])pA, (double (*)[3])pB); // evaluate dQ/da, dQ/db in pA, pB 00797 } 00798 } 00799 } 00800 00801 }