ViSP  2.9.0
vpTemplateTrackerSSDESM.cpp
1 /****************************************************************************
2  *
3  * $Id: vpTemplateTrackerSSDESM.cpp 4632 2014-02-03 17:06:40Z 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/vpTemplateTrackerSSDESM.h>
43 #include <visp/vpImageFilter.h>
44 
46  : vpTemplateTrackerSSD(warp), compoInitialised(false), HDir(), HInv(),
47  HLMDir(), HLMInv(), GDir(), GInv()
48 {
49  useCompositionnal=false;
50  useInverse=false;
51 
52  if(!Warp->isESMcompatible())
53  std::cerr<<"The selected warp function is not appropriate for the ESM algorithm..."<<std::endl;
54 
61 }
62 
64 {
65  initCompInverse(I);
66 }
67 
69 {
70  //std::cout<<"Initialise precomputed value of ESM with templateSize: "<< templateSize<<std::endl;
72  int i,j;
73  //direct
74  for(unsigned int point=0;point<templateSize;point++)
75  {
76  i=ptTemplate[point].y;
77  j=ptTemplate[point].x;
78  ptTemplateCompo[point].dW=new double[2*nbParam];
79  X1[0]=j;X1[1]=i;
80  Warp->computeDenom(X1,p);
81  Warp->getdWdp0(i,j,ptTemplateCompo[point].dW);
82 
83  }
84 
85  //inverse
86  HInv=0;
87  for(unsigned int point=0;point<templateSize;point++)
88  {
89  i=ptTemplate[point].y;
90  j=ptTemplate[point].x;
91 
92  X1[0]=j;X1[1]=i;
93  Warp->computeDenom(X1,p);
94  ptTemplate[point].dW=new double[nbParam];
95  Warp->getdW0(i,j,ptTemplate[point].dy,ptTemplate[point].dx,ptTemplate[point].dW);
96 
97  for(unsigned int it=0;it<nbParam;it++)
98  for(unsigned int jt=0;jt<nbParam;jt++)
99  HInv[it][jt]+=ptTemplate[point].dW[it]*ptTemplate[point].dW[jt];
100  }
102 
103 compoInitialised=true;
104 }
105 
107 {
108  double erreur=0;
109  int Nbpoint=0;
110 
111  if(blur)
115 
116  double IW,dIWx,dIWy;
117  double Tij;
118  unsigned int iteration=0;
119  int i,j;
120  double i2,j2;
121  double alpha=2.;
122  do
123  {
124  Nbpoint=0;
125  erreur=0;
126  dp=0;
127  HDir=0;
128  GDir=0;
129  GInv=0;
130  Warp->computeCoeff(p);
131  for(unsigned int point=0;point<templateSize;point++)
132  {
133  i=ptTemplate[point].y;
134  j=ptTemplate[point].x;
135  X1[0]=j;X1[1]=i;
136 
137  Warp->computeDenom(X1,p);
138  Warp->warpX(X1,X2,p);
139 
140  j2=X2[0];i2=X2[1];
141  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
142  {
143  //INVERSE
144  Tij=ptTemplate[point].val;
145  if(!blur)
146  IW=I.getValue(i2,j2);
147  else
148  IW=BI.getValue(i2,j2);
149  Nbpoint++;
150  double er=(Tij-IW);
151  for(unsigned int it=0;it<nbParam;it++)
152  GInv[it]+=er*ptTemplate[point].dW[it];
153 
154  erreur+=er*er;
155 
156  //DIRECT
157  //dIWx=dIx.getValue(i2,j2);
158  //dIWy=dIy.getValue(i2,j2);
159 
160  dIWx=dIx.getValue(i2,j2)+ptTemplate[point].dx;
161  dIWy=dIy.getValue(i2,j2)+ptTemplate[point].dy;
162 
163  //Calcul du Hessien
164  //Warp->dWarp(X1,X2,p,dW);
165  Warp->dWarpCompo(X1,X2,p,ptTemplateCompo[point].dW,dW);
166 
167  double *tempt=new double[nbParam];
168  for(unsigned int it=0;it<nbParam;it++)
169  tempt[it]=dW[0][it]*dIWx+dW[1][it]*dIWy;
170 
171  for(unsigned int it=0;it<nbParam;it++)
172  for(unsigned int jt=0;jt<nbParam;jt++)
173  HDir[it][jt]+=tempt[it]*tempt[jt];
174 
175  for(unsigned int it=0;it<nbParam;it++)
176  GDir[it]+=er*tempt[it];
177  delete[] tempt;
178  }
179 
180 
181  }
183  //if(Nbpoint==0)std::cout<<"plus de point dans template suivi"<<std::endl;
184  try
185  {
186  //dp=(HLMInv+HLMDir).inverseByLU()*(GInv+GDir);
187  //dp=HLMInv.inverseByLU()*GInv+HLMDir.inverseByLU()*GDir;
188  //dp=HLMInv.inverseByLU()*GInv;
189  dp=(HLMDir).inverseByLU()*(GDir);
190  }
191  catch(...)
192  {
193  std::cout<<"probleme inversion"<<std::endl;
194  break;
195  }
196 
197  dp=gain*dp;
198  if(useBrent)
199  {
200  if(! Nbpoint) {
202  "Cannot compute optimal Brent gain: size = 0")) ;
203  }
204 
205  alpha=2.;
206  computeOptimalBrentGain(I,p,erreur/Nbpoint,dp,alpha);
207  dp=alpha*dp;
208  }
209 
210  //Warp->pRondp(p,dp,p);
211  p+=dp;
212  iteration++;
213 
214  }
215  while( (iteration < iterationMax));
216 
217  nbIteration=iteration;
218 }
219 
220 
221 /*void vpTemplateTrackerSSDESM::InitCompInverse(vpImage<unsigned char> &I)
222 {
223  ptTempateCompo=new vpTemplateTrackerPointCompo[taille_template];
224  int i,j;
225  for(int point=0;point<taille_template;point++)
226  {
227  i=ptTemplate[point].y;
228  j=ptTemplate[point].x;
229  ptTempateCompo[point].dW=new double[2*nbParam];
230  Warp->getdWdp0(i,j,ptTempateCompo[point].dW);
231  }
232 
233 }
234 
235 void vpTemplateTrackerSSDESM::track(vpImage<unsigned char> &I)
236 {
237  double erreur=0,erreur_prec=1e38;
238  int Nbpoint=0;
239 
240  int taillefiltre=taille_filtre_dgaussien;
241  double *fg=new double[taillefiltre+1] ;
242  getGaussianDerivativeKernel(fg, taillefiltre) ;
243  getGradX(I, dIx,fg,taillefiltre);
244  getGradY(I, dIy,fg,taillefiltre);
245  delete[] fg;
246 
247  vpColVector dpinv(nbParam);
248  double lambda=lambdaDep;
249  double IW,dIWx,dIWy;
250  double Tij;
251  int iteration=0;
252  int i,j;
253  double i2,j2;
254  vpTemplateTrackerPoint *pt;
255  do
256  {
257  Nbpoint=0;
258  erreur_prec=erreur;
259  erreur=0;
260  dp=0;
261  HDir=0;
262  GDir=0;
263  GInv=0;
264  Warp->ComputeCoeff(p);
265  for(int point=0;point<taille_template;point++)
266  {
267  pt=&ptTemplate[point];
268  i=pt->y;
269  j=pt->x;
270  X1[0]=j;X1[1]=i;
271 
272  Warp->ComputeDenom(X1,p);
273  Warp->warpX(X1,X2,p);
274 
275  j2=X2[0];i2=X2[1];
276  if((j2<I.getWidth())&&(i2<I.getHeight())&&(i2>0)&&(j2>0))
277  {
278  //INVERSE
279  Tij=pt->val;
280  IW=I.getPixelBI(j2,i2);
281  Nbpoint++;
282  double er=(Tij-IW);
283  for(int it=0;it<nbParam;it++)
284  GInv[it]+=er*ptTemplate[point].dW[it];
285 
286  erreur+=er*er;
287 
288  //DIRECT COMPO
289  Tij=ptTemplate[point].val;
290  IW=I.getPixelBI(j2,i2);
291  dIWx=dIx.getPixelBI(j2,i2);
292  dIWy=dIy.getPixelBI(j2,i2);
293  Nbpoint++;
294  Warp->dWarpCompo(X1,X2,p,ptTempateCompo[point].dW,dW);
295  double *tempt=new double[nbParam];
296  for(int it=0;it<nbParam;it++)
297  tempt[it] =dW[0][it]*dIWx+dW[1][it]*dIWy;
298 
299  for(int it=0;it<nbParam;it++)
300  for(int jt=0;jt<nbParam;jt++)
301  HDir[it][jt]+=tempt[it]*tempt[jt];
302 
303  for(int it=0;it<nbParam;it++)
304  GDir[it]+=er*tempt[it];
305 
306  delete[] tempt;
307  }
308 
309 
310  }
311  if(Nbpoint==0)std::cout<<"plus de point dans template suivi"<<std::endl;
312  try
313  {
314  dp=(HInv+HDir).inverseByLU()*(GInv+GDir);
315  }
316  catch(...)
317  {
318  std::cout<<"probleme inversion"<<std::endl;
319  break;
320  }
321 
322  if(Compare)write_infos(p,erreur/Nbpoint);
323 
324  p+=Gain*dp;
325  iteration++;
326 
327  }
328  while( (iteration < IterationMax));
329 
330  NbIteration=iteration;
331 }*/
332 
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:183
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:159
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:76
Type getValue(double i, double j) const
Definition: vpImage.h:1029
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)
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:150
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:4051
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:94