Visual Servoing Platform  version 3.0.0
vpTemplateTrackerSSDESM.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2015 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  * Template tracker.
32  *
33  * Authors:
34  * Amaury Dame
35  * Aurelien Yol
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 #include <visp3/tt/vpTemplateTrackerSSDESM.h>
40 #include <visp3/core/vpImageFilter.h>
41 
43  : vpTemplateTrackerSSD(warp), compoInitialised(false), HDir(), HInv(),
44  HLMDir(), HLMInv(), GDir(), GInv()
45 {
46  useCompositionnal=false;
47  useInverse=false;
48 
49  if(!Warp->isESMcompatible())
50  std::cerr<<"The selected warp function is not appropriate for the ESM algorithm..."<<std::endl;
51 
58 }
59 
61 {
62  initCompInverse(I);
63 }
64 
66 {
67  //std::cout<<"Initialise precomputed value of ESM with templateSize: "<< templateSize<<std::endl;
69  int i,j;
70  //direct
71  for(unsigned int point=0;point<templateSize;point++)
72  {
73  i=ptTemplate[point].y;
74  j=ptTemplate[point].x;
75  ptTemplateCompo[point].dW=new double[2*nbParam];
76  X1[0]=j;X1[1]=i;
77  Warp->computeDenom(X1,p);
78  Warp->getdWdp0(i,j,ptTemplateCompo[point].dW);
79 
80  }
81 
82  //inverse
83  HInv=0;
84  for(unsigned int point=0;point<templateSize;point++)
85  {
86  i=ptTemplate[point].y;
87  j=ptTemplate[point].x;
88 
89  X1[0]=j;X1[1]=i;
90  Warp->computeDenom(X1,p);
91  ptTemplate[point].dW=new double[nbParam];
92  Warp->getdW0(i,j,ptTemplate[point].dy,ptTemplate[point].dx,ptTemplate[point].dW);
93 
94  for(unsigned int it=0;it<nbParam;it++)
95  for(unsigned int jt=0;jt<nbParam;jt++)
96  HInv[it][jt]+=ptTemplate[point].dW[it]*ptTemplate[point].dW[jt];
97  }
99 
100 compoInitialised=true;
101 }
102 
104 {
105  double erreur=0;
106  unsigned int Nbpoint=0;
107 
108  if(blur)
112 
113  double IW,dIWx,dIWy;
114  double Tij;
115  unsigned int iteration=0;
116  int i,j;
117  double i2,j2;
118  double alpha=2.;
119  do
120  {
121  Nbpoint=0;
122  erreur=0;
123  dp=0;
124  HDir=0;
125  GDir=0;
126  GInv=0;
127  Warp->computeCoeff(p);
128  for(unsigned int point=0;point<templateSize;point++)
129  {
130  i=ptTemplate[point].y;
131  j=ptTemplate[point].x;
132  X1[0]=j;X1[1]=i;
133 
134  Warp->computeDenom(X1,p);
135  Warp->warpX(X1,X2,p);
136 
137  j2=X2[0];i2=X2[1];
138  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
139  {
140  //INVERSE
141  Tij=ptTemplate[point].val;
142  if(!blur)
143  IW=I.getValue(i2,j2);
144  else
145  IW=BI.getValue(i2,j2);
146  Nbpoint++;
147  double er=(Tij-IW);
148  for(unsigned int it=0;it<nbParam;it++)
149  GInv[it]+=er*ptTemplate[point].dW[it];
150 
151  erreur+=er*er;
152 
153  //DIRECT
154  //dIWx=dIx.getValue(i2,j2);
155  //dIWy=dIy.getValue(i2,j2);
156 
157  dIWx=dIx.getValue(i2,j2)+ptTemplate[point].dx;
158  dIWy=dIy.getValue(i2,j2)+ptTemplate[point].dy;
159 
160  //Calcul du Hessien
161  //Warp->dWarp(X1,X2,p,dW);
162  Warp->dWarpCompo(X1,X2,p,ptTemplateCompo[point].dW,dW);
163 
164  double *tempt=new double[nbParam];
165  for(unsigned int it=0;it<nbParam;it++)
166  tempt[it]=dW[0][it]*dIWx+dW[1][it]*dIWy;
167 
168  for(unsigned int it=0;it<nbParam;it++)
169  for(unsigned int jt=0;jt<nbParam;jt++)
170  HDir[it][jt]+=tempt[it]*tempt[jt];
171 
172  for(unsigned int it=0;it<nbParam;it++)
173  GDir[it]+=er*tempt[it];
174  delete[] tempt;
175  }
176 
177 
178  }
179  if(Nbpoint==0) {
180  //std::cout<<"plus de point dans template suivi"<<std::endl;
181  throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template"));
182  }
183 
185 
186  try
187  {
188  //dp=(HLMInv+HLMDir).inverseByLU()*(GInv+GDir);
189  //dp=HLMInv.inverseByLU()*GInv+HLMDir.inverseByLU()*GDir;
190  //dp=HLMInv.inverseByLU()*GInv;
191  dp=(HLMDir).inverseByLU()*(GDir);
192  }
193  catch(vpException &e)
194  {
195  //std::cout<<"probleme inversion"<<std::endl;
196  throw(e);
197  }
198 
199  dp=gain*dp;
200  if(useBrent)
201  {
202  alpha=2.;
203  computeOptimalBrentGain(I,p,erreur/Nbpoint,dp,alpha);
204  dp=alpha*dp;
205  }
206 
207  //Warp->pRondp(p,dp,p);
208  p+=dp;
209  iteration++;
210 
211  }
212  while( (iteration < iterationMax));
213 
214  nbIteration=iteration;
215 }
216 
217 
218 /*void vpTemplateTrackerSSDESM::InitCompInverse(vpImage<unsigned char> &I)
219 {
220  ptTempateCompo=new vpTemplateTrackerPointCompo[taille_template];
221  int i,j;
222  for(int point=0;point<taille_template;point++)
223  {
224  i=ptTemplate[point].y;
225  j=ptTemplate[point].x;
226  ptTempateCompo[point].dW=new double[2*nbParam];
227  Warp->getdWdp0(i,j,ptTempateCompo[point].dW);
228  }
229 
230 }
231 
232 void vpTemplateTrackerSSDESM::track(vpImage<unsigned char> &I)
233 {
234  double erreur=0,erreur_prec=1e38;
235  int Nbpoint=0;
236 
237  int taillefiltre=taille_filtre_dgaussien;
238  double *fg=new double[taillefiltre+1] ;
239  getGaussianDerivativeKernel(fg, taillefiltre) ;
240  getGradX(I, dIx,fg,taillefiltre);
241  getGradY(I, dIy,fg,taillefiltre);
242  delete[] fg;
243 
244  vpColVector dpinv(nbParam);
245  double lambda=lambdaDep;
246  double IW,dIWx,dIWy;
247  double Tij;
248  int iteration=0;
249  int i,j;
250  double i2,j2;
251  vpTemplateTrackerPoint *pt;
252  do
253  {
254  Nbpoint=0;
255  erreur_prec=erreur;
256  erreur=0;
257  dp=0;
258  HDir=0;
259  GDir=0;
260  GInv=0;
261  Warp->ComputeCoeff(p);
262  for(int point=0;point<taille_template;point++)
263  {
264  pt=&ptTemplate[point];
265  i=pt->y;
266  j=pt->x;
267  X1[0]=j;X1[1]=i;
268 
269  Warp->ComputeDenom(X1,p);
270  Warp->warpX(X1,X2,p);
271 
272  j2=X2[0];i2=X2[1];
273  if((j2<I.getWidth())&&(i2<I.getHeight())&&(i2>0)&&(j2>0))
274  {
275  //INVERSE
276  Tij=pt->val;
277  IW=I.getPixelBI(j2,i2);
278  Nbpoint++;
279  double er=(Tij-IW);
280  for(int it=0;it<nbParam;it++)
281  GInv[it]+=er*ptTemplate[point].dW[it];
282 
283  erreur+=er*er;
284 
285  //DIRECT COMPO
286  Tij=ptTemplate[point].val;
287  IW=I.getPixelBI(j2,i2);
288  dIWx=dIx.getPixelBI(j2,i2);
289  dIWy=dIy.getPixelBI(j2,i2);
290  Nbpoint++;
291  Warp->dWarpCompo(X1,X2,p,ptTempateCompo[point].dW,dW);
292  double *tempt=new double[nbParam];
293  for(int it=0;it<nbParam;it++)
294  tempt[it] =dW[0][it]*dIWx+dW[1][it]*dIWy;
295 
296  for(int it=0;it<nbParam;it++)
297  for(int jt=0;jt<nbParam;jt++)
298  HDir[it][jt]+=tempt[it]*tempt[jt];
299 
300  for(int it=0;it<nbParam;it++)
301  GDir[it]+=er*tempt[it];
302 
303  delete[] tempt;
304  }
305 
306 
307  }
308  if(Nbpoint==0)std::cout<<"plus de point dans template suivi"<<std::endl;
309  try
310  {
311  dp=(HInv+HDir).inverseByLU()*(GInv+GDir);
312  }
313  catch(...)
314  {
315  std::cout<<"probleme inversion"<<std::endl;
316  break;
317  }
318 
319  if(Compare)write_infos(p,erreur/Nbpoint);
320 
321  p+=Gain*dp;
322  iteration++;
323 
324  }
325  while( (iteration < IterationMax));
326 
327  NbIteration=iteration;
328 }*/
329 
virtual void dWarpCompo(const vpColVector &X1, const vpColVector &X2, const vpColVector &ParamM, const double *dwdp0, vpMatrix &dW)=0
unsigned int getWidth() const
Definition: vpImage.h:161
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true)
Definition: vpArray2D.h:167
vpTemplateTrackerPoint * ptTemplate
virtual void warpX(const int &i, const int &j, double &i2, double &j2, const vpColVector &ParamM)=0
vpTemplateTrackerSSDESM(vpTemplateTrackerWarp *warp)
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:1148
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 > BI
unsigned int templateSize
unsigned int iterationMax
void trackNoPyr(const vpImage< unsigned char > &I)
Error that can be emited by the vpTracker class and its derivates.
void initHessienDesired(const vpImage< unsigned char > &I)
static void filter(const vpImage< double > &I, vpImage< double > &Iu, vpImage< double > &Iv, const vpMatrix &M)
vpImage< double > dIx
vpImage< double > dIy
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
vpTemplateTrackerPointCompo * ptTemplateCompo
void initCompInverse(const vpImage< unsigned char > &I)
unsigned int getHeight() const
Definition: vpImage.h:152
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:3470
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:217