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_utilities_camera.h,v 1.3 2011/06/17 14:03:31 mbansal Exp $ */
     18 
     19 #ifndef DB_UTILITIES_CAMERA
     20 #define DB_UTILITIES_CAMERA
     21 
     22 #include "db_utilities.h"
     23 
     24 
     25 
     26 /*****************************************************************
     27 *    Lean and mean begins here                                   *
     28 *****************************************************************/
     29 /*!
     30  * \defgroup LMCamera (LM) Camera Utilities
     31  */
     32 /*\{*/
     33 
     34 #include "db_utilities.h"
     35 
     36 #define DB_RADDISTMODE_BOUGEUT  4
     37 #define DB_RADDISTMODE_2NDORDER 5
     38 #define DB_RADDISTMODE_IDENTITY 6
     39 
     40 /*!
     41 Give reasonable guess of the calibration matrix for normalization purposes.
     42 Use real K matrix when doing real geometry.
     43 focal length = (w+h)/2.0*f_correction.
     44 \param K            calibration matrix (out)
     45 \param Kinv         inverse of K (out)
     46 \param im_width     image width
     47 \param im_height    image height
     48 \param f_correction focal length correction factor
     49 \param field        set to 1 if this is a field image (fy = fx/2)
     50 \return K(3x3) intrinsic calibration matrix
     51 */
     52 DB_API void db_Approx3DCalMat(double K[9],double Kinv[9],int im_width,int im_height,double f_correction=1.0,int field=0);
     53 
     54 /*!
     55  Make a 2x2 identity matrix
     56  */
     57 void inline db_Identity2x2(double A[4])
     58 {
     59     A[0]=1;A[1]=0;
     60     A[2]=0;A[3]=1;
     61 }
     62 /*!
     63  Make a 3x3 identity matrix
     64  */
     65 void inline db_Identity3x3(double A[9])
     66 {
     67     A[0]=1;A[1]=0;A[2]=0;
     68     A[3]=0;A[4]=1;A[5]=0;
     69     A[6]=0;A[7]=0;A[8]=1;
     70 }
     71 /*!
     72  Invert intrinsic calibration matrix K(3x3)
     73  If fx or fy is 0, I is returned.
     74  */
     75 void inline db_InvertCalibrationMatrix(double Kinv[9],const double K[9])
     76 {
     77     double a,b,c,d,e,f,ainv,dinv,adinv;
     78 
     79     a=K[0];b=K[1];c=K[2];d=K[4];e=K[5];f=K[8];
     80     if((a==0.0)||(d==0.0)) db_Identity3x3(Kinv);
     81     else
     82     {
     83         Kinv[3]=0.0;
     84         Kinv[6]=0.0;
     85         Kinv[7]=0.0;
     86         Kinv[8]=1.0;
     87 
     88         ainv=1.0/a;
     89         dinv=1.0/d;
     90         adinv=ainv*dinv;
     91         Kinv[0]=f*ainv;
     92         Kinv[1]= -b*f*adinv;
     93         Kinv[2]=(b*e-c*d)*adinv;
     94         Kinv[4]=f*dinv;
     95         Kinv[5]= -e*dinv;
     96     }
     97 }
     98 /*!
     99  De-homogenize image point: xd(1:2) = xs(1:2)/xs(3).
    100  If xs(3) is 0, xd will become 0
    101  \param xd  destination point
    102  \param xs  source point
    103  */
    104 void inline db_DeHomogenizeImagePoint(double xd[2],const double xs[3])
    105 {
    106     double temp,div;
    107 
    108     temp=xs[2];
    109     if(temp!=0)
    110     {
    111         div=1.0/temp;
    112         xd[0]=xs[0]*div;xd[1]=xs[1]*div;
    113     }
    114     else
    115     {
    116         xd[0]=0.0;xd[1]=0.0;
    117     }
    118 }
    119 
    120 
    121 /*!
    122  Orthonormalize 3D rotation R
    123  */
    124 inline void db_OrthonormalizeRotation(double R[9])
    125 {
    126     double s,mult;
    127     /*Normalize first vector*/
    128     s=db_sqr(R[0])+db_sqr(R[1])+db_sqr(R[2]);
    129     mult=sqrt(1.0/(s?s:1));
    130     R[0]*=mult; R[1]*=mult; R[2]*=mult;
    131     /*Subtract scalar product from second vector*/
    132     s=R[0]*R[3]+R[1]*R[4]+R[2]*R[5];
    133     R[3]-=s*R[0]; R[4]-=s*R[1]; R[5]-=s*R[2];
    134     /*Normalize second vector*/
    135     s=db_sqr(R[3])+db_sqr(R[4])+db_sqr(R[5]);
    136     mult=sqrt(1.0/(s?s:1));
    137     R[3]*=mult; R[4]*=mult; R[5]*=mult;
    138     /*Get third vector by vector product*/
    139     R[6]=R[1]*R[5]-R[4]*R[2];
    140     R[7]=R[2]*R[3]-R[5]*R[0];
    141     R[8]=R[0]*R[4]-R[3]*R[1];
    142 }
    143 /*!
    144 Update a rotation with the update dx=[sin(phi) sin(ohm) sin(kap)]
    145 */
    146 inline void db_UpdateRotation(double R_p_dx[9],double R[9],const double dx[3])
    147 {
    148     double R_temp[9];
    149     /*Update rotation*/
    150     db_IncrementalRotationMatrix(R_temp,dx);
    151     db_Multiply3x3_3x3(R_p_dx,R_temp,R);
    152 }
    153 /*!
    154  Compute xp = Hx for inhomogenous image points.
    155  */
    156 inline void db_ImageHomographyInhomogenous(double xp[2],const double H[9],const double x[2])
    157 {
    158     double x3,m;
    159 
    160     x3=H[6]*x[0]+H[7]*x[1]+H[8];
    161     if(x3!=0.0)
    162     {
    163         m=1.0/x3;
    164         xp[0]=m*(H[0]*x[0]+H[1]*x[1]+H[2]);
    165         xp[1]=m*(H[3]*x[0]+H[4]*x[1]+H[5]);
    166     }
    167     else
    168     {
    169         xp[0]=xp[1]=0.0;
    170     }
    171 }
    172 inline double db_FocalFromCamRotFocalHomography(const double H[9])
    173 {
    174     double k1,k2;
    175 
    176     k1=db_sqr(H[2])+db_sqr(H[5]);
    177     k2=db_sqr(H[6])+db_sqr(H[7]);
    178     if(k1>=k2)
    179     {
    180         return(db_SafeSqrt(db_SafeDivision(k1,1.0-db_sqr(H[8]))));
    181     }
    182     else
    183     {
    184         return(db_SafeSqrt(db_SafeDivision(1.0-db_sqr(H[8]),k2)));
    185     }
    186 }
    187 
    188 inline double db_FocalAndRotFromCamRotFocalHomography(double R[9],const double H[9])
    189 {
    190     double back,fi;
    191 
    192     back=db_FocalFromCamRotFocalHomography(H);
    193     fi=db_SafeReciprocal(back);
    194     R[0]=H[0];      R[1]=H[1];      R[2]=fi*H[2];
    195     R[3]=H[3];      R[4]=H[4];      R[5]=fi*H[5];
    196     R[6]=back*H[6]; R[7]=back*H[7]; R[8]=H[8];
    197     return(back);
    198 }
    199 /*!
    200 Compute Jacobian at zero of three coordinates dR*x with
    201 respect to the update dR([sin(phi) sin(ohm) sin(kap)]) given x.
    202 
    203 The Jacobian at zero of the homogenous coordinates with respect to
    204     [sin(phi) sin(ohm) sin(kap)] is
    205 \code
    206     [-rx2   0   rx1 ]
    207     [  0   rx2 -rx0 ]
    208     [ rx0 -rx1   0  ].
    209 \endcode
    210 
    211 */
    212 inline void db_JacobianOfRotatedPointStride(double J[9],const double x[3],int stride)
    213 {
    214     /*The Jacobian at zero of the homogenous coordinates with respect to
    215     [sin(phi) sin(ohm) sin(kap)] is
    216     [-rx2   0   rx1 ]
    217     [  0   rx2 -rx0 ]
    218     [ rx0 -rx1   0  ]*/
    219 
    220     J[0]= -x[stride<<1];
    221     J[1]=0;
    222     J[2]=  x[stride];
    223     J[3]=0;
    224     J[4]=  x[stride<<1];
    225     J[5]= -x[0];
    226     J[6]=  x[0];
    227     J[7]= -x[stride];
    228     J[8]=0;
    229 }
    230 /*!
    231  Invert an affine (if possible)
    232  \param Hinv    inverted matrix
    233  \param H       input matrix
    234  \return true if success and false if matrix is ill-conditioned (det < 1e-7)
    235  */
    236 inline bool db_InvertAffineTransform(double Hinv[9],const double H[9])
    237 {
    238     double det=H[0]*H[4]-H[3]*H[1];
    239     if (det<1e-7)
    240     {
    241         db_Copy9(Hinv,H);
    242         return false;
    243     }
    244     else
    245     {
    246         Hinv[0]=H[4]/det;
    247         Hinv[1]=-H[1]/det;
    248         Hinv[3]=-H[3]/det;
    249         Hinv[4]=H[0]/det;
    250         Hinv[2]= -Hinv[0]*H[2]-Hinv[1]*H[5];
    251         Hinv[5]= -Hinv[3]*H[2]-Hinv[4]*H[5];
    252     }
    253     return true;
    254 }
    255 
    256 /*!
    257 Update of upper 2x2 is multiplication by
    258 \code
    259 [s 0][ cos(theta) sin(theta)]
    260 [0 s][-sin(theta) cos(theta)]
    261 \endcode
    262 */
    263 inline void db_MultiplyScaleOntoImageHomography(double H[9],double s)
    264 {
    265 
    266     H[0]*=s;
    267     H[1]*=s;
    268     H[3]*=s;
    269     H[4]*=s;
    270 }
    271 /*!
    272 Update of upper 2x2 is multiplication by
    273 \code
    274 [s 0][ cos(theta) sin(theta)]
    275 [0 s][-sin(theta) cos(theta)]
    276 \endcode
    277 */
    278 inline void db_MultiplyRotationOntoImageHomography(double H[9],double theta)
    279 {
    280     double c,s,H0,H1;
    281 
    282 
    283     c=cos(theta);
    284     s=db_SafeSqrt(1.0-db_sqr(c));
    285     H0=  c*H[0]+s*H[3];
    286     H[3]= -s*H[0]+c*H[3];
    287     H[0]=H0;
    288     H1=c*H[1]+s*H[4];
    289     H[4]= -s*H[1]+c*H[4];
    290     H[1]=H1;
    291 }
    292 
    293 inline void db_UpdateImageHomographyAffine(double H_p_dx[9],const double H[9],const double dx[6])
    294 {
    295     db_AddVectors6(H_p_dx,H,dx);
    296     db_Copy3(H_p_dx+6,H+6);
    297 }
    298 
    299 inline void db_UpdateImageHomographyProjective(double H_p_dx[9],const double H[9],const double dx[8],int frozen_coord)
    300 {
    301     int i,j;
    302 
    303     for(j=0,i=0;i<9;i++)
    304     {
    305         if(i!=frozen_coord)
    306         {
    307             H_p_dx[i]=H[i]+dx[j];
    308             j++;
    309         }
    310         else H_p_dx[i]=H[i];
    311     }
    312 }
    313 
    314 inline void db_UpdateRotFocalHomography(double H_p_dx[9],const double H[9],const double dx[4])
    315 {
    316     double f,fp,fpi;
    317     double R[9],dR[9];
    318 
    319     /*Updated matrix is diag(f+df,f+df)*dR*R*diag(1/(f+df),1/(f+df),1)*/
    320     f=db_FocalAndRotFromCamRotFocalHomography(R,H);
    321     db_IncrementalRotationMatrix(dR,dx);
    322     db_Multiply3x3_3x3(H_p_dx,dR,R);
    323     fp=f+dx[3];
    324     fpi=db_SafeReciprocal(fp);
    325     H_p_dx[2]*=fp;
    326     H_p_dx[5]*=fp;
    327     H_p_dx[6]*=fpi;
    328     H_p_dx[7]*=fpi;
    329 }
    330 
    331 /*\}*/
    332 #endif /* DB_UTILITIES_CAMERA */
    333