Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpTemplateTrackerZNCCInverseCompositional.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  * Template tracker.
32  *
33  * Authors:
34  * Amaury Dame
35  * Aurelien Yol
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 #include <limits> // numeric_limits
40 
41 #include <visp3/tt/vpTemplateTrackerZNCCInverseCompositional.h>
42 #include <visp3/core/vpImageFilter.h>
43 
45  : vpTemplateTrackerZNCC(warp), compoInitialised(false),
46  evolRMS(0), x_pos(), y_pos(), threshold_RMS(1e-8), moydIrefdp()
47 {
48  useInverse=true;
49 }
50 
52 {
53  //std::cout<<"Initialise precomputed value of Compositionnal Inverse"<<std::endl;
56 
57  for(unsigned int point=0;point<templateSize;point++)
58  {
59  int i=ptTemplate[point].y;
60  int j=ptTemplate[point].x;
61 
62  X1[0]=j;X1[1]=i;
63  Warp->computeDenom(X1,p);
64  ptTemplate[point].dW=new double[nbParam];
65 
66  double dx=ptTemplate[point].dx;
67  double dy=ptTemplate[point].dy;
68  //std::cout<<ptTemplate[point].dx<<","<<ptTemplate[point].dy<<std::endl;
69 
70  Warp->getdW0(i,j,dy,dx,ptTemplate[point].dW);
71 
72  }
73  //vpTRACE("fin Comp Inverse");
74  compoInitialised=true;
75 }
76 
78 {
79  initCompInverse(I);
80 
81  if(blur)
85 
86  vpImage<double> dIxx,dIxy,dIyx,dIyy;
89 
92 
93  Warp->computeCoeff(p);
94  double Ic,dIcx=0.,dIcy=0.;
95  double Iref;
96  int i,j;
97  double i2,j2;
98  int Nbpoint=0;
99 
100  double moyIref=0;
101  double moyIc=0;
102  double denom=0;
104  vpMatrix moyd2Iref(nbParam,nbParam);moyd2Iref=0;
105 
106  for(unsigned int point=0;point<templateSize;point++)
107  {
108  i=ptTemplate[point].y;
109  j=ptTemplate[point].x;
110  X1[0]=j;X1[1]=i;
111  X2[0]=j;X2[1]=i;
112 
113  Warp->computeDenom(X1,p);
114 
115  j2=X2[0];i2=X2[1];
116 
117  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
118  {
119  Iref=ptTemplate[point].val;
120 
121  if(!blur)
122  Ic=I.getValue(i2,j2);
123  else
124  Ic=BI.getValue(i2,j2);
125 
126  Nbpoint++;
127  moyIref+=Iref;
128  moyIc+=Ic;
129 
130  for(unsigned int it=0;it<nbParam;it++)
131  moydIrefdp[it]+=ptTemplate[point].dW[it];
132 
133 
134  Warp->dWarp(X1,X2,p,dW);
135  double *tempt=new double[nbParam];
136  for(unsigned int it=0;it<nbParam;it++)
137  tempt[it]=dW[0][it]*dIcx+dW[1][it]*dIcy;
138  double d_Ixx=dIxx.getValue(i2,j2);
139  double d_Iyy=dIyy.getValue(i2,j2);
140  double d_Ixy=dIxy.getValue(i2,j2);
141 
142  for(unsigned int it=0;it<nbParam;it++)
143  for(unsigned int jt=0;jt<nbParam;jt++)
144  {
145  moyd2Iref[it][jt] +=(dW[0][it]*(dW[0][jt]*d_Ixx+dW[1][jt]*d_Ixy)
146  +dW[1][it]*(dW[0][jt]*d_Ixy+dW[1][jt]*d_Iyy));
147  }
148 
149  delete[] tempt;
150 
151 
152  }
153  }
154 
155  moyIref=moyIref/Nbpoint;
156  moydIrefdp=moydIrefdp/Nbpoint;
157  moyd2Iref=moyd2Iref/Nbpoint;
158  moyIc=moyIc/Nbpoint;
159  Hdesire=0;
160  double covarIref=0,covarIc=0;
161  double sIcIref=0;
162  vpColVector sIcdIref(nbParam);sIcdIref=0;
163  vpMatrix sIcd2Iref(nbParam,nbParam);sIcd2Iref=0;
164  vpMatrix sdIrefdIref(nbParam,nbParam);sdIrefdIref=0;
165  for(unsigned int point=0;point<templateSize;point++)
166  {
167  i=ptTemplate[point].y;
168  j=ptTemplate[point].x;
169  X1[0]=j;X1[1]=i;
170  X2[0]=j;X2[1]=i;
171 
172  Warp->computeDenom(X1,p);
173 
174  j2=X2[0];i2=X2[1];
175 
176  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
177  {
178  Iref=ptTemplate[point].val;
179 
180  if(!blur)
181  Ic=I.getValue(i2,j2);
182  else
183  Ic=BI.getValue(i2,j2);
184 
185  dIcx=dIx.getValue(i2,j2);
186  dIcy=dIy.getValue(i2,j2);
187 
188  Warp->dWarp(X1,X2,p,dW);
189 
190  double *tempt=new double[nbParam];
191  for(unsigned int it=0;it<nbParam;it++)
192  tempt[it]=dW[0][it]*dIcx+dW[1][it]*dIcy;
193 
194  double prodIc=(Ic-moyIc);
195 
196  double d_Ixx=dIxx.getValue(i2,j2);
197  double d_Iyy=dIyy.getValue(i2,j2);
198  double d_Ixy=dIxy.getValue(i2,j2);
199 
200  for(unsigned int it=0;it<nbParam;it++)
201  for(unsigned int jt=0;jt<nbParam;jt++)
202  {
203  sIcd2Iref[it][jt] +=prodIc*(dW[0][it]*(dW[0][jt]*d_Ixx+dW[1][jt]*d_Ixy)
204  +dW[1][it]*(dW[0][jt]*d_Ixy+dW[1][jt]*d_Iyy)-moyd2Iref[it][jt]);
205  sdIrefdIref[it][jt] +=(ptTemplate[point].dW[it]-moydIrefdp[it])*(ptTemplate[point].dW[jt]-moydIrefdp[jt]);
206  }
207 
208 
209  delete[] tempt;
210 
211  for(unsigned int it=0;it<nbParam;it++)
212  sIcdIref[it]+=prodIc*(ptTemplate[point].dW[it]-moydIrefdp[it]);
213 
214  covarIref+=(Iref-moyIref)*(Iref-moyIref);
215  covarIc+=(Ic-moyIc)*(Ic-moyIc);
216  sIcIref+=(Iref-moyIref)*(Ic-moyIc);
217  }
218 
219 
220  }
221  covarIref=sqrt(covarIref);
222  covarIc=sqrt(covarIc);
223 
224  denom=covarIref*covarIc;
225 
226  double NCC=sIcIref/denom;
227  //std::cout<<"NCC = "<<NCC<<std::endl;
228  vpColVector dcovarIref(nbParam);dcovarIref=-sIcdIref/covarIref;
229 
230  vpColVector dNCC(nbParam);dNCC=(sIcdIref/denom-NCC*dcovarIref/covarIref);
231  vpMatrix d2covarIref(nbParam,nbParam);
232  d2covarIref=-(sIcd2Iref-sdIrefdIref+dcovarIref*dcovarIref.t())/covarIref;
233 #ifdef APPROX_NCC
234  Hdesire=sIcd2Iref/denom;
235 #else
236  Hdesire=(sIcd2Iref-sdIrefdIref+dcovarIref*dcovarIref.t())/denom;
237 #endif
240  //std::cout<<"Hdesire = "<<Hdesire<<std::endl;
241 }
242 
244 {
245  if(blur)
247 
248  //double erreur=0;
249  vpColVector dpinv(nbParam);
250  double Ic;
251  double Iref;
252  unsigned int iteration=0;
253  int i,j;
254  double i2,j2;
255  initPosEvalRMS(p);
256  do
257  {
258  unsigned int Nbpoint=0;
259  //erreur=0;
260  G=0;
261  Warp->computeCoeff(p);
262  double moyIref=0;
263  double moyIc=0;
264  for(unsigned int point=0;point<templateSize;point++)
265  {
266  i=ptTemplate[point].y;
267  j=ptTemplate[point].x;
268  X1[0]=j;X1[1]=i;
269 
270  Warp->computeDenom(X1,p);
271  Warp->warpX(X1,X2,p);
272 
273  j2=X2[0];i2=X2[1];
274  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
275  {
276  Iref=ptTemplate[point].val;
277 
278  if(!blur)
279  Ic=I.getValue(i2,j2);
280  else
281  Ic=BI.getValue(i2,j2);
282 
283  Nbpoint++;
284  moyIref+=Iref;
285  moyIc+=Ic;
286  }
287 
288 
289  }
290  if(Nbpoint > 0)
291  {
292  moyIref=moyIref/Nbpoint;
293  moyIc=moyIc/Nbpoint;
294  double sIcIref=0;
295  double covarIref=0,covarIc=0;
296  vpColVector sIcdIref(nbParam);sIcdIref=0;
297  vpColVector sIrefdIref(nbParam);sIrefdIref=0;
298 
299 
300  for(unsigned int point=0;point<templateSize;point++)
301  {
302  i=ptTemplate[point].y;
303  j=ptTemplate[point].x;
304  X1[0]=j;X1[1]=i;
305 
306  Warp->computeDenom(X1,p);
307  Warp->warpX(X1,X2,p);
308 
309  j2=X2[0];i2=X2[1];
310  if((i2>=0)&&(j2>=0)&&(i2<I.getHeight()-1)&&(j2<I.getWidth()-1))
311  {
312  Iref=ptTemplate[point].val;
313 
314  if(!blur)
315  Ic=I.getValue(i2,j2);
316  else
317  Ic=BI.getValue(i2,j2);
318 
319 
320  double prod=(Ic-moyIc);
321  for(unsigned int it=0;it<nbParam;it++)
322  sIcdIref[it]+=prod*(ptTemplate[point].dW[it]-moydIrefdp[it]);
323  for(unsigned int it=0;it<nbParam;it++)
324  sIrefdIref[it]+=(Iref-moyIref)*(ptTemplate[point].dW[it]-moydIrefdp[it]);
325 
326  //double er=(Iref-Ic);
327  //erreur+=(er*er);
328  //denom+=(Iref-moyIref)*(Iref-moyIref)*(Ic-moyIc)*(Ic-moyIc);
329  covarIref+=(Iref-moyIref)*(Iref-moyIref);
330  covarIc+=(Ic-moyIc)*(Ic-moyIc);
331  sIcIref+=(Iref-moyIref)*(Ic-moyIc);
332  }
333 
334 
335  }
336  covarIref=sqrt(covarIref);
337  covarIc=sqrt(covarIc);
338  double denom=covarIref*covarIc;
339 
340  //if(denom==0.0)
341  if (std::fabs(denom) <= std::numeric_limits<double>::epsilon())
342  {
343  diverge=true;
344  }
345  else
346  {
347  double NCC=sIcIref/denom;
348  vpColVector dcovarIref(nbParam);dcovarIref=sIrefdIref/covarIref;
349  G=1.*(sIcdIref/denom-NCC*dcovarIref/covarIref);
350 
351 
352  try
353  {
354  dp=-1.*HLMdesireInverse*G;
355  }
356  catch(...)
357  {
358  std::cout<<"probleme inversion"<<std::endl;
359  break;
360  }
361 
362  Warp->getParamInverse(dp,dpinv);
363  Warp->pRondp(p,dpinv,p);
364 
365  computeEvalRMS(p);
366  }
367  }
368  else
369  diverge=true;
370 
371  iteration++;
372  }
373  while( (!diverge &&(evolRMS>threshold_RMS) && (iteration < iterationMax)));
374 
375  //std::cout<<"erreur "<<erreur<<std::endl;
376  nbIteration=iteration;
377 
379 }
380 
382 {
383  unsigned int nb_corners = zoneTracked->getNbTriangle() * 3;
384  x_pos.resize(nb_corners);
385  y_pos.resize(nb_corners);
386 
387  Warp->computeCoeff(p);
388  vpTemplateTrackerTriangle triangle;
389 
390  for(unsigned int i=0;i<zoneTracked->getNbTriangle();i++)
391  {
392  zoneTracked->getTriangle(i, triangle);
393  for (unsigned int j=0; j<3; j++) {
394  triangle.getCorner(j, X1[0], X1[1]);
395 
396  Warp->computeDenom(X1,p_);
397  Warp->warpX(X1,X2,p_);
398  x_pos[i*3+j]=X2[0];
399  y_pos[i*3+j]=X2[1];
400  }
401  }
402 }
403 
405 {
406  unsigned int nb_corners = zoneTracked->getNbTriangle() * 3;
407 
408  Warp->computeCoeff(p_);
409  evolRMS=0;
410  vpTemplateTrackerTriangle triangle;
411 
412  for(unsigned int i=0;i<zoneTracked->getNbTriangle();i++)
413  {
414  zoneTracked->getTriangle(i, triangle);
415  for (unsigned int j=0; j<3; j++) {
416  triangle.getCorner(j, X1[0], X1[1]);
417 
418  Warp->computeDenom(X1,p_);
419  Warp->warpX(X1,X2,p_);
420  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]);
421  x_pos[i*3+j]=X2[0];
422  y_pos[i*3+j]=X2[1];
423  }
424  }
425  evolRMS=evolRMS/nb_corners;
426 
427 }
428 
430 {
431 }
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
void getTriangle(unsigned int i, vpTemplateTrackerTriangle &T) const
unsigned int getWidth() const
Definition: vpImage.h:226
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
Type getValue(double i, double j) const
Definition: vpImage.h:1477
vpColVector getCorner(unsigned int i) const
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
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
unsigned int getNbTriangle() const
vpImage< double > dIx
vpRowVector t() const
vpImage< double > dIy
virtual void getdW0(const int &i, const int &j, const double &dy, const double &dx, double *dIdW)=0
unsigned int nbIteration
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
vpMatrix inverseByLU() const
vpTemplateTrackerZone * zoneTracked
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)
vpTemplateTrackerWarp * Warp
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:3525
virtual void dWarp(const vpColVector &X1, const vpColVector &X2, const vpColVector &ParamM, vpMatrix &dW)=0
void resize(const unsigned int i, const bool flagNullify=true)
Definition: vpColVector.h:225