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