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_framestitching.cpp,v 1.2 2011/06/17 14:03:30 mbansal Exp $ */
     18 
     19 #include "db_utilities.h"
     20 #include "db_framestitching.h"
     21 
     22 
     23 
     24 /*****************************************************************
     25 *    Lean and mean begins here                                   *
     26 *****************************************************************/
     27 
     28 inline void db_RotationFromMOuterProductSum(double R[9],double *score,double M[9])
     29 {
     30     double N[16],q[4],lambda[4],lambda_max;
     31     double y[4];
     32     int nr_roots;
     33 
     34     N[0]=   M[0]+M[4]+M[8];
     35     N[5]=   M[0]-M[4]-M[8];
     36     N[10]= -M[0]+M[4]-M[8];
     37     N[15]= -M[0]-M[4]+M[8];
     38     N[1] =N[4] =M[5]-M[7];
     39     N[2] =N[8] =M[6]-M[2];
     40     N[3] =N[12]=M[1]-M[3];
     41     N[6] =N[9] =M[1]+M[3];
     42     N[7] =N[13]=M[6]+M[2];
     43     N[11]=N[14]=M[5]+M[7];
     44 
     45     /*get the quaternion representing the rotation
     46     by finding the eigenvector corresponding to the most
     47     positive eigenvalue. Force eigenvalue solutions, since the matrix
     48     is symmetric and solutions might otherwise be lost
     49     when the data is planar*/
     50     db_RealEigenvalues4x4(lambda,&nr_roots,N,1);
     51     if(nr_roots)
     52     {
     53         lambda_max=lambda[0];
     54         if(nr_roots>=2)
     55         {
     56             if(lambda[1]>lambda_max) lambda_max=lambda[1];
     57             if(nr_roots>=3)
     58             {
     59                 if(lambda[2]>lambda_max) lambda_max=lambda[2];
     60                 {
     61                     if(nr_roots>=4) if(lambda[3]>lambda_max) lambda_max=lambda[3];
     62                 }
     63             }
     64         }
     65     }
     66     else lambda_max=1.0;
     67     db_EigenVector4x4(q,lambda_max,N);
     68 
     69     /*Compute the rotation matrix*/
     70     db_QuaternionToRotation(R,q);
     71 
     72     if(score)
     73     {
     74         /*Compute score=transpose(q)*N*q */
     75         db_Multiply4x4_4x1(y,N,q);
     76         *score=db_ScalarProduct4(q,y);
     77     }
     78 }
     79 
     80 void db_StitchSimilarity3DRaw(double *scale,double R[9],double t[3],
     81                             double **Xp,double **X,int nr_points,int orientation_preserving,
     82                             int allow_scaling,int allow_rotation,int allow_translation)
     83 {
     84     int i;
     85     double c[3],cp[3],r[3],rp[3],M[9],s,sp,sc;
     86     double Rr[9],score_p,score_r;
     87     double *temp,*temp_p;
     88 
     89     if(allow_translation)
     90     {
     91         db_PointCentroid3D(c,X,nr_points);
     92         db_PointCentroid3D(cp,Xp,nr_points);
     93     }
     94     else
     95     {
     96         db_Zero3(c);
     97         db_Zero3(cp);
     98     }
     99 
    100     db_Zero9(M);
    101     s=sp=0;
    102     for(i=0;i<nr_points;i++)
    103     {
    104         temp=   *X++;
    105         temp_p= *Xp++;
    106         r[0]=(*temp++)-c[0];
    107         r[1]=(*temp++)-c[1];
    108         r[2]=(*temp++)-c[2];
    109         rp[0]=(*temp_p++)-cp[0];
    110         rp[1]=(*temp_p++)-cp[1];
    111         rp[2]=(*temp_p++)-cp[2];
    112 
    113         M[0]+=r[0]*rp[0];
    114         M[1]+=r[0]*rp[1];
    115         M[2]+=r[0]*rp[2];
    116         M[3]+=r[1]*rp[0];
    117         M[4]+=r[1]*rp[1];
    118         M[5]+=r[1]*rp[2];
    119         M[6]+=r[2]*rp[0];
    120         M[7]+=r[2]*rp[1];
    121         M[8]+=r[2]*rp[2];
    122 
    123         s+=db_sqr(r[0])+db_sqr(r[1])+db_sqr(r[2]);
    124         sp+=db_sqr(rp[0])+db_sqr(rp[1])+db_sqr(rp[2]);
    125     }
    126 
    127     /*Compute scale*/
    128     if(allow_scaling) sc=sqrt(db_SafeDivision(sp,s));
    129     else sc=1.0;
    130     *scale=sc;
    131 
    132     /*Compute rotation*/
    133     if(allow_rotation)
    134     {
    135         if(orientation_preserving)
    136         {
    137             db_RotationFromMOuterProductSum(R,0,M);
    138         }
    139         else
    140         {
    141             /*Try preserving*/
    142             db_RotationFromMOuterProductSum(R,&score_p,M);
    143             /*Try reversing*/
    144             M[6]= -M[6];
    145             M[7]= -M[7];
    146             M[8]= -M[8];
    147             db_RotationFromMOuterProductSum(Rr,&score_r,M);
    148             if(score_r>score_p)
    149             {
    150                 /*Reverse is better*/
    151                 R[0]=Rr[0]; R[1]=Rr[1]; R[2]= -Rr[2];
    152                 R[3]=Rr[3]; R[4]=Rr[4]; R[5]= -Rr[5];
    153                 R[6]=Rr[6]; R[7]=Rr[7]; R[8]= -Rr[8];
    154             }
    155         }
    156     }
    157     else db_Identity3x3(R);
    158 
    159     /*Compute translation*/
    160     if(allow_translation)
    161     {
    162         t[0]=cp[0]-sc*(R[0]*c[0]+R[1]*c[1]+R[2]*c[2]);
    163         t[1]=cp[1]-sc*(R[3]*c[0]+R[4]*c[1]+R[5]*c[2]);
    164         t[2]=cp[2]-sc*(R[6]*c[0]+R[7]*c[1]+R[8]*c[2]);
    165     }
    166     else db_Zero3(t);
    167 }
    168 
    169 
    170