⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sba_levmar.c

📁 sba, a C/C++ package for generic sparse bundle adjustment is almost invariably used as the last step
💻 C
📖 第 1 页 / 共 5 页
字号:
        for(i=0, dL=0.0; i<nvars; ++i)          dL+=dp[i]*(mu*dp[i]+eab[i]);        dF=p_eL2-pdp_eL2;        if(verbose>1)          printf("\ndamping term %8g, gain ratio %8g, errors %8g / %8g = %g\n", mu, dL!=0.0? dF/dL : dF/DBL_EPSILON, p_eL2/nvis, pdp_eL2/nvis, p_eL2/pdp_eL2);        if(dL>0.0 && dF>0.0){ /* reduction in error, increment is accepted */          tmp=(2.0*dF/dL-1.0);          tmp=1.0-tmp*tmp*tmp;          mu=mu*( (tmp>=SBA_ONE_THIRD)? tmp : SBA_ONE_THIRD );          nu=2;          /* the test below is equivalent to the relative reduction of the RMS reprojection error: sqrt(p_eL2)-sqrt(pdp_eL2)<eps4*sqrt(p_eL2) */          if(pdp_eL2-2.0*sqrt(p_eL2*pdp_eL2)<(eps4_sq-1.0)*p_eL2) stop=4;                    for(i=0; i<nvars; ++i) /* update p's estimate */            p[i]=pdp[i];          for(i=0; i<nobs; ++i) /* update e and ||e||_2 */            e[i]=hx[i];          p_eL2=pdp_eL2;          break;        }      } /* issolved */moredamping:      /* if this point is reached (also via an explicit goto!), either the linear system could       * not be solved or the error did not reduce; in any case, the increment must be rejected       */      mu*=nu;      nu2=nu<<1; // 2*nu;      if(nu2<=nu){ /* nu has wrapped around (overflown) */        fprintf(stderr, "SBA: too many failed attempts to increase the damping factor in sba_motstr_levmar_x()! Singular Hessian matrix?\n");        //exit(1);        stop=6;        break;      }      nu=nu2;      /* restore U, V diagonal entries */      for(j=mcon; j<m; ++j){        ptr1=U + j*Usz; // set ptr1 to point to U_j        ptr2=diagU + j*cnp; // set ptr2 to point to diagU_j        for(i=0; i<cnp; ++i)          ptr1[i*cnp+i]=ptr2[i];      }      for(i=0; i<n; ++i){        ptr1=V + i*Vsz; // set ptr1 to point to V_i        ptr2=diagV + i*pnp; // set ptr2 to point to diagV_i        for(j=0; j<pnp; ++j)          ptr1[j*pnp+j]=ptr2[j];      }    } /* inner while loop */    if(p_eL2<=eps3_sq) stop=5; // error is small, force termination of outer loop  }  if(itno>=itmax) stop=3;  /* restore U, V diagonal entries */  for(j=mcon; j<m; ++j){    ptr1=U + j*Usz; // set ptr1 to point to U_j    ptr2=diagU + j*cnp; // set ptr2 to point to diagU_j    for(i=0; i<cnp; ++i)      ptr1[i*cnp+i]=ptr2[i];  }  for(i=0; i<n; ++i){    ptr1=V + i*Vsz; // set ptr1 to point to V_i    ptr2=diagV + i*pnp; // set ptr2 to point to diagV_i    for(j=0; j<pnp; ++j)     ptr1[j*pnp+j]=ptr2[j];  }  if(info){    info[0]=init_p_eL2;    info[1]=p_eL2;    info[2]=eab_inf;    info[3]=dp_L2;    for(j=mcon, tmp=DBL_MIN; j<m; ++j){      ptr1=U + j*Usz; // set ptr1 to point to U_j      for(i=0; i<cnp; ++i)        if(tmp<ptr1[i*cnp+i]) tmp=ptr1[i*cnp+i];    }    for(i=0; i<n; ++i){      ptr1=V + i*Vsz; // set ptr1 to point to V_i      for(j=0; j<pnp; ++j)        if(tmp<ptr1[j*pnp+j]) tmp=ptr1[j*pnp+j];      }    info[4]=mu/tmp;    info[5]=itno;    info[6]=stop;    info[7]=nfev;    info[8]=njev;    info[9]=nlss;  }                                                                 //sba_print_sol(n, m, p, cnp, pnp, x, mnp, &idxij, rcidxs, rcsubs);  retval=(stop!=7)?  itno : SBA_ERROR;freemem_and_return: /* NOTE: this point is also reached via a goto! */   /* free whatever was allocated */  free(W);   free(U);  free(V);  free(e);   free(eab);  free(E);   free(Yj); free(YWt);  free(S);   free(dp); free(Wtda);  free(rcidxs); free(rcsubs);#ifndef SBA_DESTROY_COVS  if(wght) free(wght);#else  /* nothing to do */#endif /* SBA_DESTROY_COVS */  free(hx); free(diagUV); free(pdp);  if(fdj_data.hxx){ // cleanup    free(fdj_data.hxx);    free(fdj_data.func_rcidxs);  }  sba_crsm_free(&idxij);  /* free the memory allocated by the matrix inversion & linear solver routines */  if(matinv) (*matinv)(NULL, 0);  if(linsolver) (*linsolver)(NULL, NULL, NULL, 0, 0);  return retval;}/* Bundle adjustment on camera parameters only  * using the sparse Levenberg-Marquardt as described in HZ p. 568 * * Returns the number of iterations (>=0) if successfull, SBA_ERROR if failed */int sba_mot_levmar_x(    const int n,   /* number of points */    const int m,   /* number of images */    const int mcon,/* number of images (starting from the 1st) whose parameters should not be modified.					          * All A_ij (see below) with j<mcon are assumed to be zero					          */    char *vmask,  /* visibility mask: vmask[i, j]=1 if point i visible in image j, 0 otherwise. nxm */    double *p,    /* initial parameter vector p0: (a1, ..., am).                   * aj are the image j parameters, size m*cnp */    const int cnp,/* number of parameters for ONE camera; e.g. 6 for Euclidean cameras */    double *x,    /* measurements vector: (x_11^T, .. x_1m^T, ..., x_n1^T, .. x_nm^T)^T where                   * x_ij is the projection of the i-th point on the j-th image.                   * NOTE: some of the x_ij might be missing, if point i is not visible in image j;                   * see vmask[i, j], max. size n*m*mnp                   */    double *covx, /* measurements covariance matrices: (Sigma_x_11, .. Sigma_x_1m, ..., Sigma_x_n1, .. Sigma_x_nm),                   * where Sigma_x_ij is the mnp x mnp covariance of x_ij stored row-by-row. Set to NULL if no                   * covariance estimates are available (identity matrices are implicitly used in this case).                   * NOTE: a certain Sigma_x_ij is missing if the corresponding x_ij is also missing;                   * see vmask[i, j], max. size n*m*mnp*mnp                   */    const int mnp,/* number of parameters for EACH measurement; usually 2 */    void (*func)(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *hx, void *adata),                                              /* functional relation describing measurements. Given a parameter vector p,                                               * computes a prediction of the measurements \hat{x}. p is (m*cnp)x1,                                               * \hat{x} is (n*m*mnp)x1, maximum                                               * rcidxs, rcsubs are max(m, n) x 1, allocated by the caller and can be used                                               * as working memory                                               */    void (*fjac)(double *p, struct sba_crsm *idxij, int *rcidxs, int *rcsubs, double *jac, void *adata),                                              /* function to evaluate the sparse jacobian dX/dp.                                               * The Jacobian is returned in jac as                                               * (dx_11/da_1, ..., dx_1m/da_m, ..., dx_n1/da_1, ..., dx_nm/da_m), or (using HZ's notation),                                               * jac=(A_11, ..., A_1m, ..., A_n1, ..., A_nm)                                               * Notice that depending on idxij, some of the A_ij might be missing.                                               * Note also that the A_ij are mnp x cnp matrices and they                                               * should be stored in jac in row-major order.                                               * rcidxs, rcsubs are max(m, n) x 1, allocated by the caller and can be used                                               * as working memory                                               *                                               * If NULL, the jacobian is approximated by repetitive func calls and finite                                               * differences. This is computationally inefficient and thus NOT recommended.                                               */    void *adata,       /* pointer to possibly additional data, passed uninterpreted to func, fjac */     const int itmax,   /* I: maximum number of iterations. itmax==0 signals jacobian verification followed by immediate return */    const int verbose, /* I: verbosity */    const double opts[SBA_OPTSSZ],	                     /* I: minim. options [\mu, \epsilon1, \epsilon2, \epsilon3, \epsilon4]. Respectively the scale factor for initial \mu,                        * stopping thresholds for ||J^T e||_inf, ||dp||_2, ||e||_2 and (||e||_2-||e_new||_2)/||e||_2                        */    double info[SBA_INFOSZ]	                     /* O: information regarding the minimization. Set to NULL if don't care                        * info[0]=||e||_2 at initial p.                        * info[1-4]=[ ||e||_2, ||J^T e||_inf,  ||dp||_2, mu/max[J^T J]_ii ], all computed at estimated p.                        * info[5]= # iterations,                        * info[6]=reason for terminating: 1 - stopped by small gradient J^T e                        *                                 2 - stopped by small dp                        *                                 3 - stopped by itmax                        *                                 4 - stopped by small relative reduction in ||e||_2                        *                                 5 - stopped by small ||e||_2                        *                                 6 - too many attempts to increase damping. Restart with increased mu                        *                                 7 - stopped by invalid (i.e. NaN or Inf) "func" values. This is a user error                        * info[7]= # function evaluations                        * info[8]= # jacobian evaluations			                  * info[9]= # number of linear systems solved, i.e. number of attempts	for reducing error                        */){register int i, j, ii, jj, k;int nvis, nnz, retval;/* The following are work arrays that are dynamically allocated by sba_mot_levmar_x() */double *jac; /* work array for storing the jacobian, max. size n*m*mnp*cnp */double *U;    /* work array for storing the U_j in the order U_1, ..., U_m, size m*cnp*cnp */double *e;    /* work array for storing the e_ij in the order e_11, ..., e_1m, ..., e_n1, ..., e_nm,                 max. size n*m*mnp */double *ea;   /* work array for storing the ea_j in the order ea_1, .. ea_m, size m*cnp */double *dp;   /* work array for storing the parameter vector updates da_1, ..., da_m, size m*cnp */double *wght= /* work array for storing the weights computed from the covariance inverses, max. size n*m*mnp*mnp */            NULL;/* Of the above arrays, jac, e, wght are sparse and * U, ea, dp are dense. Sparse arrays are indexed through * idxij (see below), that is with the same mechanism as the input  * measurements vector x *//* submatrices sizes */int Asz, Usz,    esz, easz, covsz;register double *ptr1, *ptr2, *ptr3, *ptr4, sum;struct sba_crsm idxij; /* sparse matrix containing the location of x_ij in x. This is also the location of A_ij                         * in jac, e_ij in e, etc.                        * This matrix can be thought as a map from a sparse set of pairs (i, j) to a continuous                        * index k and it is used to efficiently lookup the memory locations where the non-zero                        * blocks of a sparse matrix/vector are stored                        */int maxCPvis, /* max. of projections across cameras & projections across points */    *rcidxs,  /* work array for the indexes corresponding to the nonzero elements of a single row or                 column in a sparse matrix, size max(n, m) */    *rcsubs;  /* work array for the subscripts of nonzero elements in a single row or column of a                 sparse matrix, size max(n, m) *//* The following variables are needed by the LM algorithm */register int itno;  /* iteration counter */int nsolved;/* temporary work arrays that are dynamically allocated */double *hx,         /* \hat{x}_i, max. size m*n*mnp */       *diagU,      /* diagonals of U_j, size m*cnp */       *pdp;        /* p + dp, size m*cnp */register double mu,  /* damping constant */                tmp; /* mainly used in matrix & vector multiplications */double p_eL2, ea_inf, pdp_eL2; /* ||e(p)||_2, ||J^T e||_inf, ||e(p+dp)||_2 */double p_L2, dp_L2=DBL_MAX, dF, dL;double tau=FABS(opts[0]), eps1=FABS(opts[1]), eps2=FABS(opts[2]), eps2_sq=opts[2]*opts[2],       eps3_sq=opts[3]*opts[3], eps4_sq=opts[4]*opts[4];double init_p_eL2;int nu=2, nu2, stop=0, nfev, njev=0, nlss=0;int nobs, nvars;PLS linsolver=NULL;struct fdj_data_x_ fdj_data;void *jac_adata;/* Initialization */  mu=ea_inf=0.0; /* -Wall */  /* block sizes */  Asz=mnp * cnp; Usz=cnp * cnp;  esz=mnp; easz=cnp;  covsz=mnp * mnp;    /* count total number of visible image points */  for(i=nvis=0, jj=n*m; i<jj; ++i)    nvis+=(vmask[i]!=0);  nobs=nvis*mnp;  nvars=m*cnp;  if(nobs<nvars){    fprintf(stderr, "SBA: sba_mot_levmar_x() cannot solve a problem with fewer measurements [%d] than unknowns [%d]\n", nobs, nvars);    return SBA_ERROR;  }  /* allocate & fill up the idxij structure */  sba_crsm_alloc(&idxij, n, m, nvis);  for(i=k=0; i<n; ++i){    idxij.rowptr[i]=k;    ii=i*m;    for(j=0; j<m; ++j)      if(vmask[ii+j]){        idxij.val[k]=k;        idxij.colidx[k++]=j;      }  }  idxij.rowptr[n]=nvis;  /* find the maximum number of visible image points in any single camera or coming from a single 3D point */  /* cameras */  for(i=maxCPvis=0; i<n; ++i)    if((k=idxij.rowptr[i+1]-idxij.rowptr[i])>maxCPvis) maxCPvis=k;  /* points, note that maxCPvis is not reinitialized! */  for(j=0; j<m; ++j){    for(i=ii=0; i<n; ++i)      if(vmask[i*m+j]) ++ii;    if(ii>maxCPvis) maxCPvis=ii;  }  /* allocate work arrays */  jac=(double *)emalloc(nvis*Asz*sizeof(double));  U=(double *)emalloc(m*Usz*sizeof(double));  e=(double *)emalloc(nobs*sizeof(double));  ea=(double *)emalloc(nvars*sizeof(double));  dp=(double *)emalloc(nvars*sizeof(double));  rcidxs=(int *)emalloc

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -