GSoC2011SfM  0.1
Google Summer of Code 2011: Structure from motion
D:/Travail/These/Determination caracteristiques camera/GSoC/SfM/src/bundle_related.cpp
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 }
 All Classes Functions Variables