Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpTemplateTrackerMIESM.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Example of template tracking.
32  *
33  * Authors:
34  * Amaury Dame
35  * Aurelien Yol
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
40 #include <visp3/tt_mi/vpTemplateTrackerMIESM.h>
41 
42 #ifdef VISP_HAVE_OPENMP
43 #include <omp.h>
44 #endif
45 
47  : vpTemplateTrackerMI(_warp), minimizationMethod(USE_NEWTON), CompoInitialised(false),
48  HDirect(), HInverse(), HdesireDirect(), HdesireInverse(), GDirect(), GInverse()
49 {
50  useCompositionnal=false;
51  useInverse=false;
52  if(!Warp->isESMcompatible())
53  std::cerr<<"The selected warp function is not appropriate for the ESM algorithm..."<<std::endl;
54 }
55 
57 {
59  std::cout<<"Initialise Hessian at Desired position..."<<std::endl;
60 
61  dW=0;
62 
63  //double erreur=0;
64  int Nbpoint=0;
65 
66  double i2,j2;
67  //double Tij;
68  double /*IW,*/dx,dy;
69  //int cr,ct;
70  //double er,et;
71  int i,j;
72 
73  Nbpoint=0;
74  //erreur=0;
75 
76  if(blur)
78 
80 
81  Warp->computeCoeff(p);
82  for(unsigned int point=0;point<templateSize;point++)
83  {
84  i=ptTemplate[point].y;
85  j=ptTemplate[point].x;
86  X1[0]=j;X1[1]=i;
87 
88  Warp->computeDenom(X1,p);
89  Warp->warpX(X1,X2,p);
90 
91  j2=X2[0];i2=X2[1];
92 
93  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
94  {
95  Nbpoint++;
96 // if(blur)
97 // IW=BI.getValue(i2,j2);
98 // else
99 // IW=I.getValue(i2,j2);
100 
101  //ct=ptTemplateSupp[point].ct;
102  //et=ptTemplateSupp[point].et;
103  //cr=(int)((IW*(Nc-1))/255.);
104  //er=((double)IW*(Nc-1))/255.-cr;
105 
106  // if(ApproxHessian==vpTemplateTrackerMI::HESSIAN_NONSECOND) // cas à tester AY
107  // vpTemplateTrackerMIBSpline::PutTotPVBsplineNoSecond(PrtTout,cr, er, ct, et, Nc, ptTemplate[point].dW, nbParam, bspline);
108  // else
109  // vpTemplateTrackerMIBSpline::PutTotPVBspline(PrtTout,cr, er, ct, et, Nc, ptTemplate[point].dW, nbParam, bspline);
110 
111  // vpTemplateTrackerMIBSpline::computeProbabilities(PrtTout,cr, er, ct, et, Nc, ptTemplate[point].dW, nbParam,bspline,ApproxHessian,false);
112  }
113  }
114 
115 
116  double MI;
117  computeProba(Nbpoint);
118  computeMI(MI);
120  //std::cout<<"HdesireInverse"<<std::endl<<HdesireInverse<<std::endl;
121 
123  // DIRECT COMPO
124 
128  {
132  }
133 
134  Nbpoint=0;
135  //erreur=0;
137 
138  Warp->computeCoeff(p);
139  for(unsigned int point=0;point<templateSize;point++)
140  {
141  i=ptTemplate[point].y;
142  j=ptTemplate[point].x;
143  X1[0]=j;X1[1]=i;
144 
145  Warp->computeDenom(X1,p);
146  Warp->warpX(X1,X2,p);
147 
148  j2=X2[0];i2=X2[1];
149 
150  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight())&&(j2<I.getWidth()))
151  {
152  Nbpoint++;
153  //Tij=ptTemplate[point].val;
154  //if(!blur)
155  // IW=I.getValue(i2,j2);
156  //else
157  // IW=BI.getValue(i2,j2);
158 
159  dx=1.*dIx.getValue(i2,j2)*(Nc-1)/255.;
160  dy=1.*dIy.getValue(i2,j2)*(Nc-1)/255.;
161 
162  //cr=ptTemplateSupp[point].ct;
163  //er=ptTemplateSupp[point].et;
164  //ct=(int)((IW*(Nc-1))/255.);
165  //et=((double)IW*(Nc-1))/255.-ct;
166 
167  Warp->dWarpCompo(X1,X2,p,ptTemplateCompo[point].dW,dW);
168 
169  double *tptemp=new double[nbParam];
170  for(unsigned int it=0;it<nbParam;it++)
171  tptemp[it] =dW[0][it]*dx+dW[1][it]*dy;
172 
173 
174  // vpTemplateTrackerMIBSpline::computeProbabilities(PrtTout,cr, er, ct, et, Nc, ptTemplate[point].dW, nbParam,bspline,ApproxHessian,
175  // hessianComputation== vpTemplateTrackerMI::USE_HESSIEN_DESIRE);
176  //calcul de l'erreur
177  //erreur+=(Tij-IW)*(Tij-IW);
178 
179  // if(ApproxHessian==vpTemplateTrackerMI::HESSIAN_NONSECOND) // cas à tester AY
180  // vpTemplateTrackerMIBSpline::PutTotPVBsplineNoSecond(PrtTout,cr, er, ct, et, Nc, tptemp, nbParam, bspline);
181  // else
182  // vpTemplateTrackerMIBSpline::PutTotPVBspline(PrtTout,cr, er, ct, et, Nc, tptemp, nbParam, bspline);
183 
184  // vpTemplateTrackerMIBSpline::computeProbabilities(PrtTout,cr, er, ct, et, Nc, tptemp, nbParam,bspline,ApproxHessian,false);
185 
186  delete[] tptemp;
187  }
188  }
189 
190  computeProba(Nbpoint);
191  computeMI(MI);
193  //std::cout<<"HdesireDirect"<<std::endl<<HdesireDirect<<std::endl;
194 
196 
198  //Hdesire=HdesireDirect;
199  //Hdesire=HdesireInverse;
200 
201  //std::cout<<"HdesireDirect "<<HdesireDirect<<std::endl;
202  //std::cout<<"HdesireInverse "<<HdesireInverse<<std::endl;
205 
206  //std::cout<<"\tEnd initialisation..."<<std::endl;
207 
208 }
209 
211 {
212  //std::cout<<"Initialise precomputed value of ESM Tracker"<<std::endl;
213 
220 
221  ptTemplateSupp=new vpTemplateTrackerPointSuppMIInv[templateSize];
223  for(unsigned int point=0;point<templateSize;point++)
224  {
225  int i=ptTemplate[point].y;
226  int j=ptTemplate[point].x;
227  X1[0]=j;X1[1]=i;
228  Warp->computeDenom(X1,p);
229 
230  ptTemplateCompo[point].dW=new double[2*nbParam];
231  Warp->getdWdp0(i,j,ptTemplateCompo[point].dW);
232 
233  ptTemplate[point].dW=new double[nbParam];
234  double dx=ptTemplate[point].dx*(Nc-1)/255.;
235  double dy=ptTemplate[point].dy*(Nc-1)/255.;
236  Warp->getdW0(i,j,dy,dx,ptTemplate[point].dW);
237 
238  double Tij=ptTemplate[point].val;
239  int ct=(int)((Tij*(Nc-1))/255.);
240  double et=(Tij*(Nc-1))/255.-ct;
241  ptTemplateSupp[point].et=et;
242  ptTemplateSupp[point].ct=ct;
243  ptTemplateSupp[point].Bt=new double[4];
244  ptTemplateSupp[point].dBt=new double[4];
245  for(char it=-1;it<=2;it++)
246  {
247  ptTemplateSupp[point].Bt[it+1] =vpTemplateTrackerBSpline::Bspline4(-it+et);
248  ptTemplateSupp[point].dBt[it+1] =vpTemplateTrackerMIBSpline::dBspline4(-it+et);
249  }
250  }
251  CompoInitialised=true;
252 }
253 
255 {
256  if(!CompoInitialised)
257  std::cout<<"Compositionnal tracking no initialised\nUse initCompInverse(vpImage<unsigned char> &I) function"<<std::endl;
258  dW=0;
259 
260  if(blur)
264  /* if(ApproxHessian!=HESSIAN_NONSECOND && ApproxHessian!=HESSIAN_0 && ApproxHessian!=HESSIAN_NEW && ApproxHessian!=HESSIAN_YOUCEF)
265  {
266  getGradX(dIx, d2Ix,fgdG,taillef);
267  getGradY(dIx, d2Ixy,fgdG,taillef);
268  getGradY(dIy, d2Iy,fgdG,taillef);
269  }*/
270 
271  //double erreur=0;
272  int point;
273 
275 
277  //double MIprec=-1000;
278 
279  double i2,j2;
280  //double Tij;
281  //double IW;
282  //int cr,ct;
283  //double er,et;
284 
285  vpColVector dpinv(nbParam);
286 
287  double alpha=2.;
288 
289  int i,j;
290  unsigned int iteration=0;
291  do
292  {
293  int Nbpoint=0;
294  //MIprec=MI;
295  double MI=0;
296  //erreur=0;
297 
299 
301  // Inverse
302  Warp->computeCoeff(p);
303  for(point=0;point<(int)templateSize;point++)
304  {
305  i=ptTemplate[point].y;
306  j=ptTemplate[point].x;
307  X1[0]=j;X1[1]=i;
308 
309  Warp->computeDenom(X1,p);
310  Warp->warpX(X1,X2,p);
311 
312  j2=X2[0];i2=X2[1];
313 
314  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
315  {
316  Nbpoint++;
317  //Tij=ptTemplate[point].val;
318  //if(!blur)
319  // IW=I.getValue(i2,j2);
320  //else
321  // IW=BI.getValue(i2,j2);
322 
323  //ct=ptTemplateSupp[point].ct;
324  //et=ptTemplateSupp[point].et;
325  //cr=(int)((IW*(Nc-1))/255.);
326  //er=((double)IW*(Nc-1))/255.-cr;
327 
328  // if(ApproxHessian==vpTemplateTrackerMI::HESSIAN_NONSECOND||hessianComputation==vpTemplateTrackerMI::USE_HESSIEN_DESIRE) // cas à tester AY
329  // vpTemplateTrackerMIBSpline::PutTotPVBsplineNoSecond(PrtTout, cr, er, ct, et, Nc, ptTemplate[point].dW, nbParam, bspline);
330  // else
331  // vpTemplateTrackerMIBSpline::PutTotPVBspline(PrtTout, cr, er, ct, et, Nc, ptTemplate[point].dW, nbParam, bspline);
332  }
333  }
334 
335  if(Nbpoint==0)
336  {
337  //std::cout<<"plus de point dans template suivi"<<std::endl;
338  diverge=true;
339  MI=0;
340  throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template"));
341  }
342  else
343  {
344  computeProba(Nbpoint);
345  computeMI(MI);
348  computeGradient();
349  GInverse=G;
350 
352  // DIRECT
353 
354  Nbpoint=0;
355  //MIprec=MI;
356  MI=0;
357  //erreur=0;
358 
360 
361  Warp->computeCoeff(p);
362 #ifdef VISP_HAVE_OPENMP
363  int nthreads = omp_get_num_procs() ;
364  //std::cout << "file: " __FILE__ << " line: " << __LINE__ << " function: " << __FUNCTION__ << " nthread: " << nthreads << std::endl;
365  omp_set_num_threads(nthreads);
366 #pragma omp parallel for private(point, i,j,i2,j2) default(shared)
367 #endif
368  for(point=0;point<(int)templateSize;point++)
369  {
370  i=ptTemplate[point].y;
371  j=ptTemplate[point].x;
372  X1[0]=j;X1[1]=i;
373  Warp->computeDenom(X1,p);
374  Warp->warpX(i,j,i2,j2,p);
375  X2[0]=j2;X2[1]=i2;
376 
377  //Warp->computeDenom(X1,p);
378  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
379  {
380  Nbpoint++;
381  //Tij=ptTemplate[point].val;
382  //Tij=Iterateurvecteur->val;
383  //if(!blur)
384  // IW=I.getValue(i2,j2);
385  //else
386  // IW=BI.getValue(i2,j2);
387 
388  double dx=1.*dIx.getValue(i2,j2)*(Nc-1)/255.;
389  double dy=1.*dIy.getValue(i2,j2)*(Nc-1)/255.;
390 
391  //ct=(int)((IW*(Nc-1))/255.);
392  //et=((double)IW*(Nc-1))/255.-ct;
393  //cr=ptTemplateSupp[point].ct;
394  //er=ptTemplateSupp[point].et;
395 
396  Warp->dWarpCompo(X1,X2,p,ptTemplateCompo[point].dW,dW);
397 
398  double *tptemp=new double[nbParam];
399  for(unsigned int it=0;it<nbParam;it++)
400  tptemp[it] =dW[0][it]*dx+dW[1][it]*dy;
401 
402 
403  //calcul de l'erreur
404  //erreur+=(Tij-IW)*(Tij-IW);
405  // if(bspline==3)
406  // vpTemplateTrackerMIBSpline::PutTotPVBspline3NoSecond(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam);
407  // else
408  // vpTemplateTrackerMIBSpline::PutTotPVBspline4NoSecond(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam);
409  // vpTemplateTrackerMIBSpline::computeProbabilities(PrtTout,cr, er, ct, et, Nc, tptemp, nbParam,bspline,ApproxHessian,
410  // hessianComputation==vpHessienType::USE_HESSIEN_DESIRE);
411 
412  delete[] tptemp;
413 
414  }
415  }
416 
417  computeProba(Nbpoint);
418  computeMI(MI);
421  computeGradient();
422  GDirect=G;
423 
425  {
428  }
430  //G=GDirect;
431  //G=-GInverse;
432 
433  try
434  {
435  if(minimizationMethod==vpTemplateTrackerMIESM::USE_GRADIENT)
436  dp=-gain*0.3*G;
437  else
438  {
439  switch(hessianComputation)
440  {
443  break;
445  if(HLM.cond()>HLMdesire.cond())
447  else
448  dp=gain*0.3*HLM.inverseByLU()*G;
449  break;
450  default:
451  dp=gain*0.3*HLM.inverseByLU()*G;
452  break;
453  }
454  }
455  }
456  catch(vpException &e)
457  {
458  //std::cerr<<"probleme inversion"<<std::endl;
459  throw(e);
460  }
461 
463  dp=-1.*dp;
464 
465  if(useBrent)
466  {
467  alpha=2.;
468  computeOptimalBrentGain(I,p,-MI,dp,alpha);
469  dp=alpha*dp;
470  }
471  p+=dp;
472 
473  iteration++;
474  }
475  }
476  while( /*(MI!=MIprec) &&*/(iteration< iterationMax));
477 
480  {
481  MI_postEstimation = -1;
482  }
483 
484  nbIteration=iteration;
485 }
virtual void dWarpCompo(const vpColVector &X1, const vpColVector &X2, const vpColVector &ParamM, const double *dwdp0, vpMatrix &dW)=0
void computeHessien(vpMatrix &H)
unsigned int getWidth() const
Definition: vpImage.h:226
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
static void getGradX(const vpImage< unsigned char > &I, vpImage< double > &dIx)
vpTemplateTrackerPoint * ptTemplate
static void getGradY(const vpImage< unsigned char > &I, vpImage< double > &dIy)
virtual void warpX(const int &i, const int &j, double &i2, double &j2, const vpColVector &ParamM)=0
vpTemplateTrackerMIESM()
Default constructor.
void computeOptimalBrentGain(const vpImage< unsigned char > &I, vpColVector &tp, double tMI, vpColVector &direction, double &alpha)
error that can be emited by ViSP classes.
Definition: vpException.h:73
Type getValue(double i, double j) const
Definition: vpImage.h:1477
static void getGradYGauss2D(const vpImage< unsigned char > &I, vpImage< double > &dIy, const double *gaussianKernel, const double *gaussianDerivativeKernel, unsigned int size)
static void getGradXGauss2D(const vpImage< unsigned char > &I, vpImage< double > &dIx, const double *gaussianKernel, const double *gaussianDerivativeKernel, unsigned int size)
vpImage< double > d2Ix
vpImage< double > BI
vpHessienApproximationType ApproxHessian
double cond() const
Definition: vpMatrix.cpp:3500
unsigned int templateSize
unsigned int iterationMax
Error that can be emited by the vpTracker class and its derivates.
double getCost(const vpImage< unsigned char > &I, const vpColVector &tp)
void initHessienDesired(const vpImage< unsigned char > &I)
vpImage< double > dIx
void computeMI(double &MI)
vpImage< double > dIy
vpImage< double > d2Iy
virtual bool isESMcompatible() const =0
virtual void getdW0(const int &i, const int &j, const double &dy, const double &dx, double *dIdW)=0
unsigned int nbIteration
void trackNoPyr(const vpImage< unsigned char > &I)
vpMinimizationTypeMIESM minimizationMethod
vpTemplateTrackerPointCompo * ptTemplateCompo
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
vpImage< double > d2Ixy
vpMatrix inverseByLU() const
unsigned int getHeight() const
Definition: vpImage.h:175
static void filter(const vpImage< double > &I, vpImage< double > &Iu, vpImage< double > &Iv, const vpMatrix &M, const bool convolve=false)
virtual void getdWdp0(const int &i, const int &j, double *dIdW)=0
vpTemplateTrackerWarp * Warp
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:3525
void computeProba(int &nbpoint)
vpHessienType hessianComputation
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:225