ViSP  2.9.0
vpTemplateTrackerWarpHomographySL3.cpp
1 /****************************************************************************
2  *
3  * $Id: vpTemplateTrackerWarpHomographySL3.cpp 4669 2014-02-16 16:25:57Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  * Description:
34  * Template tracker.
35  *
36  * Authors:
37  * Amaury Dame
38  * Aurelien Yol
39  * Fabien Spindler
40  *
41  *****************************************************************************/
42 #include <visp/vpTemplateTrackerWarpHomographySL3.h>
43 
44 //findWarp special a SL3 car methode additionnelle ne marche pas (la derivee n est calculable qu en p=0)
45 // => resout le probleme de maniere compositionnelle
46 void vpTemplateTrackerWarpHomographySL3::findWarp(const double *ut0,const double *vt0,
47  const double *u, const double *v,int nb_pt,vpColVector& p)
48 {
49  //std::cout<<"findWarp OVERLOADE"<<std::endl;
50  vpColVector dp(nbParam);
51  vpMatrix dW_(2,nbParam);
52  vpMatrix dX(2,1);
54  vpMatrix G_(nbParam,1);
55 
56  //vpMatrix *dW_ddp0=new vpMatrix[nb_pt];
57  double **dW_ddp0=new double*[(unsigned int)nb_pt];
58  for(int i=0;i<nb_pt;i++)
59  {
60  //dW_ddp0[i].resize(2,nbParam);
61  dW_ddp0[i]=new double[2*nbParam];
62  //getdWdp0(vt0[i],ut0[i],dW_ddp0[i]);
63  //std::cout<<"findWarp"<<v[i]<<","<<u[i]<<std::endl;
64  getdWdp0(v[i],u[i],dW_ddp0[i]);
65  }
66 
67  int cpt=0;
68  vpColVector X1(2);
69  vpColVector fX1(2);
70  vpColVector X2(2);
71  double erreur=0;
72  double erreur_prec;
73  double lambda=0.00001;
74  do
75  {
76  erreur_prec=erreur;
77  H=0;
78  G_=0;
79  erreur=0;
80  computeCoeff(p);
81  for(int i=0;i<nb_pt;i++)
82  {
83  X1[0]=ut0[i];
84  X1[1]=vt0[i];
85  computeDenom(X1,p);
86  warpX(X1,fX1,p);
87  //dWarpCompo(X1,fX1,p,dW_ddp0[i],dW);
88  //dWarp(X1,fX1,p,dW);
89  for(unsigned int ip=0;ip<nbParam;ip++)
90  {
91  dW_[0][ip]=dW_ddp0[i][ip];
92  dW_[1][ip]=dW_ddp0[i][ip+nbParam];
93  }
94 
95  H+=dW_.AtA();
96 
97  X2[0]=u[i];
98  X2[1]=v[i];
99 
100  dX=X2-fX1;
101  G_+=dW_.t()*dX;
102 
103  erreur+=((u[i]-fX1[0])*(u[i]-fX1[0])+(v[i]-fX1[1])*(v[i]-fX1[1]));
104  }
105 
106  vpMatrix::computeHLM(H, lambda, HLM);
107  try{
108  dp=HLM.inverseByLU()*G_;
109  }
110  catch(...){
111  std::cout<<"Cannot inverse the matrix by LU "<<std::endl;
112  break;
113  }
114  pRondp(p,dp,p);
115 
116  cpt++;
117  // std::cout<<"erreur ="<<erreur<<std::endl;
118  }
119  //while((cpt<1500));
120  while((cpt<150)&&(sqrt((erreur_prec-erreur)*(erreur_prec-erreur))>1e-20));
121 
122  //std::cout<<"erreur apres transformation="<<erreur<<std::endl;
123  for(int i=0;i<nb_pt;i++)
124  delete[] dW_ddp0[i];
125  delete[] dW_ddp0;
126 
127 }
128 
130  : G(), dGx(), A()
131 {
132  nbParam = 8 ;
133  G.resize(3,3);
134  dGx.resize(3,nbParam);
135 
136  A.resize(8);
137  for(unsigned int i=0;i<8;i++)
138  {
139  A[i].resize(3,3);
140  A[i]=0;
141  }
142  A[0][0][2]=1;
143  A[1][1][2]=1;
144  A[2][0][1]=1;
145  A[3][1][0]=1;
146  A[4][0][0]=1;
147  A[4][1][1]=-1;
148  A[5][1][1]=-1;
149  A[5][2][2]=1;
150  A[6][2][0]=1;
151  A[7][2][1]=1;
152 }
153 
155 {
156 }
157 
158 //get the parameter corresponding to the lower level of a gaussian pyramid
159 //a refaire de facon analytique
161 {
162  double *u,*v;u=new double[4];v=new double[4];
163  //u[0]=0;v[0]=0;u[1]=640;v[1]=0;u[2]=640;v[2]=480;u[3]=0;v[3]=480;
164  u[0]=0;v[0]=0;u[1]=160;v[1]=0;u[2]=160;v[2]=120;u[3]=0;v[3]=120;
165  double *u2,*v2;u2=new double[4];v2=new double[4];
166  warp(u,v,4,p,u2,v2);
167  //p=0;findWarp(u,v,u2,v2,4,p);
168  for(int i=0;i<4;i++)
169  {
170  u[i]=u[i]/2.;
171  v[i]=v[i]/2.;
172  u2[i]=u2[i]/2.;
173  v2[i]=v2[i]/2.;
174  //std::cout<<"recherche "<<u2[i]<<","<<v2[i]<<std::endl;
175  }
176  pdown=p;
177  findWarp(u,v,u2,v2,4,pdown);
178  delete[] u;
179  delete[] v;
180  delete[] u2;
181  delete[] v2;
182 }
183 
185 {
186  double *u,*v;u=new double[4];v=new double[4];
187  //u[0]=0;v[0]=0;u[1]=640;v[1]=0;u[2]=640;v[2]=480;u[3]=0;v[3]=480;
188  u[0]=0;v[0]=0;u[1]=160;v[1]=0;u[2]=160;v[2]=120;u[3]=0;v[3]=120;
189  //u[0]=40;v[0]=30;u[1]=160;v[1]=30;u[2]=160;v[2]=120;u[3]=40;v[3]=120;
190  double *u2,*v2;u2=new double[4];v2=new double[4];
191 
192  //pup=p;
193 
194  /*vpColVector ptest=pup;
195  warp(u,v,4,ptest,u2,v2);
196  for(int i=0;i<4;i++)
197  std::cout<<"test "<<u2[i]<<","<<v2[i]<<std::endl;*/
198 
199  warp(u,v,4,p,u2,v2);
200  //p=0;findWarp(u,v,u2,v2,4,p);
201 
202 
203  for(int i=0;i<4;i++)
204  {
205  u[i]=u[i]*2.;
206  v[i]=v[i]*2.;
207  u2[i]=u2[i]*2.;
208  v2[i]=v2[i]*2.;
209  /*std::cout<<"#########################################################################################"<<std::endl;
210  std::cout<<"#########################################################################################"<<std::endl;
211  std::cout<<"#########################################################################################"<<std::endl;
212  std::cout<<"recherche "<<u2[i]<<","<<v2[i]<<std::endl;*/
213  }
214  findWarp(u,v,u2,v2,4,pup);
215 
216  delete[] u;
217  delete[] v;
218  delete[] u2;
219  delete[] v2;
220 }
221 
223 {
224  denom=vX[0]*G[2][0]+vX[1]*G[2][1]+G[2][2];
225 }
226 
228 {
229  vpMatrix pA(3,3);
230  pA[0][0]=p[4];
231  pA[0][1]=p[2];
232  pA[0][2]=p[0];
233 
234  pA[1][0]=p[3];
235  pA[1][1]=-p[4]-p[5];
236  pA[1][2]=p[1];
237 
238  pA[2][0]=p[6];
239  pA[2][1]=p[7];
240  pA[2][2]=p[5];
241 
242  G=pA.expm();
243 }
244 
245 
247 {
248  double i=vX[1],j=vX[0];
249  vXres[0]=(j*G[0][0]+i*G[0][1]+G[0][2])/denom;
250  vXres[1]=(j*G[1][0]+i*G[1][1]+G[1][2])/denom;
251 }
252 void vpTemplateTrackerWarpHomographySL3::warpX(const int &i,const int &j,double &i2,double &j2,const vpColVector &/*ParamM*/)
253 {
254  j2=(j*G[0][0]+i*G[0][1]+G[0][2])/denom;
255  i2=(j*G[1][0]+i*G[1][1]+G[1][2])/denom;
256 }
257 
259 {
260  vpHomography H;
261  for (unsigned int i=0; i<3; i++)
262  for (unsigned int j=0; j<3; j++)
263  H[i][j] = G[i][j];
264  return H;
265 }
266 
268 {
269  vpMatrix dhdx(2,3);
270  dhdx=0;
271  dhdx[0][0]=1./denom;dhdx[1][1]=1./denom;dhdx[0][2]=-X2[0]/(denom);dhdx[1][2]=-X2[1]/(denom);
272  dGx=0;
273  for(unsigned int i=0;i<3;i++)
274  {
275  dGx[i][0]=G[i][0];
276  dGx[i][1]=G[i][1];
277  dGx[i][2]=G[i][0]*X1[1];
278  dGx[i][3]=G[i][1]*X1[0];
279  dGx[i][4]=G[i][0]*X1[0]-G[i][1]*X1[1];
280  dGx[i][5]=G[i][2]-G[i][1]*X1[1];
281  dGx[i][6]=G[i][2]*X1[0];
282  dGx[i][7]=G[i][2]*X1[1];
283  }
284  dW_=dhdx*dGx;
285 
286 }
287 
288 /*calcul de di*dw(x,p0)/dp
289 */
290 void vpTemplateTrackerWarpHomographySL3::getdW0(const int &i,const int &j,const double &dy,const double &dx,double *dIdW)
291 {
292  vpMatrix dhdx(1,3);
293  dhdx=0;
294  dhdx[0][0]=dx;dhdx[0][1]=dy;dhdx[0][2]=-j*dx-i*dy;
295  G.setIdentity();
296 
297  dGx=0;
298  for(unsigned int par=0;par<3;par++)
299  {
300  dGx[par][0]=G[par][0];
301  dGx[par][1]=G[par][1];
302  dGx[par][2]=G[par][0]*i;
303  dGx[par][3]=G[par][1]*j;
304  dGx[par][4]=G[par][0]*j-G[par][1]*i;
305  dGx[par][5]=G[par][2]-G[par][1]*i;
306  dGx[par][6]=G[par][2]*j;
307  dGx[par][7]=G[par][2]*i;
308  }
309 
310  for(unsigned int par=0;par<nbParam;par++)
311  {
312  double res=0;
313  for(unsigned int par2=0;par2<3;par2++)
314  res+=dhdx[0][par2]*dGx[par2][par];
315  dIdW[par]=res;
316  }
317 
318 }
319 /*calcul de dw(x,p0)/dp
320 */
321 
322 void vpTemplateTrackerWarpHomographySL3::getdWdp0(const int &i,const int &j,double *dIdW)
323 {
324  vpMatrix dhdx(2,3);
325  dhdx=0;
326  dhdx[0][0]=1.;dhdx[1][1]=1.;dhdx[0][2]=-j;dhdx[1][2]=-i;
327  G.setIdentity();
328 
329  dGx=0;
330  for(unsigned int par=0;par<3;par++)
331  {
332  dGx[par][0]=G[par][0];
333  dGx[par][1]=G[par][1];
334  dGx[par][2]=G[par][0]*i;
335  dGx[par][3]=G[par][1]*j;
336  dGx[par][4]=G[par][0]*j-G[par][1]*i;
337  dGx[par][5]=G[par][2]-G[par][1]*i;
338  dGx[par][6]=G[par][2]*j;
339  dGx[par][7]=G[par][2]*i;
340  }
341  vpMatrix dIdW_temp(2,nbParam);
342  dIdW_temp=dhdx*dGx;
343 
344  for(unsigned int par=0;par<nbParam;par++)
345  {
346  dIdW[par]=dIdW_temp[0][par];
347  dIdW[par+nbParam]=dIdW_temp[1][par];
348  }
349 
350 }
351 void vpTemplateTrackerWarpHomographySL3::getdWdp0(const double &i,const double &j,double *dIdW)
352 {
353  vpMatrix dhdx(2,3);
354  dhdx=0;
355  dhdx[0][0]=1.;dhdx[1][1]=1.;dhdx[0][2]=-j;dhdx[1][2]=-i;
356  G.setIdentity();
357 
358  dGx=0;
359  for(unsigned int par=0;par<3;par++)
360  {
361  dGx[par][0]=G[par][0];
362  dGx[par][1]=G[par][1];
363  dGx[par][2]=G[par][0]*i;
364  dGx[par][3]=G[par][1]*j;
365  dGx[par][4]=G[par][0]*j-G[par][1]*i;
366  dGx[par][5]=G[par][2]-G[par][1]*i;
367  dGx[par][6]=G[par][2]*j;
368  dGx[par][7]=G[par][2]*i;
369  }
370  vpMatrix dIdW_temp(2,nbParam);
371  dIdW_temp=dhdx*dGx;
372 
373  for(unsigned int par=0;par<nbParam;par++)
374  {
375  dIdW[par]=dIdW_temp[0][par];
376  dIdW[par+nbParam]=dIdW_temp[1][par];
377  }
378 
379 }
380 /*compute dw=dw/dx*dw/dp
381 */
382 
384  const double *dwdp0,vpMatrix &dW_)
385 {
386  for(unsigned int i=0;i<nbParam;i++)
387  {
388  dW_[0][i]=denom*((G[0][0]-X2[0]*G[2][0])*dwdp0[i]+(G[0][1]-X2[0]*G[2][1])*dwdp0[i+nbParam]);
389  dW_[1][i]=denom*((G[1][0]-X2[1]*G[2][0])*dwdp0[i]+(G[1][1]-X2[1]*G[2][1])*dwdp0[i+nbParam]);
390  }
391 }
392 
394 {
395  ParamMinv=-ParamM;
396 }
398 {
399  //vrai que si commutatif ...
400  pres=p1+p2;
401 }
402 
void pRondp(const vpColVector &p1, const vpColVector &p2, vpColVector &pres) const
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
void computeDenom(vpColVector &vX, const vpColVector &ParamM)
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:183
void getParamPyramidDown(const vpColVector &p, vpColVector &pdown)
void getdW0(const int &i, const int &j, const double &dy, const double &dx, double *dIdW)
void dWarpCompo(const vpColVector &X1, const vpColVector &X2, const vpColVector &ParamM, const double *dwdp0, vpMatrix &dW)
void findWarp(const double *ut0, const double *vt0, const double *u, const double *v, int nb_pt, vpColVector &p)
void getdWdp0(const int &i, const int &j, double *dIdW)
This class aims to compute the homography wrt.two images.
Definition: vpHomography.h:178
void setIdentity(const double &val=1.0)
Definition: vpMatrix.cpp:1159
vpMatrix AtA() const
Definition: vpMatrix.cpp:1408
void warpX(const vpColVector &vX, vpColVector &vXres, const vpColVector &ParamM)
void getParamInverse(const vpColVector &ParamM, vpColVector &ParamMinv) const
void getParamPyramidUp(const vpColVector &p, vpColVector &pup)
vpMatrix t() const
Definition: vpMatrix.cpp:1225
Class that provides a data structure for the column vectors as well as a set of operations on these v...
Definition: vpColVector.h:72
vpMatrix inverseByLU() const
void dWarp(const vpColVector &X1, const vpColVector &X2, const vpColVector &ParamM, vpMatrix &dW)
vpMatrix expm()
Definition: vpMatrix.cpp:3868
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:4051
void warp(const double *ut0, const double *vt0, int nb_pt, const vpColVector &p, double *u, double *v)