Home | History | Annotate | Download | only in dbreg
      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 /*
     18 #sourcefile  vp_motionmodel.h
     19 #category    warp
     20 #description general motion model for tranlation/affine/projective
     21 #title       motion-model
     22 #parentlink  hindex.html
     23 *
     24 * Copyright 1998 Sarnoff Corporation
     25 * All Rights Reserved
     26 *
     27 * Modification History
     28 *      Date: 02/13/98
     29 *      Author: supuns
     30 *      Shop Order: 15491 001
     31 *              @(#) $Id: vp_motionmodel.h,v 1.4 2011/06/17 14:04:33 mbansal Exp $
     32 */
     33 
     34 #ifndef VP_MOTIONMODEL_H
     35 #define VP_MOTIONMODEL_H
     36 #include <stdio.h>
     37 
     38 #define         FALSE           0
     39 #define         TRUE            1
     40 
     41 #if 0 /* Moved mottomat.c and mattomot_d.c from vpmotion.h to vpcompat.h
     42      in order to remove otherwise unnecessary dependency of vpmotion,
     43      vpwarp, and newvpio on vpmath */
     44 #ifndef VPMATH_H
     45 #include "vpmath.h"
     46 #endif
     47 #endif
     48 
     49 #if 0
     50 #ifndef VP_WARP_H
     51 #include "vp_warp.h"
     52 #endif
     53 #endif
     54 /*
     55 
     56 #htmlstart
     57 # ===================================================================
     58 #h 1 Introduction
     59 
     60   This defines a motion model that can describe translation,
     61   affine, and projective projective 3d and 3d view transforms.
     62 
     63   The main structure VP_MOTION contains a 16 parameter array (That
     64   can be considered as elements of a 4x4 matrix) and a type field
     65   which can be one of VP_MOTION_NONE,VP_MOTION_TRANSLATION,
     66   VP_MOTION_AFFINE, VP_MOTION_PROJECTIVE,VP_MOTION_PROJ_3D or
     67   VP_MOTION_VIEW_3D. (These are defined using enums with gaps of 10
     68   so that subsets of these motions that are still consistant can be
     69   added in between. Motion models that are inconsistant with this set
     70   should be added at the end so the routines can hadle them
     71   independently.
     72 
     73   The transformation VP_MOTION_NONE,VP_MOTION_TRANSLATION,
     74   VP_MOTION_AFFINE, VP_MOTION_PROJECTIVE, VP_MOTION_PROJ_3D and
     75   VP_MOTION_SEMI_PROJ_3D would map a point P={x,y,z,w} to a new point
     76   P'={x',y',z',w'} using a motion model M such that P'= M.par * P.
     77   Where M.par is thought of as  elements of a 4x4 matrix ordered row
     78   by row. The interpretation of all models except VP_MOTION_SEMI_PROJ_3D
     79   is taken to be mapping of a 3d point P"={x",y",z"} which is obtained
     80   from the normalization {x'/w',y'/w',z'/w'}. In the VP_MOTION_SEMI_PROJ_3D
     81   the mapping to a point P"={x",y",z"} is obtained from the normalization
     82   {x'/w',y'/w',z'}. All these motion models have the property that they
     83   can be inverted using 4x4 matrices. Except for the VP_MOTION_SEMI_PROJ_3D all
     84   other types can also be cascaded using 4x4 matrices.
     85 
     86   Specific macros and functions have been provided to handle 2d instances
     87   of these functions. As the parameter interpretations can change when adding
     88   new motion models it is HIGHLY RECOMMENDED that you use the macros MXX,MXY..
     89   ect. to interpret each motion component.
     90 #pre
     91 */
     92 
     93 /*
     94 #endpre
     95 # ===================================================================
     96 #h 1 Typedef and Struct Declarations
     97 #pre
     98 */
     99 
    100 #define VP_MAX_MOTION_PAR 16
    101 
    102 typedef double VP_PAR;
    103 typedef VP_PAR VP_TRS[VP_MAX_MOTION_PAR];
    104 
    105 /* Do not add any motion models before VP_MOTION_PROJECTIVE */
    106 /* The order is assumed in vp functions */
    107 enum VP_MOTION_MODEL {
    108   VP_MOTION_NONE=0,
    109   VP_MOTION_TRANSLATION=10,
    110   VP_MOTION_SCALE=11,
    111   VP_MOTION_ROTATE=12,
    112   VP_MOTION_X_SHEAR=13,
    113   VP_MOTION_Y_SHEAR=14,
    114   VP_MOTION_SIMILARITY=15,
    115   VP_MOTION_AFFINE=20,
    116   VP_MOTION_PROJECTIVE=30,
    117   VP_MOTION_PROJ_3D=40,
    118   VP_MOTION_SEMI_PROJ_3D=80,
    119   VP_SIMILARITY=100,
    120   VP_VFE_AFFINE=120
    121 };
    122 
    123 #define VP_REFID (-1)   /* Default ID used for reference frame */
    124 
    125 typedef struct {
    126   VP_TRS par;            /* Contains the motion paramerers.
    127                 For the standard motion types this is
    128                 represented as 16 number that refer
    129                 to a 4x4 matrix */
    130   enum VP_MOTION_MODEL type;
    131   int refid;            /* Reference frame ( takes a point in refid frame
    132                and moves it by the par to get a point in insid
    133                frame ) */
    134   int insid;            /* Inspection frame */
    135 } VP_MOTION;
    136 
    137 //typedef VP_LIST VP_MOTION_LIST;
    138 /*
    139 #endpre
    140 # ===================================================================
    141 #h 1 Constant Declarations
    142 */
    143 
    144 /* Macros related to the 4x4 matrix parameters */
    145 #define MXX(m) (m).par[0]
    146 #define MXY(m) (m).par[1]
    147 #define MXZ(m) (m).par[2]
    148 #define MXW(m) (m).par[3]
    149 #define MYX(m) (m).par[4]
    150 #define MYY(m) (m).par[5]
    151 #define MYZ(m) (m).par[6]
    152 #define MYW(m) (m).par[7]
    153 #define MZX(m) (m).par[8]
    154 #define MZY(m) (m).par[9]
    155 #define MZZ(m) (m).par[10]
    156 #define MZW(m) (m).par[11]
    157 #define MWX(m) (m).par[12]
    158 #define MWY(m) (m).par[13]
    159 #define MWZ(m) (m).par[14]
    160 #define MWW(m) (m).par[15]
    161 
    162 /* The do {...} while (0) technique creates a statement that can be used legally
    163    in an if-else statement.  See "Swallowing the semicolon",
    164    http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC23 */
    165 /* Initialize the Motion to be Identity */
    166 #define VP_MOTION_ID(m) do {\
    167   MXX(m)=MYY(m)=MZZ(m)=MWW(m)=(VP_PAR)1.0; \
    168   MXY(m)=MXZ(m)=MXW(m)=(VP_PAR)0.0; \
    169   MYX(m)=MYZ(m)=MYW(m)=(VP_PAR)0.0; \
    170   MZX(m)=MZY(m)=MZW(m)=(VP_PAR)0.0; \
    171   MWX(m)=MWY(m)=MWZ(m)=(VP_PAR)0.0; \
    172 (m).type = VP_MOTION_TRANSLATION; } while (0)
    173 
    174 /* Initialize without altering the translation components */
    175 #define VP_KEEP_TRANSLATION_3D(m) do {\
    176   MXX(m)=MYY(m)=MZZ(m)=MWW(m)=(VP_PAR)1.0; \
    177   MXY(m)=MXZ(m)=(VP_PAR)0.0; \
    178   MYX(m)=MYZ(m)=(VP_PAR)0.0; \
    179   MZX(m)=MZY(m)=(VP_PAR)0.0; \
    180   MWX(m)=MWY(m)=MWZ(m)=(VP_PAR)0.0; \
    181   (m).type = VP_MOTION_PROJ_3D; } while (0)
    182 
    183 /* Initialize without altering the 2d translation components */
    184 #define VP_KEEP_TRANSLATION_2D(m) do {\
    185   VP_KEEP_TRANSLATION_3D(m); MZW(m)=(VP_PAR)0.0; (m).type= VP_MOTION_TRANSLATION;} while (0)
    186 
    187 /* Initialize without altering the affine & translation components */
    188 #define VP_KEEP_AFFINE_3D(m) do {\
    189   MWX(m)=MWY(m)=MWZ(m)=(VP_PAR)0.0; MWW(m)=(VP_PAR)1.0; \
    190   (m).type = VP_MOTION_PROJ_3D; } while (0)
    191 
    192 /* Initialize without altering the 2d affine & translation components */
    193 #define VP_KEEP_AFFINE_2D(m) do {\
    194   VP_KEEP_AFFINE_3D(m); \
    195   MXZ(m)=MYZ(m)=(VP_PAR)0.0; MZZ(m)=(VP_PAR)1.0; \
    196   MZX(m)=MZY(m)=MZW(m)=(VP_PAR)0.0; \
    197   (m).type = VP_MOTION_AFFINE; } while (0)
    198 
    199 /* Initialize without altering the 2d projective parameters */
    200 #define VP_KEEP_PROJECTIVE_2D(m) do {\
    201   MXZ(m)=MYZ(m)=(VP_PAR)0.0; MZZ(m)=(VP_PAR)1.0; \
    202   MZX(m)=MZY(m)=MZW(m)=MWZ(m)=(VP_PAR)0.0; \
    203   (m).type = VP_MOTION_PROJECTIVE; } while (0)
    204 
    205 /* Warp a 2d point (assuming the z component is zero) */
    206 #define VP_WARP_POINT_2D(inx,iny,m,outx,outy) do {\
    207   VP_PAR vpTmpWarpPnt___= MWX(m)*(inx)+MWY(m)*(iny)+MWW(m); \
    208   (outx) = (MXX(m)*((VP_PAR)(inx))+MXY(m)*((VP_PAR)(iny))+MXW(m))/vpTmpWarpPnt___; \
    209   (outy) = (MYX(m)*((VP_PAR)(inx))+MYY(m)*((VP_PAR)(iny))+MYW(m))/vpTmpWarpPnt___; } while (0)
    210 
    211 /* Warp a 3d point */
    212 #define VP_WARP_POINT_3D(inx,iny,inz,m,outx,outy,outz) do {\
    213   VP_PAR vpTmpWarpPnt___= MWX(m)*(inx)+MWY(m)*(iny)+MWZ(m)*((VP_PAR)(inz))+MWW(m); \
    214   (outx) = (MXX(m)*((VP_PAR)(inx))+MXY(m)*((VP_PAR)(iny))+MXZ(m)*((VP_PAR)(inz))+MXW(m))/vpTmpWarpPnt___; \
    215   (outy) = (MYX(m)*((VP_PAR)(inx))+MYY(m)*((VP_PAR)(iny))+MYZ(m)*((VP_PAR)(inz))+MYW(m))/vpTmpWarpPnt___; \
    216   (outz) = MZX(m)*((VP_PAR)(inx))+MZY(m)*((VP_PAR)(iny))+MZZ(m)*((VP_PAR)(inz))+MZW(m); \
    217   if ((m).type==VP_MOTION_PROJ_3D) (outz)/=vpTmpWarpPnt___; } while (0)
    218 
    219 /* Projections of each component */
    220 #define VP_PROJW_3D(m,x,y,z,f)   ( MWX(m)*(x)+MWY(m)*(y)+MWZ(m)*(z)+MWW(m) )
    221 #define VP_PROJX_3D(m,x,y,z,f,w) ((MXX(m)*(x)+MXY(m)*(y)+MXZ(m)*(z)+MXW(m))/(w))
    222 #define VP_PROJY_3D(m,x,y,z,f,w) ((MYX(m)*(x)+MYY(m)*(y)+MYZ(m)*(z)+MYW(m))/(w))
    223 #define VP_PROJZ_3D(m,x,y,z,f,w) ((MZX(m)*(x)+MZY(m)*(y)+MZZ(m)*(z)+MZW(m))/(w))
    224 
    225 /* Scale Down a matrix by Sfactor */
    226 #define VP_SCALEDOWN(m,Sfactor) do { \
    227   MXW(m) /= (VP_PAR)(Sfactor); MWX(m) *= (VP_PAR)(Sfactor); \
    228   MYW(m) /= (VP_PAR)(Sfactor); MWY(m) *= (VP_PAR)(Sfactor); \
    229   MZW(m) /= (VP_PAR)(Sfactor); MWZ(m) *= (VP_PAR)(Sfactor); } while (0)
    230 
    231 /* Scale Up a matrix by Sfactor */
    232 #define VP_SCALEUP(m,Sfactor) do { \
    233   MXW(m) *= (VP_PAR)(Sfactor); MWX(m) /= (VP_PAR)(Sfactor); \
    234   MYW(m) *= (VP_PAR)(Sfactor); MWY(m) /= (VP_PAR)(Sfactor); \
    235   MZW(m) *= (VP_PAR)(Sfactor); MWZ(m) /= (VP_PAR)(Sfactor); } while (0)
    236 
    237 /* Normalize the transformation matrix so that MWW is 1 */
    238 #define VP_NORMALIZE(m) if (MWW(m)!=(VP_PAR)0.0) do { \
    239   MXX(m)/=MWW(m); MXY(m)/=MWW(m); MXZ(m)/=MWW(m); MXW(m)/= MWW(m); \
    240   MYX(m)/=MWW(m); MYY(m)/=MWW(m); MYZ(m)/=MWW(m); MYW(m)/= MWW(m); \
    241   MZX(m)/=MWW(m); MZY(m)/=MWW(m); MZZ(m)/=MWW(m); MZW(m)/= MWW(m); \
    242   MWX(m)/=MWW(m); MWY(m)/=MWW(m); MWZ(m)/=MWW(m); MWW(m) = (VP_PAR)1.0; } while (0)
    243 
    244 #define VP_PRINT_TRANS(msg,b) do { \
    245   fprintf(stderr, \
    246       "%s\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n", \
    247       msg, \
    248       MXX(b),MXY(b),MXZ(b),MXW(b),  \
    249       MYX(b),MYY(b),MYZ(b),MYW(b),  \
    250       MZX(b),MZY(b),MZZ(b),MZW(b),  \
    251       MWX(b),MWY(b),MWZ(b),MWW(b)); \
    252 } while (0)
    253 
    254 /* w' projection given a point x,y,0,f */
    255 #define VP_PROJZ(m,x,y,f) ( \
    256     MWX(m)*((VP_PAR)(x))+MWY(m)*((VP_PAR)(y))+MWW(m)*((VP_PAR)(f)))
    257 
    258 /* X Projection given a point x,y,0,f and w' */
    259 #define VP_PROJX(m,x,y,w,f) (\
    260    (MXX(m)*((VP_PAR)(x))+MXY(m)*((VP_PAR)(y))+MXW(m)*((VP_PAR)(f)))/((VP_PAR)(w)))
    261 
    262 /* Y Projection given a point x,y,0,f and the w' */
    263 #define VP_PROJY(m,x,y,w,f) (\
    264   (MYX(m)*((VP_PAR)(x))+MYY(m)*((VP_PAR)(y))+MYW(m)*((VP_PAR)(f)))/((VP_PAR)(w)))
    265 
    266 /* Set the reference id for a motion */
    267 #define VP_SET_REFID(m,id) do { (m).refid=id; } while (0)
    268 
    269 /* Set the inspection id for a motion */
    270 #define VP_SET_INSID(m,id) do { (m).insid=id; } while (0)
    271 
    272 void vp_copy_motion  (const VP_MOTION *src, VP_MOTION *dst);
    273 int vp_invert_motion(const VP_MOTION* in,VP_MOTION* out);
    274 int vp_cascade_motion(const VP_MOTION* InAB, const VP_MOTION* InBC,VP_MOTION* OutAC);
    275 int vp_zoom_motion2d(VP_MOTION* in, VP_MOTION* out,
    276               int n, int w, int h, double zoom);
    277 double vp_motion_cornerdiff(const VP_MOTION *mot_a, const VP_MOTION *mot_b,
    278                      int xo, int yo, int w, int h);
    279 
    280 #endif /* VP_MOTIONMODEL_H */
    281 /* =================================================================== */
    282 /* end vp_motionmodel.h */
    283