Home | History | Annotate | Download | only in db_vlvm
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /* $Id: db_rob_image_homography.cpp,v 1.2 2011/06/17 14:03:31 mbansal Exp $ */
     18 
     19 #include "db_utilities.h"
     20 #include "db_rob_image_homography.h"
     21 #include "db_bundle.h"
     22 
     23 
     24 
     25 /*****************************************************************
     26 *    Lean and mean begins here                                   *
     27 *****************************************************************/
     28 
     29 #include "db_image_homography.h"
     30 
     31 #ifdef _VERBOSE_
     32 #include <iostream>
     33 using namespace std;
     34 #endif /*VERBOSE*/
     35 
     36 inline double db_RobImageHomography_Cost(double H[9],int point_count,double *x_i,double *xp_i,double one_over_scale2)
     37 {
     38     int c;
     39     double back,acc,*x_i_temp,*xp_i_temp;
     40 
     41     for(back=0.0,c=0;c<point_count;)
     42     {
     43         /*Take log of product of ten reprojection
     44         errors to reduce nr of expensive log operations*/
     45         if(c+9<point_count)
     46         {
     47             x_i_temp=x_i+(c<<1);
     48             xp_i_temp=xp_i+(c<<1);
     49 
     50             acc=db_ExpCauchyInhomogenousHomographyError(xp_i_temp,H,x_i_temp,one_over_scale2);
     51             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+2,H,x_i_temp+2,one_over_scale2);
     52             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+4,H,x_i_temp+4,one_over_scale2);
     53             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+6,H,x_i_temp+6,one_over_scale2);
     54             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+8,H,x_i_temp+8,one_over_scale2);
     55             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+10,H,x_i_temp+10,one_over_scale2);
     56             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+12,H,x_i_temp+12,one_over_scale2);
     57             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+14,H,x_i_temp+14,one_over_scale2);
     58             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+16,H,x_i_temp+16,one_over_scale2);
     59             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+18,H,x_i_temp+18,one_over_scale2);
     60             c+=10;
     61         }
     62         else
     63         {
     64             for(acc=1.0;c<point_count;c++)
     65             {
     66                 acc*=db_ExpCauchyInhomogenousHomographyError(xp_i+(c<<1),H,x_i+(c<<1),one_over_scale2);
     67             }
     68         }
     69         back+=log(acc);
     70     }
     71     return(back);
     72 }
     73 
     74 inline double db_RobImageHomography_Statistics(double H[9],int point_count,double *x_i,double *xp_i,double one_over_scale2,db_Statistics *stat,double thresh=DB_OUTLIER_THRESHOLD)
     75 {
     76     int c,i;
     77     double t2,frac;
     78 
     79     t2=thresh*thresh;
     80     for(i=0,c=0;c<point_count;c++)
     81     {
     82         i+=(db_SquaredInhomogenousHomographyError(xp_i+(c<<1),H,x_i+(c<<1))*one_over_scale2<=t2)?1:0;
     83     }
     84     frac=((double)i)/((double)(db_maxi(point_count,1)));
     85 
     86 #ifdef _VERBOSE_
     87     std::cout << "Inlier Percentage RobImageHomography: " << frac*100.0 << "% out of " << point_count << " constraints" << std::endl;
     88 #endif /*_VERBOSE_*/
     89 
     90     if(stat)
     91     {
     92         stat->nr_points=point_count;
     93         stat->one_over_scale2=one_over_scale2;
     94         stat->nr_inliers=i;
     95         stat->inlier_fraction=frac;
     96 
     97         stat->cost=db_RobImageHomography_Cost(H,point_count,x_i,xp_i,one_over_scale2);
     98         stat->model_dimension=0;
     99         /*stat->nr_parameters=;*/
    100 
    101         stat->lambda1=log(4.0);
    102         stat->lambda2=log(4.0*((double)db_maxi(1,stat->nr_points)));
    103         stat->lambda3=10.0;
    104         stat->gric=stat->cost+stat->lambda1*stat->model_dimension*((double)stat->nr_points)+stat->lambda2*((double)stat->nr_parameters);
    105         stat->inlier_evidence=((double)stat->nr_inliers)-stat->lambda3*((double)stat->nr_parameters);
    106     }
    107 
    108     return(frac);
    109 }
    110 
    111 /*Compute min_Jtf and upper right of JtJ. Return cost.*/
    112 inline double db_RobImageHomography_Jacobians(double JtJ[81],double min_Jtf[9],double H[9],int point_count,double *x_i,double *xp_i,double one_over_scale2)
    113 {
    114     double back,Jf_dx[18],f[2],temp,temp2;
    115     int i;
    116 
    117     db_Zero(JtJ,81);
    118     db_Zero(min_Jtf,9);
    119     for(back=0.0,i=0;i<point_count;i++)
    120     {
    121         /*Compute reprojection error vector and its Jacobian
    122         for this point*/
    123         db_DerivativeCauchyInhomHomographyReprojection(Jf_dx,f,xp_i+(i<<1),H,x_i+(i<<1),one_over_scale2);
    124         /*Perform
    125         min_Jtf-=Jf_dx*f[0] and
    126         min_Jtf-=(Jf_dx+9)*f[1] to accumulate -Jt%f*/
    127         db_RowOperation9(min_Jtf,Jf_dx,f[0]);
    128         db_RowOperation9(min_Jtf,Jf_dx+9,f[1]);
    129         /*Accumulate upper right of JtJ with outer product*/
    130         temp=Jf_dx[0]; temp2=Jf_dx[9];
    131         JtJ[0]+=temp*Jf_dx[0]+temp2*Jf_dx[9];
    132         JtJ[1]+=temp*Jf_dx[1]+temp2*Jf_dx[10];
    133         JtJ[2]+=temp*Jf_dx[2]+temp2*Jf_dx[11];
    134         JtJ[3]+=temp*Jf_dx[3]+temp2*Jf_dx[12];
    135         JtJ[4]+=temp*Jf_dx[4]+temp2*Jf_dx[13];
    136         JtJ[5]+=temp*Jf_dx[5]+temp2*Jf_dx[14];
    137         JtJ[6]+=temp*Jf_dx[6]+temp2*Jf_dx[15];
    138         JtJ[7]+=temp*Jf_dx[7]+temp2*Jf_dx[16];
    139         JtJ[8]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    140         temp=Jf_dx[1]; temp2=Jf_dx[10];
    141         JtJ[10]+=temp*Jf_dx[1]+temp2*Jf_dx[10];
    142         JtJ[11]+=temp*Jf_dx[2]+temp2*Jf_dx[11];
    143         JtJ[12]+=temp*Jf_dx[3]+temp2*Jf_dx[12];
    144         JtJ[13]+=temp*Jf_dx[4]+temp2*Jf_dx[13];
    145         JtJ[14]+=temp*Jf_dx[5]+temp2*Jf_dx[14];
    146         JtJ[15]+=temp*Jf_dx[6]+temp2*Jf_dx[15];
    147         JtJ[16]+=temp*Jf_dx[7]+temp2*Jf_dx[16];
    148         JtJ[17]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    149         temp=Jf_dx[2]; temp2=Jf_dx[11];
    150         JtJ[20]+=temp*Jf_dx[2]+temp2*Jf_dx[11];
    151         JtJ[21]+=temp*Jf_dx[3]+temp2*Jf_dx[12];
    152         JtJ[22]+=temp*Jf_dx[4]+temp2*Jf_dx[13];
    153         JtJ[23]+=temp*Jf_dx[5]+temp2*Jf_dx[14];
    154         JtJ[24]+=temp*Jf_dx[6]+temp2*Jf_dx[15];
    155         JtJ[25]+=temp*Jf_dx[7]+temp2*Jf_dx[16];
    156         JtJ[26]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    157         temp=Jf_dx[3]; temp2=Jf_dx[12];
    158         JtJ[30]+=temp*Jf_dx[3]+temp2*Jf_dx[12];
    159         JtJ[31]+=temp*Jf_dx[4]+temp2*Jf_dx[13];
    160         JtJ[32]+=temp*Jf_dx[5]+temp2*Jf_dx[14];
    161         JtJ[33]+=temp*Jf_dx[6]+temp2*Jf_dx[15];
    162         JtJ[34]+=temp*Jf_dx[7]+temp2*Jf_dx[16];
    163         JtJ[35]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    164         temp=Jf_dx[4]; temp2=Jf_dx[13];
    165         JtJ[40]+=temp*Jf_dx[4]+temp2*Jf_dx[13];
    166         JtJ[41]+=temp*Jf_dx[5]+temp2*Jf_dx[14];
    167         JtJ[42]+=temp*Jf_dx[6]+temp2*Jf_dx[15];
    168         JtJ[43]+=temp*Jf_dx[7]+temp2*Jf_dx[16];
    169         JtJ[44]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    170         temp=Jf_dx[5]; temp2=Jf_dx[14];
    171         JtJ[50]+=temp*Jf_dx[5]+temp2*Jf_dx[14];
    172         JtJ[51]+=temp*Jf_dx[6]+temp2*Jf_dx[15];
    173         JtJ[52]+=temp*Jf_dx[7]+temp2*Jf_dx[16];
    174         JtJ[53]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    175         temp=Jf_dx[6]; temp2=Jf_dx[15];
    176         JtJ[60]+=temp*Jf_dx[6]+temp2*Jf_dx[15];
    177         JtJ[61]+=temp*Jf_dx[7]+temp2*Jf_dx[16];
    178         JtJ[62]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    179         temp=Jf_dx[7]; temp2=Jf_dx[16];
    180         JtJ[70]+=temp*Jf_dx[7]+temp2*Jf_dx[16];
    181         JtJ[71]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    182         temp=Jf_dx[8]; temp2=Jf_dx[17];
    183         JtJ[80]+=temp*Jf_dx[8]+temp2*Jf_dx[17];
    184 
    185         /*Add square-sum to cost*/
    186         back+=db_sqr(f[0])+db_sqr(f[1]);
    187     }
    188 
    189     return(back);
    190 }
    191 
    192 /*Compute min_Jtf and upper right of JtJ. Return cost*/
    193 inline double db_RobCamRotation_Jacobians(double JtJ[9],double min_Jtf[3],double H[9],int point_count,double *x_i,double *xp_i,double one_over_scale2)
    194 {
    195     double back,Jf_dx[6],f[2];
    196     int i,j;
    197 
    198     db_Zero(JtJ,9);
    199     db_Zero(min_Jtf,3);
    200     for(back=0.0,i=0;i<point_count;i++)
    201     {
    202         /*Compute reprojection error vector and its Jacobian
    203         for this point*/
    204         j=(i<<1);
    205         db_DerivativeCauchyInhomRotationReprojection(Jf_dx,f,xp_i+j,H,x_i+j,one_over_scale2);
    206         /*Perform
    207         min_Jtf-=Jf_dx*f[0] and
    208         min_Jtf-=(Jf_dx+3)*f[1] to accumulate -Jt%f*/
    209         db_RowOperation3(min_Jtf,Jf_dx,f[0]);
    210         db_RowOperation3(min_Jtf,Jf_dx+3,f[1]);
    211         /*Accumulate upper right of JtJ with outer product*/
    212         JtJ[0]+=Jf_dx[0]*Jf_dx[0]+Jf_dx[3]*Jf_dx[3];
    213         JtJ[1]+=Jf_dx[0]*Jf_dx[1]+Jf_dx[3]*Jf_dx[4];
    214         JtJ[2]+=Jf_dx[0]*Jf_dx[2]+Jf_dx[3]*Jf_dx[5];
    215         JtJ[4]+=Jf_dx[1]*Jf_dx[1]+Jf_dx[4]*Jf_dx[4];
    216         JtJ[5]+=Jf_dx[1]*Jf_dx[2]+Jf_dx[4]*Jf_dx[5];
    217         JtJ[8]+=Jf_dx[2]*Jf_dx[2]+Jf_dx[5]*Jf_dx[5];
    218 
    219         /*Add square-sum to cost*/
    220         back+=db_sqr(f[0])+db_sqr(f[1]);
    221     }
    222 
    223     return(back);
    224 }
    225 
    226 void db_RobCamRotation_Polish(double H[9],int point_count,double *x_i,double *xp_i,double one_over_scale2,
    227                                int max_iterations,double improvement_requirement)
    228 {
    229     int i,update,stop;
    230     double lambda,cost,current_cost;
    231     double JtJ[9],min_Jtf[3],dx[3],H_p_dx[9];
    232 
    233     lambda=0.001;
    234     for(update=1,stop=0,i=0;(stop<2) && (i<max_iterations);i++)
    235     {
    236         /*if first time since improvement, compute Jacobian and residual*/
    237         if(update)
    238         {
    239             current_cost=db_RobCamRotation_Jacobians(JtJ,min_Jtf,H,point_count,x_i,xp_i,one_over_scale2);
    240             update=0;
    241         }
    242 
    243 #ifdef _VERBOSE_
    244         /*std::cout << "Cost:" << current_cost << " ";*/
    245 #endif /*_VERBOSE_*/
    246 
    247         /*Come up with a hypothesis dx
    248         based on the current lambda*/
    249         db_Compute_dx_3x3(dx,JtJ,min_Jtf,lambda);
    250 
    251         /*Compute Cost(x+dx)*/
    252         db_UpdateRotation(H_p_dx,H,dx);
    253         cost=db_RobImageHomography_Cost(H_p_dx,point_count,x_i,xp_i,one_over_scale2);
    254 
    255         /*Is there an improvement?*/
    256         if(cost<current_cost)
    257         {
    258             /*improvement*/
    259             if(current_cost-cost<current_cost*improvement_requirement) stop++;
    260             else stop=0;
    261             lambda*=0.1;
    262             /*Move to the hypothesised position x+dx*/
    263             current_cost=cost;
    264             db_Copy9(H,H_p_dx);
    265             db_OrthonormalizeRotation(H);
    266             update=1;
    267 
    268 #ifdef _VERBOSE_
    269         std::cout << "Step" << i << "Imp,Lambda=" << lambda << "Cost:" << current_cost << std::endl;
    270 #endif /*_VERBOSE_*/
    271         }
    272         else
    273         {
    274             /*no improvement*/
    275             lambda*=10.0;
    276             stop=0;
    277         }
    278     }
    279 }
    280 
    281 inline void db_RobImageHomographyFetchJacobian(double **JtJ_ref,double *min_Jtf,double **JtJ_temp_ref,double *min_Jtf_temp,int n,int *fetch_vector)
    282 {
    283     int i,j,t;
    284     double *t1,*t2;
    285 
    286     for(i=0;i<n;i++)
    287     {
    288         t=fetch_vector[i];
    289         min_Jtf[i]=min_Jtf_temp[t];
    290         t1=JtJ_ref[i];
    291         t2=JtJ_temp_ref[t];
    292         for(j=i;j<n;j++)
    293         {
    294             t1[j]=t2[fetch_vector[j]];
    295         }
    296     }
    297 }
    298 
    299 inline void db_RobImageHomographyMultiplyJacobian(double **JtJ_ref,double *min_Jtf,double **JtJ_temp_ref,double *min_Jtf_temp,double **JE_dx_ref,int n)
    300 {
    301     double JtJ_JE[72],*JtJ_JE_ref[9];
    302 
    303     db_SetupMatrixRefs(JtJ_JE_ref,9,8,JtJ_JE);
    304 
    305     db_SymmetricExtendUpperToLower(JtJ_temp_ref,9,9);
    306     db_MultiplyMatricesAB(JtJ_JE_ref,JtJ_temp_ref,JE_dx_ref,9,9,n);
    307     db_UpperMultiplyMatricesAtB(JtJ_ref,JE_dx_ref,JtJ_JE_ref,n,9,n);
    308     db_MultiplyMatrixVectorAtb(min_Jtf,JE_dx_ref,min_Jtf_temp,n,9);
    309 }
    310 
    311 inline void db_RobImageHomographyJH_Js(double **JE_dx_ref,int j,double H[9])
    312 {
    313     /*Update of upper 2x2 is multiplication by
    314     [s 0][ cos(theta) sin(theta)]
    315     [0 s][-sin(theta) cos(theta)]*/
    316     JE_dx_ref[0][j]=H[0];
    317     JE_dx_ref[1][j]=H[1];
    318     JE_dx_ref[2][j]=0;
    319     JE_dx_ref[3][j]=H[2];
    320     JE_dx_ref[4][j]=H[3];
    321     JE_dx_ref[5][j]=0;
    322     JE_dx_ref[6][j]=0;
    323     JE_dx_ref[7][j]=0;
    324     JE_dx_ref[8][j]=0;
    325 }
    326 
    327 inline void db_RobImageHomographyJH_JR(double **JE_dx_ref,int j,double H[9])
    328 {
    329     /*Update of upper 2x2 is multiplication by
    330     [s 0][ cos(theta) sin(theta)]
    331     [0 s][-sin(theta) cos(theta)]*/
    332     JE_dx_ref[0][j]=  H[3];
    333     JE_dx_ref[1][j]=  H[4];
    334     JE_dx_ref[2][j]=0;
    335     JE_dx_ref[3][j]= -H[0];
    336     JE_dx_ref[4][j]= -H[1];
    337     JE_dx_ref[5][j]=0;
    338     JE_dx_ref[6][j]=0;
    339     JE_dx_ref[7][j]=0;
    340     JE_dx_ref[8][j]=0;
    341 }
    342 
    343 inline void db_RobImageHomographyJH_Jt(double **JE_dx_ref,int j,int k,double H[9])
    344 {
    345     JE_dx_ref[0][j]=0;
    346     JE_dx_ref[1][j]=0;
    347     JE_dx_ref[2][j]=1.0;
    348     JE_dx_ref[3][j]=0;
    349     JE_dx_ref[4][j]=0;
    350     JE_dx_ref[5][j]=0;
    351     JE_dx_ref[6][j]=0;
    352     JE_dx_ref[7][j]=0;
    353     JE_dx_ref[8][j]=0;
    354 
    355     JE_dx_ref[0][k]=0;
    356     JE_dx_ref[1][k]=0;
    357     JE_dx_ref[2][k]=0;
    358     JE_dx_ref[3][k]=0;
    359     JE_dx_ref[4][k]=0;
    360     JE_dx_ref[5][k]=1.0;
    361     JE_dx_ref[6][k]=0;
    362     JE_dx_ref[7][k]=0;
    363     JE_dx_ref[8][k]=0;
    364 }
    365 
    366 inline void db_RobImageHomographyJH_dRotFocal(double **JE_dx_ref,int j,int k,int l,int m,double H[9])
    367 {
    368     double f,fi,fi2;
    369     double R[9],J[9];
    370 
    371     /*Updated matrix is diag(f+df,f+df)*dR*R*diag(1/(f+df),1/(f+df),1)*/
    372     f=db_FocalAndRotFromCamRotFocalHomography(R,H);
    373     fi=db_SafeReciprocal(f);
    374     fi2=db_sqr(fi);
    375     db_JacobianOfRotatedPointStride(J,R,3);
    376     JE_dx_ref[0][j]=   J[0];
    377     JE_dx_ref[1][j]=   J[1];
    378     JE_dx_ref[2][j]=f* J[2];
    379     JE_dx_ref[3][j]=   J[3];
    380     JE_dx_ref[4][j]=   J[4];
    381     JE_dx_ref[5][j]=f* J[5];
    382     JE_dx_ref[6][j]=fi*J[6];
    383     JE_dx_ref[7][j]=fi*J[7];
    384     JE_dx_ref[8][j]=   J[8];
    385     db_JacobianOfRotatedPointStride(J,R+1,3);
    386     JE_dx_ref[0][k]=   J[0];
    387     JE_dx_ref[1][k]=   J[1];
    388     JE_dx_ref[2][k]=f* J[2];
    389     JE_dx_ref[3][k]=   J[3];
    390     JE_dx_ref[4][k]=   J[4];
    391     JE_dx_ref[5][k]=f* J[5];
    392     JE_dx_ref[6][k]=fi*J[6];
    393     JE_dx_ref[7][k]=fi*J[7];
    394     JE_dx_ref[8][k]=   J[8];
    395     db_JacobianOfRotatedPointStride(J,R+2,3);
    396     JE_dx_ref[0][l]=   J[0];
    397     JE_dx_ref[1][l]=   J[1];
    398     JE_dx_ref[2][l]=f* J[2];
    399     JE_dx_ref[3][l]=   J[3];
    400     JE_dx_ref[4][l]=   J[4];
    401     JE_dx_ref[5][l]=f* J[5];
    402     JE_dx_ref[6][l]=fi*J[6];
    403     JE_dx_ref[7][l]=fi*J[7];
    404     JE_dx_ref[8][l]=   J[8];
    405 
    406     JE_dx_ref[0][m]=0;
    407     JE_dx_ref[1][m]=0;
    408     JE_dx_ref[2][m]=H[2];
    409     JE_dx_ref[3][m]=0;
    410     JE_dx_ref[4][m]=0;
    411     JE_dx_ref[5][m]=H[5];
    412     JE_dx_ref[6][m]= -fi2*H[6];
    413     JE_dx_ref[7][m]= -fi2*H[7];
    414     JE_dx_ref[8][m]=0;
    415 }
    416 
    417 inline double db_RobImageHomography_Jacobians_Generic(double *JtJ_ref[8],double min_Jtf[8],int *num_param,int *frozen_coord,double H[9],int point_count,double *x_i,double *xp_i,int homography_type,double one_over_scale2)
    418 {
    419     double back;
    420     int i,j,fetch_vector[8],n;
    421     double JtJ_temp[81],min_Jtf_temp[9],JE_dx[72];
    422     double *JE_dx_ref[9],*JtJ_temp_ref[9];
    423 
    424     /*Compute cost and JtJ,min_Jtf with respect to H*/
    425     back=db_RobImageHomography_Jacobians(JtJ_temp,min_Jtf_temp,H,point_count,x_i,xp_i,one_over_scale2);
    426 
    427     /*Compute JtJ,min_Jtf with respect to the right parameters
    428     The formulas are
    429     JtJ=transpose(JE_dx)*JtJ*JE_dx and
    430     min_Jtf=transpose(JE_dx)*min_Jtf,
    431     where the 9xN matrix JE_dx is the Jacobian of H with respect
    432     to the update*/
    433     db_SetupMatrixRefs(JtJ_temp_ref,9,9,JtJ_temp);
    434     db_SetupMatrixRefs(JE_dx_ref,9,8,JE_dx);
    435     switch(homography_type)
    436     {
    437         case DB_HOMOGRAPHY_TYPE_SIMILARITY:
    438         case DB_HOMOGRAPHY_TYPE_SIMILARITY_U:
    439             n=4;
    440             db_RobImageHomographyJH_Js(JE_dx_ref,0,H);
    441             db_RobImageHomographyJH_JR(JE_dx_ref,1,H);
    442             db_RobImageHomographyJH_Jt(JE_dx_ref,2,3,H);
    443             db_RobImageHomographyMultiplyJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,JE_dx_ref,n);
    444             break;
    445         case DB_HOMOGRAPHY_TYPE_ROTATION:
    446         case DB_HOMOGRAPHY_TYPE_ROTATION_U:
    447             n=1;
    448             db_RobImageHomographyJH_JR(JE_dx_ref,0,H);
    449             db_RobImageHomographyMultiplyJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,JE_dx_ref,n);
    450             break;
    451         case DB_HOMOGRAPHY_TYPE_SCALING:
    452             n=1;
    453             db_RobImageHomographyJH_Js(JE_dx_ref,0,H);
    454             db_RobImageHomographyMultiplyJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,JE_dx_ref,n);
    455             break;
    456         case DB_HOMOGRAPHY_TYPE_S_T:
    457             n=3;
    458             db_RobImageHomographyJH_Js(JE_dx_ref,0,H);
    459             db_RobImageHomographyJH_Jt(JE_dx_ref,1,2,H);
    460             db_RobImageHomographyMultiplyJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,JE_dx_ref,n);
    461             break;
    462         case DB_HOMOGRAPHY_TYPE_R_T:
    463             n=3;
    464             db_RobImageHomographyJH_JR(JE_dx_ref,0,H);
    465             db_RobImageHomographyJH_Jt(JE_dx_ref,1,2,H);
    466             db_RobImageHomographyMultiplyJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,JE_dx_ref,n);
    467             break;
    468         case DB_HOMOGRAPHY_TYPE_R_S:
    469             n=2;
    470             db_RobImageHomographyJH_Js(JE_dx_ref,0,H);
    471             db_RobImageHomographyJH_JR(JE_dx_ref,1,H);
    472             db_RobImageHomographyMultiplyJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,JE_dx_ref,n);
    473             break;
    474 
    475         case DB_HOMOGRAPHY_TYPE_TRANSLATION:
    476             n=2;
    477             fetch_vector[0]=2;
    478             fetch_vector[1]=5;
    479             db_RobImageHomographyFetchJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,n,fetch_vector);
    480             break;
    481         case DB_HOMOGRAPHY_TYPE_AFFINE:
    482             n=6;
    483             fetch_vector[0]=0;
    484             fetch_vector[1]=1;
    485             fetch_vector[2]=2;
    486             fetch_vector[3]=3;
    487             fetch_vector[4]=4;
    488             fetch_vector[5]=5;
    489             db_RobImageHomographyFetchJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,n,fetch_vector);
    490             break;
    491         case DB_HOMOGRAPHY_TYPE_PROJECTIVE:
    492             n=8;
    493             *frozen_coord=db_MaxAbsIndex9(H);
    494             for(j=0,i=0;i<9;i++) if(i!=(*frozen_coord))
    495             {
    496                 fetch_vector[j]=i;
    497                 j++;
    498             }
    499             db_RobImageHomographyFetchJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,n,fetch_vector);
    500             break;
    501         case DB_HOMOGRAPHY_TYPE_CAMROTATION_F:
    502         case DB_HOMOGRAPHY_TYPE_CAMROTATION_F_UD:
    503             n=4;
    504             db_RobImageHomographyJH_dRotFocal(JE_dx_ref,0,1,2,3,H);
    505             db_RobImageHomographyMultiplyJacobian(JtJ_ref,min_Jtf,JtJ_temp_ref,min_Jtf_temp,JE_dx_ref,n);
    506             break;
    507     }
    508     *num_param=n;
    509 
    510     return(back);
    511 }
    512 
    513 inline void db_ImageHomographyUpdateGeneric(double H_p_dx[9],double H[9],double *dx,int homography_type,int frozen_coord)
    514 {
    515     switch(homography_type)
    516     {
    517         case DB_HOMOGRAPHY_TYPE_SIMILARITY:
    518         case DB_HOMOGRAPHY_TYPE_SIMILARITY_U:
    519             db_Copy9(H_p_dx,H);
    520             db_MultiplyScaleOntoImageHomography(H,1.0+dx[0]);
    521             db_MultiplyRotationOntoImageHomography(H,dx[1]);
    522             H_p_dx[2]+=dx[2];
    523             H_p_dx[5]+=dx[3];
    524             break;
    525         case DB_HOMOGRAPHY_TYPE_ROTATION:
    526         case DB_HOMOGRAPHY_TYPE_ROTATION_U:
    527             db_MultiplyRotationOntoImageHomography(H,dx[0]);
    528             break;
    529         case DB_HOMOGRAPHY_TYPE_SCALING:
    530             db_MultiplyScaleOntoImageHomography(H,1.0+dx[0]);
    531             break;
    532         case DB_HOMOGRAPHY_TYPE_S_T:
    533             db_Copy9(H_p_dx,H);
    534             db_MultiplyScaleOntoImageHomography(H,1.0+dx[0]);
    535             H_p_dx[2]+=dx[1];
    536             H_p_dx[5]+=dx[2];
    537             break;
    538         case DB_HOMOGRAPHY_TYPE_R_T:
    539             db_Copy9(H_p_dx,H);
    540             db_MultiplyRotationOntoImageHomography(H,dx[0]);
    541             H_p_dx[2]+=dx[1];
    542             H_p_dx[5]+=dx[2];
    543             break;
    544         case DB_HOMOGRAPHY_TYPE_R_S:
    545             db_Copy9(H_p_dx,H);
    546             db_MultiplyScaleOntoImageHomography(H,1.0+dx[0]);
    547             db_MultiplyRotationOntoImageHomography(H,dx[1]);
    548             break;
    549         case DB_HOMOGRAPHY_TYPE_TRANSLATION:
    550             db_Copy9(H_p_dx,H);
    551             H_p_dx[2]+=dx[0];
    552             H_p_dx[5]+=dx[1];
    553             break;
    554         case DB_HOMOGRAPHY_TYPE_AFFINE:
    555             db_UpdateImageHomographyAffine(H_p_dx,H,dx);
    556             break;
    557         case DB_HOMOGRAPHY_TYPE_PROJECTIVE:
    558             db_UpdateImageHomographyProjective(H_p_dx,H,dx,frozen_coord);
    559             break;
    560         case DB_HOMOGRAPHY_TYPE_CAMROTATION_F:
    561         case DB_HOMOGRAPHY_TYPE_CAMROTATION_F_UD:
    562             db_UpdateRotFocalHomography(H_p_dx,H,dx);
    563             break;
    564     }
    565 }
    566 
    567 void db_RobCamRotation_Polish_Generic(double H[9],int point_count,int homography_type,double *x_i,double *xp_i,double one_over_scale2,
    568                                int max_iterations,double improvement_requirement)
    569 {
    570     int i,update,stop,n;
    571     int frozen_coord = 0;
    572     double lambda,cost,current_cost;
    573     double JtJ[72],min_Jtf[9],dx[8],H_p_dx[9];
    574     double *JtJ_ref[9],d[8];
    575 
    576     lambda=0.001;
    577     for(update=1,stop=0,i=0;(stop<2) && (i<max_iterations);i++)
    578     {
    579         /*if first time since improvement, compute Jacobian and residual*/
    580         if(update)
    581         {
    582             db_SetupMatrixRefs(JtJ_ref,9,8,JtJ);
    583             current_cost=db_RobImageHomography_Jacobians_Generic(JtJ_ref,min_Jtf,&n,&frozen_coord,H,point_count,x_i,xp_i,homography_type,one_over_scale2);
    584             update=0;
    585         }
    586 
    587 #ifdef _VERBOSE_
    588         /*std::cout << "Cost:" << current_cost << " ";*/
    589 #endif /*_VERBOSE_*/
    590 
    591         /*Come up with a hypothesis dx
    592         based on the current lambda*/
    593         db_Compute_dx(dx,JtJ_ref,min_Jtf,lambda,d,n);
    594 
    595         /*Compute Cost(x+dx)*/
    596         db_ImageHomographyUpdateGeneric(H_p_dx,H,dx,homography_type,frozen_coord);
    597         cost=db_RobImageHomography_Cost(H_p_dx,point_count,x_i,xp_i,one_over_scale2);
    598 
    599         /*Is there an improvement?*/
    600         if(cost<current_cost)
    601         {
    602             /*improvement*/
    603             if(current_cost-cost<current_cost*improvement_requirement) stop++;
    604             else stop=0;
    605             lambda*=0.1;
    606             /*Move to the hypothesised position x+dx*/
    607             current_cost=cost;
    608             db_Copy9(H,H_p_dx);
    609             update=1;
    610 
    611 #ifdef _VERBOSE_
    612         std::cout << "Step" << i << "Imp,Lambda=" << lambda << "Cost:" << current_cost << std::endl;
    613 #endif /*_VERBOSE_*/
    614         }
    615         else
    616         {
    617             /*no improvement*/
    618             lambda*=10.0;
    619             stop=0;
    620         }
    621     }
    622 }
    623 void db_RobImageHomography(
    624                               /*Best homography*/
    625                               double H[9],
    626                               /*2DPoint to 2DPoint constraints
    627                               Points are assumed to be given in
    628                               homogenous coordinates*/
    629                               double *im, double *im_p,
    630                               /*Nr of points in total*/
    631                               int nr_points,
    632                               /*Calibration matrices
    633                               used to normalize the points*/
    634                               double K[9],
    635                               double Kp[9],
    636                               /*Pre-allocated space temp_d
    637                               should point to at least
    638                               12*nr_samples+10*nr_points
    639                               allocated positions*/
    640                               double *temp_d,
    641                               /*Pre-allocated space temp_i
    642                               should point to at least
    643                               max(nr_samples,nr_points)
    644                               allocated positions*/
    645                               int *temp_i,
    646                               int homography_type,
    647                               db_Statistics *stat,
    648                               int max_iterations,
    649                               int max_points,
    650                               double scale,
    651                               int nr_samples,
    652                               int chunk_size,
    653                               /////////////////////////////////////////////
    654                               // regular use: set outlierremoveflagE =0;
    655                               // flag for the outlier removal
    656                               int outlierremoveflagE,
    657                               // if flag is 1, then the following variables
    658                               // need the input
    659                               //////////////////////////////////////
    660                               // 3D coordinates
    661                               double *wp,
    662                               // its corresponding stereo pair's points
    663                               double *im_r,
    664                               // raw image coordinates
    665                               double *im_raw, double *im_raw_p,
    666                               // final matches
    667                               int *finalNumE)
    668 {
    669     /*Random seed*/
    670     int r_seed;
    671 
    672     int point_count_new;
    673     /*Counters*/
    674     int i,j,c,point_count,hyp_count;
    675     int last_hyp,new_last_hyp,last_corr;
    676     int pos,point_pos,last_point;
    677     /*Accumulator*/
    678     double acc;
    679     /*Hypothesis pointer*/
    680     double *hyp_point;
    681     /*Random sample*/
    682     int s[4];
    683     /*Pivot for hypothesis pruning*/
    684     double pivot;
    685     /*Best hypothesis position*/
    686     int best_pos;
    687     /*Best score*/
    688     double lowest_cost;
    689     /*One over the squared scale of
    690     Cauchy distribution*/
    691     double one_over_scale2;
    692     /*temporary pointers*/
    693     double *x_i_temp,*xp_i_temp;
    694     /*Temporary space for inverse calibration matrices*/
    695     double K_inv[9];
    696     double Kp_inv[9];
    697     /*Temporary space for homography*/
    698     double H_temp[9],H_temp2[9];
    699     /*Pointers to homogenous coordinates*/
    700     double *x_h_point,*xp_h_point;
    701     /*Array of pointers to inhomogenous coordinates*/
    702     double *X[3],*Xp[3];
    703     /*Similarity parameters*/
    704     int orientation_preserving,allow_scaling,allow_rotation,allow_translation,sample_size;
    705 
    706     /*Homogenous coordinates of image points in first image*/
    707     double *x_h;
    708     /*Homogenous coordinates of image points in second image*/
    709     double *xp_h;
    710     /*Inhomogenous coordinates of image points in first image*/
    711     double *x_i;
    712     /*Inhomogenous coordinates of image points in second image*/
    713     double *xp_i;
    714     /*Homography hypotheses*/
    715     double *hyp_H_array;
    716     /*Cost array*/
    717     double *hyp_cost_array;
    718     /*Permutation of the hypotheses*/
    719     int *hyp_perm;
    720     /*Sample of the points*/
    721     int *point_perm;
    722     /*Temporary space for quick-select
    723     2*nr_samples*/
    724     double *temp_select;
    725 
    726     /*Get inverse calibration matrices*/
    727     db_InvertCalibrationMatrix(K_inv,K);
    728     db_InvertCalibrationMatrix(Kp_inv,Kp);
    729     /*Compute scale coefficient*/
    730     one_over_scale2=1.0/(scale*scale);
    731     /*Initialize random seed*/
    732     r_seed=12345;
    733     /*Set pointers to pre-allocated space*/
    734     hyp_cost_array=temp_d;
    735     hyp_H_array=temp_d+nr_samples;
    736     temp_select=temp_d+10*nr_samples;
    737     x_h=temp_d+12*nr_samples;
    738     xp_h=temp_d+12*nr_samples+3*nr_points;
    739     x_i=temp_d+12*nr_samples+6*nr_points;
    740     xp_i=temp_d+12*nr_samples+8*nr_points;
    741     hyp_perm=temp_i;
    742     point_perm=temp_i;
    743 
    744     /*Prepare a randomly permuted subset of size
    745     point_count from the input points*/
    746 
    747     point_count=db_mini(nr_points,(int)(chunk_size*log((double)nr_samples)/DB_LN2));
    748 
    749     point_count_new = point_count;
    750 
    751     for(i=0;i<nr_points;i++) point_perm[i]=i;
    752 
    753     for(last_point=nr_points-1,i=0;i<point_count;i++,last_point--)
    754     {
    755         pos=db_RandomInt(r_seed,last_point);
    756         point_pos=point_perm[pos];
    757         point_perm[pos]=point_perm[last_point];
    758 
    759         /*Normalize image points with calibration
    760         matrices and move them to x_h and xp_h*/
    761         c=3*point_pos;
    762         j=3*i;
    763         x_h_point=x_h+j;
    764         xp_h_point=xp_h+j;
    765         db_Multiply3x3_3x1(x_h_point,K_inv,im+c);
    766         db_Multiply3x3_3x1(xp_h_point,Kp_inv,im_p+c);
    767 
    768         db_HomogenousNormalize3(x_h_point);
    769         db_HomogenousNormalize3(xp_h_point);
    770 
    771         /*Dehomogenize image points and move them
    772         to x_i and xp_i*/
    773         c=(i<<1);
    774         db_DeHomogenizeImagePoint(x_i+c,x_h_point); // 2-dimension
    775         db_DeHomogenizeImagePoint(xp_i+c,xp_h_point); //2-dimension
    776     }
    777 
    778 
    779     /*Generate Hypotheses*/
    780     hyp_count=0;
    781     switch(homography_type)
    782     {
    783     case DB_HOMOGRAPHY_TYPE_SIMILARITY:
    784     case DB_HOMOGRAPHY_TYPE_SIMILARITY_U:
    785     case DB_HOMOGRAPHY_TYPE_TRANSLATION:
    786     case DB_HOMOGRAPHY_TYPE_ROTATION:
    787     case DB_HOMOGRAPHY_TYPE_ROTATION_U:
    788     case DB_HOMOGRAPHY_TYPE_SCALING:
    789     case DB_HOMOGRAPHY_TYPE_S_T:
    790     case DB_HOMOGRAPHY_TYPE_R_T:
    791     case DB_HOMOGRAPHY_TYPE_R_S:
    792 
    793         switch(homography_type)
    794         {
    795         case DB_HOMOGRAPHY_TYPE_SIMILARITY:
    796             orientation_preserving=1;
    797             allow_scaling=1;
    798             allow_rotation=1;
    799             allow_translation=1;
    800             sample_size=2;
    801             break;
    802         case DB_HOMOGRAPHY_TYPE_SIMILARITY_U:
    803             orientation_preserving=0;
    804             allow_scaling=1;
    805             allow_rotation=1;
    806             allow_translation=1;
    807             sample_size=3;
    808             break;
    809         case DB_HOMOGRAPHY_TYPE_TRANSLATION:
    810             orientation_preserving=1;
    811             allow_scaling=0;
    812             allow_rotation=0;
    813             allow_translation=1;
    814             sample_size=1;
    815             break;
    816         case DB_HOMOGRAPHY_TYPE_ROTATION:
    817             orientation_preserving=1;
    818             allow_scaling=0;
    819             allow_rotation=1;
    820             allow_translation=0;
    821             sample_size=1;
    822             break;
    823         case DB_HOMOGRAPHY_TYPE_ROTATION_U:
    824             orientation_preserving=0;
    825             allow_scaling=0;
    826             allow_rotation=1;
    827             allow_translation=0;
    828             sample_size=2;
    829             break;
    830         case DB_HOMOGRAPHY_TYPE_SCALING:
    831             orientation_preserving=1;
    832             allow_scaling=1;
    833             allow_rotation=0;
    834             allow_translation=0;
    835             sample_size=1;
    836             break;
    837         case DB_HOMOGRAPHY_TYPE_S_T:
    838             orientation_preserving=1;
    839             allow_scaling=1;
    840             allow_rotation=0;
    841             allow_translation=1;
    842             sample_size=2;
    843             break;
    844         case DB_HOMOGRAPHY_TYPE_R_T:
    845             orientation_preserving=1;
    846             allow_scaling=0;
    847             allow_rotation=1;
    848             allow_translation=1;
    849             sample_size=2;
    850             break;
    851         case DB_HOMOGRAPHY_TYPE_R_S:
    852             orientation_preserving=1;
    853             allow_scaling=1;
    854             allow_rotation=0;
    855             allow_translation=0;
    856             sample_size=1;
    857             break;
    858         }
    859 
    860         if(point_count>=sample_size) for(i=0;i<nr_samples;i++)
    861         {
    862             db_RandomSample(s,3,point_count,r_seed);
    863             X[0]= &x_i[s[0]<<1];
    864             X[1]= &x_i[s[1]<<1];
    865             X[2]= &x_i[s[2]<<1];
    866             Xp[0]= &xp_i[s[0]<<1];
    867             Xp[1]= &xp_i[s[1]<<1];
    868             Xp[2]= &xp_i[s[2]<<1];
    869             db_StitchSimilarity2D(&hyp_H_array[9*hyp_count],Xp,X,sample_size,orientation_preserving,
    870                                   allow_scaling,allow_rotation,allow_translation);
    871             hyp_count++;
    872         }
    873         break;
    874 
    875     case DB_HOMOGRAPHY_TYPE_CAMROTATION:
    876         if(point_count>=2) for(i=0;i<nr_samples;i++)
    877         {
    878             db_RandomSample(s,2,point_count,r_seed);
    879             db_StitchCameraRotation_2Points(&hyp_H_array[9*hyp_count],
    880                                       &x_h[3*s[0]],&x_h[3*s[1]],
    881                                       &xp_h[3*s[0]],&xp_h[3*s[1]]);
    882             hyp_count++;
    883         }
    884         break;
    885 
    886     case DB_HOMOGRAPHY_TYPE_CAMROTATION_F:
    887         if(point_count>=3) for(i=0;i<nr_samples;i++)
    888         {
    889             db_RandomSample(s,3,point_count,r_seed);
    890             hyp_count+=db_StitchRotationCommonFocalLength_3Points(&hyp_H_array[9*hyp_count],
    891                                       &x_h[3*s[0]],&x_h[3*s[1]],&x_h[3*s[2]],
    892                                       &xp_h[3*s[0]],&xp_h[3*s[1]],&xp_h[3*s[2]]);
    893         }
    894         break;
    895 
    896     case DB_HOMOGRAPHY_TYPE_CAMROTATION_F_UD:
    897         if(point_count>=3) for(i=0;i<nr_samples;i++)
    898         {
    899             db_RandomSample(s,3,point_count,r_seed);
    900             hyp_count+=db_StitchRotationCommonFocalLength_3Points(&hyp_H_array[9*hyp_count],
    901                                       &x_h[3*s[0]],&x_h[3*s[1]],&x_h[3*s[2]],
    902                                       &xp_h[3*s[0]],&xp_h[3*s[1]],&xp_h[3*s[2]],NULL,0);
    903         }
    904         break;
    905 
    906     case DB_HOMOGRAPHY_TYPE_AFFINE:
    907         if(point_count>=3) for(i=0;i<nr_samples;i++)
    908         {
    909             db_RandomSample(s,3,point_count,r_seed);
    910             db_StitchAffine2D_3Points(&hyp_H_array[9*hyp_count],
    911                                       &x_h[3*s[0]],&x_h[3*s[1]],&x_h[3*s[2]],
    912                                       &xp_h[3*s[0]],&xp_h[3*s[1]],&xp_h[3*s[2]]);
    913             hyp_count++;
    914         }
    915         break;
    916 
    917     case DB_HOMOGRAPHY_TYPE_PROJECTIVE:
    918     default:
    919         if(point_count>=4) for(i=0;i<nr_samples;i++)
    920         {
    921             db_RandomSample(s,4,point_count,r_seed);
    922             db_StitchProjective2D_4Points(&hyp_H_array[9*hyp_count],
    923                                       &x_h[3*s[0]],&x_h[3*s[1]],&x_h[3*s[2]],&x_h[3*s[3]],
    924                                       &xp_h[3*s[0]],&xp_h[3*s[1]],&xp_h[3*s[2]],&xp_h[3*s[3]]);
    925             hyp_count++;
    926         }
    927     }
    928 
    929     if(hyp_count)
    930     {
    931         /*Count cost in chunks and decimate hypotheses
    932         until only one remains or the correspondences are
    933         exhausted*/
    934         for(i=0;i<hyp_count;i++)
    935         {
    936             hyp_perm[i]=i;
    937             hyp_cost_array[i]=0.0;
    938         }
    939         for(i=0,last_hyp=hyp_count-1;(last_hyp>0) && (i<point_count);i+=chunk_size)
    940         {
    941             /*Update cost with the next chunk*/
    942             last_corr=db_mini(i+chunk_size-1,point_count-1);
    943             for(j=0;j<=last_hyp;j++)
    944             {
    945                 hyp_point=hyp_H_array+9*hyp_perm[j];
    946                 for(c=i;c<=last_corr;)
    947                 {
    948                     /*Take log of product of ten reprojection
    949                     errors to reduce nr of expensive log operations*/
    950                     if(c+9<=last_corr)
    951                     {
    952                         x_i_temp=x_i+(c<<1);
    953                         xp_i_temp=xp_i+(c<<1);
    954 
    955                         acc=db_ExpCauchyInhomogenousHomographyError(xp_i_temp,hyp_point,x_i_temp,one_over_scale2);
    956                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+2,hyp_point,x_i_temp+2,one_over_scale2);
    957                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+4,hyp_point,x_i_temp+4,one_over_scale2);
    958                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+6,hyp_point,x_i_temp+6,one_over_scale2);
    959                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+8,hyp_point,x_i_temp+8,one_over_scale2);
    960                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+10,hyp_point,x_i_temp+10,one_over_scale2);
    961                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+12,hyp_point,x_i_temp+12,one_over_scale2);
    962                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+14,hyp_point,x_i_temp+14,one_over_scale2);
    963                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+16,hyp_point,x_i_temp+16,one_over_scale2);
    964                         acc*=db_ExpCauchyInhomogenousHomographyError(xp_i_temp+18,hyp_point,x_i_temp+18,one_over_scale2);
    965                         c+=10;
    966                     }
    967                     else
    968                     {
    969                         for(acc=1.0;c<=last_corr;c++)
    970                         {
    971                             acc*=db_ExpCauchyInhomogenousHomographyError(xp_i+(c<<1),hyp_point,x_i+(c<<1),one_over_scale2);
    972                         }
    973                     }
    974                     hyp_cost_array[j]+=log(acc);
    975                 }
    976             }
    977             if (chunk_size<point_count){
    978                 /*Prune out half of the hypotheses*/
    979                 new_last_hyp=(last_hyp+1)/2-1;
    980                 pivot=db_LeanQuickSelect(hyp_cost_array,last_hyp+1,new_last_hyp,temp_select);
    981                 for(j=0,c=0;(j<=last_hyp) && (c<=new_last_hyp);j++)
    982                 {
    983                     if(hyp_cost_array[j]<=pivot)
    984                     {
    985                         hyp_cost_array[c]=hyp_cost_array[j];
    986                         hyp_perm[c]=hyp_perm[j];
    987                         c++;
    988                     }
    989                 }
    990                 last_hyp=new_last_hyp;
    991             }
    992         }
    993         /*Find the best hypothesis*/
    994         lowest_cost=hyp_cost_array[0];
    995         best_pos=0;
    996         for(j=1;j<=last_hyp;j++)
    997         {
    998             if(hyp_cost_array[j]<lowest_cost)
    999             {
   1000                 lowest_cost=hyp_cost_array[j];
   1001                 best_pos=j;
   1002             }
   1003         }
   1004 
   1005         /*Move the best hypothesis*/
   1006         db_Copy9(H_temp,hyp_H_array+9*hyp_perm[best_pos]);
   1007 
   1008         // outlier removal
   1009         if (outlierremoveflagE) // no polishment needed
   1010         {
   1011             point_count_new = db_RemoveOutliers_Homography(H_temp,x_i,xp_i,wp,im,im_p,im_r,im_raw,im_raw_p,point_count,one_over_scale2);
   1012         }
   1013         else
   1014         {
   1015             /*Polish*/
   1016             switch(homography_type)
   1017             {
   1018             case DB_HOMOGRAPHY_TYPE_SIMILARITY:
   1019             case DB_HOMOGRAPHY_TYPE_SIMILARITY_U:
   1020             case DB_HOMOGRAPHY_TYPE_TRANSLATION:
   1021             case DB_HOMOGRAPHY_TYPE_ROTATION:
   1022             case DB_HOMOGRAPHY_TYPE_ROTATION_U:
   1023             case DB_HOMOGRAPHY_TYPE_SCALING:
   1024             case DB_HOMOGRAPHY_TYPE_S_T:
   1025             case DB_HOMOGRAPHY_TYPE_R_T:
   1026             case DB_HOMOGRAPHY_TYPE_R_S:
   1027             case DB_HOMOGRAPHY_TYPE_AFFINE:
   1028             case DB_HOMOGRAPHY_TYPE_PROJECTIVE:
   1029             case DB_HOMOGRAPHY_TYPE_CAMROTATION_F:
   1030             case DB_HOMOGRAPHY_TYPE_CAMROTATION_F_UD:
   1031                 db_RobCamRotation_Polish_Generic(H_temp,db_mini(point_count,max_points),homography_type,x_i,xp_i,one_over_scale2,max_iterations);
   1032                 break;
   1033             case DB_HOMOGRAPHY_TYPE_CAMROTATION:
   1034                 db_RobCamRotation_Polish(H_temp,db_mini(point_count,max_points),x_i,xp_i,one_over_scale2,max_iterations);
   1035                 break;
   1036             }
   1037 
   1038         }
   1039 
   1040     }
   1041     else db_Identity3x3(H_temp);
   1042 
   1043     switch(homography_type)
   1044     {
   1045     case DB_HOMOGRAPHY_TYPE_PROJECTIVE:
   1046         if(stat) stat->nr_parameters=8;
   1047         break;
   1048     case DB_HOMOGRAPHY_TYPE_AFFINE:
   1049         if(stat) stat->nr_parameters=6;
   1050         break;
   1051     case DB_HOMOGRAPHY_TYPE_SIMILARITY:
   1052     case DB_HOMOGRAPHY_TYPE_SIMILARITY_U:
   1053     case DB_HOMOGRAPHY_TYPE_CAMROTATION_F:
   1054     case DB_HOMOGRAPHY_TYPE_CAMROTATION_F_UD:
   1055         if(stat) stat->nr_parameters=4;
   1056         break;
   1057     case DB_HOMOGRAPHY_TYPE_CAMROTATION:
   1058         if(stat) stat->nr_parameters=3;
   1059         break;
   1060     case DB_HOMOGRAPHY_TYPE_TRANSLATION:
   1061     case DB_HOMOGRAPHY_TYPE_S_T:
   1062     case DB_HOMOGRAPHY_TYPE_R_T:
   1063     case DB_HOMOGRAPHY_TYPE_R_S:
   1064         if(stat) stat->nr_parameters=2;
   1065         break;
   1066     case DB_HOMOGRAPHY_TYPE_ROTATION:
   1067     case DB_HOMOGRAPHY_TYPE_ROTATION_U:
   1068     case DB_HOMOGRAPHY_TYPE_SCALING:
   1069         if(stat) stat->nr_parameters=1;
   1070         break;
   1071     }
   1072 
   1073     db_RobImageHomography_Statistics(H_temp,db_mini(point_count,max_points),x_i,xp_i,one_over_scale2,stat);
   1074 
   1075     /*Put on the calibration matrices*/
   1076     db_Multiply3x3_3x3(H_temp2,H_temp,K_inv);
   1077     db_Multiply3x3_3x3(H,Kp,H_temp2);
   1078 
   1079     if (finalNumE)
   1080         *finalNumE = point_count_new;
   1081 
   1082 }
   1083