ViSP  2.10.0
vpTemplateTrackerSSDInverseCompositional.cpp
1 /****************************************************************************
2  *
3  * $Id: vpTemplateTrackerSSDInverseCompositional.cpp 5264 2015-02-04 13:49:55Z 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/vpTemplateTrackerSSDInverseCompositional.h>
43 #include <visp/vpImageTools.h>
44 
46  : vpTemplateTrackerSSD(warp), compoInitialised(false), HInv(), HCompInverse(), useTemplateSelect(false),
47  evolRMS(0), x_pos(), y_pos(), threshold_RMS(1e-8)
48 {
49  useInverse=true;
52 }
53 
55 {
56 
57  H=0;
58  int i,j;
59 
60  for(unsigned int point=0;point<templateSize;point++)
61  {
62  if((!useTemplateSelect)||(ptTemplateSelect[point]))
63  {
64  i=ptTemplate[point].y;
65  j=ptTemplate[point].x;
66  X1[0]=j;X1[1]=i;
67  Warp->computeDenom(X1,p);
68  ptTemplate[point].dW=new double[nbParam];
69 
70  Warp->getdW0(i,j,ptTemplate[point].dy,ptTemplate[point].dx,ptTemplate[point].dW);
71 
72  for(unsigned int it=0;it<nbParam;it++)
73  for(unsigned int jt=0;jt<nbParam;jt++)
74  H[it][jt]+=ptTemplate[point].dW[it]*ptTemplate[point].dW[jt];
75  }
76 
77  }
78  HInv=H;
79  vpMatrix HLMtemp(nbParam,nbParam);
81 
83  HCompInverse=HLMtemp.inverseByLU();
84  //std::cout<<Hinverse<<std::endl;
85  vpColVector dWtemp(nbParam);
86  vpColVector HiGtemp(nbParam);
87 
88  for(unsigned int point=0;point<templateSize;point++)
89  {
90  if((!useTemplateSelect)||(ptTemplateSelect[point]))
91  {
92  i=ptTemplate[point].y;
93  j=ptTemplate[point].x;
94  for(unsigned int it=0;it<nbParam;it++)
95  dWtemp[it]=ptTemplate[point].dW[it];
96 
97  HiGtemp = -1.*HCompInverse*dWtemp;
98  ptTemplate[point].HiG=new double[nbParam];
99 
100  for(unsigned int it=0;it<nbParam;it++)
101  ptTemplate[point].HiG[it]=HiGtemp[it];
102  }
103  }
104  compoInitialised=true;
105 }
106 
108 {
109  initCompInverse(I);
110 }
111 
113 {
114  double erreur=0;
115  unsigned int Nbpoint=0;
116  if(blur)
118 
119  vpColVector dpinv(nbParam);
120  double IW;
121  double Tij;
122  unsigned int iteration=0;
123  int i,j;
124  double i2,j2;
125  double alpha=2.;
126  //vpTemplateTrackerPointtest *pt;
127  initPosEvalRMS(p);
128 
130  do
131  {
132  Nbpoint=0;
133  erreur=0;
134  dp=0;
135  Warp->computeCoeff(p);
136  for(unsigned int point=0;point<templateSize;point++)
137  {
138  if((!useTemplateSelect)||(ptTemplateSelect[point]))
139  {
140  //pt=&ptTemplatetest[point];
141  pt=&ptTemplate[point];
142  i=pt->y;
143  j=pt->x;
144  X1[0]=j;X1[1]=i;
145  Warp->computeDenom(X1,p);
146  Warp->warpX(X1,X2,p);
147  j2=X2[0];i2=X2[1];
148 
149  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
150  {
151  Tij=pt->val;
152  if(!blur)
153  IW=I.getValue(i2,j2);
154  else
155  IW=BI.getValue(i2,j2);
156  Nbpoint++;
157  double er=(Tij-IW);
158  for(unsigned int it=0;it<nbParam;it++)
159  dp[it]+=er*pt->HiG[it];
160 
161  erreur+=er*er;
162  }
163  }
164  }
165  //std::cout << "npoint: " << Nbpoint << std::endl;
166  if(Nbpoint==0) {
167  //std::cout<<"plus de point dans template suivi"<<std::endl;
169  throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template"));
170  }
171  dp=gain*dp;
172  //std::cout<<erreur/Nbpoint<<","<<GetCost(I,p)<<std::endl;
173  if(useBrent)
174  {
175  alpha=2.;
176  computeOptimalBrentGain(I,p,erreur/Nbpoint,dp,alpha);
177  dp=alpha*dp;
178  }
179  Warp->getParamInverse(dp,dpinv);
180  Warp->pRondp(p,dpinv,p);
181  iteration++;
182 
183  computeEvalRMS(p);
184  //std::cout << "iteration: " << iteration << " max: " << iterationMax << std::endl;
185  //std::cout << "evolRMS: " << evolRMS << " threshold: " << threshold_RMS << std::endl;
186  }
187  while(/*( erreur_prec-erreur<50) &&*/ (iteration < iterationMax)&&(evolRMS>threshold_RMS));
188 
189  nbIteration=iteration;
191 }
192 
194 {
195  unsigned int nb_corners = zoneTracked->getNbTriangle() * 3;
196  x_pos.resize(nb_corners);
197  y_pos.resize(nb_corners);
198 
199  Warp->computeCoeff(p_);
200  vpTemplateTrackerTriangle triangle;
201 
202  for(unsigned int i=0;i<zoneTracked->getNbTriangle();i++)
203  {
204  zoneTracked->getTriangle(i, triangle);
205  for (unsigned int j=0; j<3; j++) {
206  triangle.getCorner(j, X1[0], X1[1]);
207 
208  Warp->computeDenom(X1,p_);
209  Warp->warpX(X1,X2,p_);
210  x_pos[i*3+j]=X2[0];
211  y_pos[i*3+j]=X2[1];
212  }
213  }
214 }
215 
217 {
218  unsigned int nb_corners = zoneTracked->getNbTriangle() * 3;
219 
220  Warp->computeCoeff(p_);
221  evolRMS=0;
222  vpTemplateTrackerTriangle triangle;
223 
224  for(unsigned int i=0;i<zoneTracked->getNbTriangle();i++)
225  {
226  zoneTracked->getTriangle(i, triangle);
227  for (unsigned int j=0; j<3; j++) {
228  triangle.getCorner(j, X1[0], X1[1]);
229 
230  Warp->computeDenom(X1,p_);
231  Warp->warpX(X1,X2,p_);
232  evolRMS+=(x_pos[i*3+j]-X2[0])*(x_pos[i*3+j]-X2[0])+(y_pos[i*3+j]-X2[1])*(y_pos[i*3+j]-X2[1]);
233  x_pos[i*3+j]=X2[0];
234  y_pos[i*3+j]=X2[1];
235  }
236  }
237  evolRMS=evolRMS/nb_corners;
238 }
239 
241 {
242 }
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
void resize(const unsigned int nrows, const unsigned int ncols, const bool nullify=true)
Definition: vpMatrix.cpp:199
void getTriangle(unsigned int i, vpTemplateTrackerTriangle &T) const
unsigned int getWidth() const
Definition: vpImage.h:161
vpTemplateTrackerPoint * ptTemplate
virtual void warpX(const int &i, const int &j, double &i2, double &j2, const vpColVector &ParamM)=0
void computeOptimalBrentGain(const vpImage< unsigned char > &I, vpColVector &tp, double tMI, vpColVector &direction, double &alpha)
Type getValue(double i, double j) const
Definition: vpImage.h:1068
vpColVector getCorner(unsigned int i) const
vpImage< double > BI
virtual void getParamInverse(const vpColVector &ParamM, vpColVector &ParamMinv) const =0
unsigned int templateSize
unsigned int iterationMax
virtual void pRondp(const vpColVector &p1, const vpColVector &p2, vpColVector &pres) const =0
Error that can be emited by the vpTracker class and its derivates.
unsigned int getNbTriangle() const
static void filter(const vpImage< double > &I, vpImage< double > &Iu, vpImage< double > &Iv, const vpMatrix &M)
virtual void getdW0(const int &i, const int &j, const double &dy, const double &dx, double *dIdW)=0
unsigned int nbIteration
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
vpTemplateTrackerZone * zoneTracked
unsigned int getHeight() const
Definition: vpImage.h:152
vpTemplateTrackerWarp * Warp
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:4320