Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
vpTemplateTrackerMI.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Example of template tracking.
33  *
34  * Authors:
35  * Amaury Dame
36  * Aurelien Yol
37  * Fabien Spindler
38  *
39  *****************************************************************************/
40 #include <visp3/core/vpException.h>
41 #include <visp3/tt_mi/vpTemplateTrackerMI.h>
42 #include <visp3/tt_mi/vpTemplateTrackerMIBSpline.h>
43 
45 {
46  bspline = (int)newbs;
48  Ncb = Nc + bspline;
49  if (Pt)
50  delete[] Pt;
51  if (Pr)
52  delete[] Pr;
53  if (Prt)
54  delete[] Prt;
55  if (dPrt)
56  delete[] dPrt;
57  if (d2Prt)
58  delete[] d2Prt;
59  if (PrtD)
60  delete[] PrtD;
61  if (dPrtD)
62  delete[] dPrtD;
63  if (PrtTout)
64  delete[] PrtTout;
65 
66  Pt = new double[Ncb];
67  Pr = new double[Ncb];
68 
69  Prt = new double[Ncb * Ncb];
70  dPrt = new double[Ncb * Ncb * (int)(nbParam)];
71  d2Prt = new double[Ncb * Ncb * (int)(nbParam * nbParam)];
72 
73  /*std::cout<<Nc*Nc*influBspline<<std::endl;std::cout<<Nc*Nc*nbParam*influBspline<<std::endl;*/
74  PrtD = new double[Nc * Nc * influBspline];
75  dPrtD = new double[Nc * Nc * (int)(nbParam)*influBspline];
76  PrtTout = new double[Nc * Nc * influBspline * (1 + (int)(nbParam + nbParam * nbParam))];
77 
79 }
80 
83  Prt(NULL), dPrt(NULL), Pt(NULL), Pr(NULL), d2Prt(NULL), PrtTout(NULL), dprtemp(NULL), PrtD(NULL), dPrtD(NULL),
84  influBspline(0), bspline(3), Nc(8), Ncb(0), d2Ix(), d2Iy(), d2Ixy(), MI_preEstimation(0), MI_postEstimation(0),
86 {
87  Ncb = Nc + bspline;
88  influBspline = bspline * bspline;
89 
90  dW.resize(2, nbParam);
92  G.resize(nbParam);
96  dprtemp = new double[nbParam];
97  temp = new double[nbParam];
98 
99  X1.resize(2);
100  X2.resize(2);
101 
102  PrtD = new double[Nc * Nc * influBspline]; //(r,t)
103  dPrtD = new double[Nc * Nc * (int)(nbParam)*influBspline];
104 
105  Prt = new double[Ncb * Ncb]; //(r,t)
106  Pt = new double[Ncb];
107  Pr = new double[Ncb];
108  dPrt = new double[Ncb * Ncb * (int)(nbParam)];
109  d2Prt = new double[Ncb * Ncb * (int)(nbParam * nbParam)];
110 
111  PrtTout = new double[Nc * Nc * influBspline * (1 + (int)(nbParam + nbParam * nbParam))];
112 
113  lambda = lambdaDep;
114 }
115 
117 {
118  Nc = nc;
119  Ncb = Nc + bspline;
120 
121  if (Pt)
122  delete[] Pt;
123  if (Pr)
124  delete[] Pr;
125  if (Prt)
126  delete[] Prt;
127  if (dPrt)
128  delete[] dPrt;
129  if (d2Prt)
130  delete[] d2Prt;
131  if (PrtD)
132  delete[] PrtD;
133  if (dPrtD)
134  delete[] dPrtD;
135  if (PrtTout)
136  delete[] PrtTout;
137 
138  PrtD = new double[Nc * Nc * influBspline]; //(r,t)
139  dPrtD = new double[Nc * Nc * (int)(nbParam)*influBspline];
140  Prt = new double[Ncb * Ncb]; //(r,t)
141  dPrt = new double[Ncb * Ncb * (int)(nbParam)];
142  Pt = new double[Ncb];
143  Pr = new double[Ncb];
144  d2Prt = new double[Ncb * Ncb * (int)(nbParam * nbParam)]; //(r,t)
145  PrtTout = new double[Nc * Nc * influBspline * (1 + (int)(nbParam + nbParam * nbParam))];
146 }
147 
149 {
150  double MI = 0;
151  int Nbpoint = 0;
152  double IW;
153 
154  unsigned int Ncb_ = (unsigned int)Ncb;
155  unsigned int Nc_ = (unsigned int)Nc;
156  unsigned int influBspline_ = (unsigned int)influBspline;
157 
158  memset(Prt, 0, Ncb_ * Ncb_ * sizeof(double));
159  memset(PrtD, 0, Nc_ * Nc_ * influBspline_ * sizeof(double));
160 
161  // Warp->ComputeMAtWarp(tp);
162  Warp->computeCoeff(tp);
163  for (unsigned int point = 0; point < templateSize; point++) {
164  X1[0] = ptTemplate[point].x;
165  X1[1] = ptTemplate[point].y;
166 
167  Warp->computeDenom(X1, tp);
168  Warp->warpX(X1, X2, tp);
169  double j2 = X2[0];
170  double i2 = X2[1];
171 
172  // Tij=Templ[i-(int)Triangle->GetMiny()][j-(int)Triangle->GetMinx()];
173  if ((i2 >= 0) && (j2 >= 0) && (i2 < I.getHeight() - 1) && (j2 < I.getWidth() - 1)) {
174  Nbpoint++;
175 
176  double Tij = ptTemplate[point].val;
177  if (!blur)
178  IW = I.getValue(i2, j2);
179  else
180  IW = BI.getValue(i2, j2);
181 
182  double Nc_1 = (Nc - 1.)/255.;
183  double IW_Nc = IW * Nc_1;
184  double Tij_Nc = Tij * Nc_1;
185  int cr = static_cast<int>(IW_Nc);
186  int ct = static_cast<int>(Tij_Nc);
187  double er = IW_Nc - cr;
188  double et = Tij_Nc - ct;
189 
190  // Calcul de l'histogramme joint par interpolation bilinÈaire
191  // (Bspline ordre 1)
192  vpTemplateTrackerMIBSpline::PutPVBsplineD(PrtD, cr, er, ct, et, Nc, 1., bspline);
193  }
194  }
195 
196  ratioPixelIn = (double)Nbpoint / (double)templateSize;
197 
198  double *pt = PrtD;
199  for (int r = 0; r < Nc; r++)
200  for (int t = 0; t < Nc; t++) {
201  for (int i = 0; i < influBspline; i++) {
202  int r2, t2;
203  r2 = r + i / bspline;
204  t2 = t + i % bspline;
205  Prt[r2 * Ncb + t2] += *pt;
206 
207  pt++;
208  }
209  }
210 
211  if (Nbpoint == 0)
212  return 0;
213  for (unsigned int r = 0; r < Ncb_; r++) {
214  for (unsigned int t = 0; t < Ncb_; t++) {
215  Prt[r * Ncb_ + t] /= Nbpoint;
216  }
217  }
218  // Compute Pr, Pt
219  memset(Pr, 0, Ncb_ * sizeof(double));
220  memset(Pt, 0, Ncb_ * sizeof(double));
221  for (unsigned int r = 0; r < Ncb_; r++) {
222  for (unsigned int t = 0; t < Ncb_; t++) {
223  Pr[r] += Prt[r * Ncb_ + t];
224  Pt[r] += Prt[t * Ncb_ + r];
225  }
226  }
227 
228  for (unsigned int r = 0; r < Ncb_; r++) {
229  // if(Pr[r]!=0)
230  if (std::fabs(Pr[r]) > std::numeric_limits<double>::epsilon()) {
231  MI -= Pr[r] * log(Pr[r]);
232  }
233  if (std::fabs(Pt[r]) > std::numeric_limits<double>::epsilon()) {
234  MI -= Pt[r] * log(Pt[r]);
235  }
236  for (unsigned int t = 0; t < Ncb_; t++) {
237  unsigned int r_Ncb_t_ = r * Ncb_ + t;
238  // if(Prt[r*Ncb+t]!=0)
239  if (std::fabs(Prt[r_Ncb_t_]) > std::numeric_limits<double>::epsilon()) {
240  MI += Prt[r_Ncb_t_] * log(Prt[r_Ncb_t_]);
241  }
242  }
243  }
244 
245  return -MI;
246 }
247 
249 {
250  // Attention, cette version calculée de la NMI ne pourra pas atteindre le
251  // maximum de 2 Ceci est du au fait que par defaut, l'image est floutée dans
252  // vpTemplateTracker::initTracking()
253 
254  double MI = 0;
255  double Nbpoint = 0;
256  double IW;
257 
258  double Pr_[256];
259  double Pt_[256];
260  double Prt_[256][256];
261 
262  memset(Pr_, 0, 256 * sizeof(double));
263  memset(Pt_, 0, 256 * sizeof(double));
264  memset(Prt_, 0, 256 * 256 * sizeof(double));
265 
266  for (unsigned int point = 0; point < templateSize; point++) {
267  X1[0] = ptTemplate[point].x;
268  X1[1] = ptTemplate[point].y;
269 
270  Warp->computeDenom(X1, tp);
271  Warp->warpX(X1, X2, tp);
272  double j2 = X2[0];
273  double i2 = X2[1];
274 
275  if ((i2 >= 0) && (j2 >= 0) && (i2 < I.getHeight() - 1) && (j2 < I.getWidth() - 1)) {
276  Nbpoint++;
277  double Tij = ptTemplate[point].val;
278  int Tij_ = static_cast<int>(Tij);
279  if (!blur) {
280  IW = I[(int)i2][(int)j2];
281  }
282  else {
283  IW = BI.getValue(i2, j2);
284  }
285  int IW_ = static_cast<int>(IW);
286 
287  Pr_[Tij_]++;
288  Pt_[IW_]++;
289  Prt_[Tij_][IW_]++;
290  }
291  }
292 
293  double denom = 0;
294  for (int r = 0; r < 256; r++) {
295  Pr_[r] /= Nbpoint;
296  Pt_[r] /= Nbpoint;
297  if (std::fabs(Pr_[r]) > std::numeric_limits<double>::epsilon()) {
298  MI -= Pr_[r] * log(Pr_[r]);
299  }
300  if (std::fabs(Pt_[r]) > std::numeric_limits<double>::epsilon()) {
301  MI -= Pt_[r] * log(Pt_[r]);
302  }
303  for (int t = 0; t < 256; t++) {
304  Prt_[r][t] /= Nbpoint;
305  if (std::fabs(Prt_[r][t]) > std::numeric_limits<double>::epsilon()) {
306  denom -= (Prt_[r][t] * log(Prt_[r][t]));
307  }
308  }
309  }
310 
311  if (std::fabs(denom) > std::numeric_limits<double>::epsilon())
312  MI = MI / denom;
313  else
314  MI = 0;
315 
316  return -MI;
317 }
318 
320 {
321  if (Pt)
322  delete[] Pt;
323  if (Pr)
324  delete[] Pr;
325  if (Prt)
326  delete[] Prt;
327  if (dPrt)
328  delete[] dPrt;
329  if (d2Prt)
330  delete[] d2Prt;
331  if (PrtD)
332  delete[] PrtD;
333  if (dPrtD)
334  delete[] dPrtD;
335  if (PrtTout)
336  delete[] PrtTout;
337  if (temp)
338  delete[] temp;
339  if (dprtemp)
340  delete[] dprtemp;
341 }
342 
344 {
345  double *pt = PrtTout;
346  unsigned int Nc_ = static_cast<unsigned int>(Nc);
347  unsigned int Ncb_ = static_cast<unsigned int>(Ncb);
348  unsigned int bspline_ = static_cast<unsigned int>(bspline);
349 
350  for (unsigned int r = 0; r < Nc_; r++) {
351  for (unsigned int t = 0; t < Nc_; t++) {
352  for (unsigned int r2 = 0; r2 < bspline_; r2++) {
353  unsigned int r2_r_Ncb_ = (r2 + r) * Ncb_;
354  for (unsigned int t2 = 0; t2 < bspline_; t2++) {
355  unsigned int t2_t_ = t2 + t;
356  unsigned int r2_r_Ncb_t2_t_nbParam_ = (r2_r_Ncb_ + t2_t_) * nbParam;
357  Prt[r2_r_Ncb_ + t2_t_] += *pt++;
358  for (unsigned int ip = 0; ip < nbParam; ip++) {
359  dPrt[r2_r_Ncb_t2_t_nbParam_ + ip] += *pt++;
360  unsigned int ip_nbParam_ = ip * nbParam;
361  for (unsigned int it = 0; it < nbParam; it++) {
362  d2Prt[r2_r_Ncb_t2_t_nbParam_ * nbParam + ip_nbParam_ + it] += *pt++;
363  }
364  }
365  }
366  }
367  }
368  }
369 
370  if (nbpoint == 0) {
371  throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template"));
372  }
373  unsigned int indd, indd2;
374  indd = indd2 = 0;
375  for (volatile int i = 0; i < Ncb * Ncb; i++) {
376  Prt[i] = Prt[i] / nbpoint;
377  for (unsigned int j = 0; j < nbParam; j++) {
378  dPrt[indd] /= nbpoint;
379  indd++;
380  for (unsigned int k = 0; k < nbParam; k++) {
381  d2Prt[indd2] /= nbpoint;
382  indd2++;
383  }
384  }
385  }
386 }
387 
389 {
390  unsigned int Ncb_ = (unsigned int)Ncb;
391 
392  // Compute Pr and Pt
393  memset(Pr, 0, Ncb_ * sizeof(double));
394  memset(Pt, 0, Ncb_ * sizeof(double));
395  for (unsigned int r = 0; r < Ncb_; r++) {
396  unsigned int r_Nbc_ = r * Ncb_;
397  for (unsigned int t = 0; t < Ncb_; t++) {
398  Pr[r] += Prt[r_Nbc_ + t];
399  Pt[r] += Prt[r + Ncb_* t];
400  }
401  }
402 
403  // Compute Entropy
404  for (unsigned int r = 0; r < Ncb_; r++) {
405  if (std::fabs(Pr[r]) > std::numeric_limits<double>::epsilon()) {
406  MI -= Pr[r] * log(Pr[r]);
407  }
408  if (std::fabs(Pt[r]) > std::numeric_limits<double>::epsilon()) {
409  MI -= Pt[r] * log(Pt[r]);
410  }
411  unsigned int r_Nbc_ = r * Ncb_;
412  for (unsigned int t = 0; t < Ncb_; t++) {
413  unsigned int r_Nbc_t_ = r_Nbc_ + t;
414  if (std::fabs(Prt[r_Nbc_t_]) > std::numeric_limits<double>::epsilon()) {
415  MI += Prt[r_Nbc_t_] * log(Prt[r_Nbc_t_]);
416  }
417  }
418  }
419 }
420 
422 {
423  double seuilevitinf = 1e-200;
424  Hessian = 0;
425  double dtemp;
426  unsigned int Ncb_ = static_cast<unsigned int>(Ncb);
427  unsigned int nbParam2 = nbParam * nbParam;
428 
429  for (unsigned int t = 0; t < Ncb_; t++) {
430  // if(Pt[t]!=0)
431  if (Pt[t] > seuilevitinf) {
432  for (unsigned int r = 0; r < Ncb_; r++) {
433  // if(Prt[r*Ncb+t]!=0)
434  if (Prt[r * Ncb_ + t] > seuilevitinf) {
435  unsigned int r_Ncb_t_ = r * Ncb_ + t;
436  unsigned int r_Ncb_t_nbParam_ = r_Ncb_t_ * nbParam ;
437  for (unsigned int it = 0; it < nbParam; it++) {
438  dprtemp[it] = dPrt[r_Ncb_t_nbParam_ + it];
439  }
440 
441  dtemp = 1. + log(Prt[r * Ncb_ + t] / Pt[t]);
442 
443  double Prt_Pt_ = 1. / Prt[r_Ncb_t_] - 1. / Pt[t];
444  unsigned int r_Ncb_t_nbParam2_ = r_Ncb_t_ * nbParam2;
445  for (unsigned int it = 0; it < nbParam; it++) {
446  unsigned int r_Ncb_t_nbParam2_it_nbParam_ = r_Ncb_t_nbParam2_ + it * nbParam;
447  for (unsigned int jt = 0; jt < nbParam; jt++) {
449  Hessian[it][jt] += dprtemp[it] * dprtemp[jt] * Prt_Pt_ +
450  d2Prt[r_Ncb_t_nbParam2_it_nbParam_ + jt] * dtemp;
451  else if (ApproxHessian == HESSIAN_NEW)
452  Hessian[it][jt] += d2Prt[r_Ncb_t_nbParam2_it_nbParam_ + jt] * dtemp;
453  else
454  Hessian[it][jt] += dprtemp[it] * dprtemp[jt] * Prt_Pt_;
455  }
456  }
457  }
458  }
459  }
460  }
461 }
462 
464 {
465  double seuilevitinf = 1e-200;
466  // double dtemp;
467  double u = 0, v = 0, B = 0;
468  m_du.resize(nbParam);
469  m_dv.resize(nbParam);
470  m_A.resize(nbParam);
471  m_dB.resize(nbParam);
472  m_d2u.resize(nbParam);
473  m_d2v.resize(nbParam);
474  m_dA.resize(nbParam);
475 
476  for (unsigned int i = 0; i < nbParam; i++) {
477  m_d2u[i].resize(nbParam);
478  m_d2v[i].resize(nbParam);
479  m_dA[i].resize(nbParam);
480  }
481 
482  std::fill(m_du.begin(), m_du.end(), 0);
483  std::fill(m_dv.begin(), m_dv.end(), 0);
484  std::fill(m_A.begin(), m_A.end(), 0);
485  std::fill(m_dB.begin(), m_dB.end(), 0);
486  for (unsigned int it = 0; it < nbParam; it++) {
487  std::fill(m_d2u[0].begin(), m_d2u[0].end(), 0);
488  std::fill(m_d2v[0].begin(), m_d2v[0].end(), 0);
489  std::fill(m_dA[0].begin(), m_dA[0].end(), 0);
490  }
491 
492  memset(dprtemp, 0, nbParam * sizeof(double));
493 
494  unsigned int Ncb_ = static_cast<unsigned int>(Ncb);
495  unsigned int nbParam2 = nbParam * nbParam;
496 
497  for (unsigned int t = 0; t < Ncb_; t++) {
498  // if(Pt[t]!=0)
499  if (Pt[t] > seuilevitinf) {
500  for (unsigned int r = 0; r < Ncb_; r++) {
501  // if(Prt[r*Ncb+t]!=0)
502  unsigned int r_Ncb_t_ = r * Ncb_ + t;
503  if (Prt[r_Ncb_t_] > seuilevitinf) {
504  unsigned int r_Ncb_t_nbParam_ = r_Ncb_t_ * nbParam;
505  for (unsigned int it = 0; it < nbParam; it++) {
506  // dPxy/dt
507  dprtemp[it] = dPrt[r_Ncb_t_nbParam_ + it];
508  }
509  double log_Pt_Pr_ = log(Pt[t] * Pr[r]);
510  double log_Prt_ = log(Prt[r_Ncb_t_]);
511  // dtemp=1.+log(Prt[r*Ncb+t]/Pt[t]);
512  // u = som(Pxy.logPxPy)
513  u += Prt[r_Ncb_t_] * log_Pt_Pr_;
514  // v = som(Pxy.logPxy)
515  v += Prt[r_Ncb_t_] * log_Prt_;
516 
517  double log_Prt_1_ = 1 + log(Prt[r_Ncb_t_]);
518  for (unsigned int it = 0; it < nbParam; it++) {
519  // u' = som dPxylog(PxPy)
520  m_du[it] += dprtemp[it] * log_Pt_Pr_;
521  // v' = som dPxy(1+log(Pxy))
522  m_dv[it] += dprtemp[it] * log_Prt_1_;
523  }
524  double Prt_ = 1.0 / Prt[r_Ncb_t_];
525  unsigned int r_Ncb_t_nbParam2_ = r_Ncb_t_ * nbParam2;
526  for (unsigned int it = 0; it < nbParam; it++) {
527  double dprtemp_it2_ = Prt_ * dprtemp[it] * dprtemp[it];
528  unsigned int r_Ncb_t_nbParam2_it_nbParam_ = r_Ncb_t_nbParam2_ + it * nbParam;
529  for (unsigned int jt = 0; jt < nbParam; jt++) {
530  unsigned int r_Ncb_t_nbParam2_it_nbParam_jt_ = r_Ncb_t_nbParam2_it_nbParam_ + jt;
531  m_d2u[it][jt] += d2Prt[r_Ncb_t_nbParam2_it_nbParam_jt_] * log_Pt_Pr_ + dprtemp_it2_;
532  m_d2v[it][jt] += d2Prt[r_Ncb_t_nbParam2_it_nbParam_jt_] * log_Prt_1_ + dprtemp_it2_;
533  }
534  }
535  }
536  }
537  }
538  }
539  // B = v2
540  B = (v * v);
541  double B2 = B * B;
542  for (unsigned int it = 0; it < nbParam; it++) {
543  // A = u'v-uv'
544  m_A[it] = m_du[it] * v - u * m_dv[it];
545  // B' = 2vv'
546  m_dB[it] = 2 * v * m_dv[it];
547  double A_it_dB_it_ = m_A[it] * m_dB[it];
548  for (unsigned int jt = 0; jt < nbParam; jt++) {
549  // A' = u''v-v''u
550  m_dA[it][jt] = m_d2u[it][jt] * v - m_d2v[it][jt] * u;
551  // Hessian = (A'B-AB')/B2
552  Hessian[it][jt] = (m_dA[it][jt] * B - A_it_dB_it_) / B2;
553  }
554  }
555 }
556 
558 {
559  double seuilevitinf = 1e-200;
560  G = 0;
561  unsigned int Ncb_ = static_cast<unsigned int>(Ncb);
562  double dtemp;
563  for (unsigned int t = 0; t < Ncb_; t++) {
564  // if(Pt[t]!=0)
565  if (Pt[t] > seuilevitinf) {
566  for (unsigned int r = 0; r < Ncb_; r++) {
567  unsigned int r_Ncb_t_ = r * Ncb_ + t;
568  if (Prt[r_Ncb_t_] > seuilevitinf) {
569  unsigned int r_Ncb_t_nbParam_ = r_Ncb_t_ * nbParam;
570  for (unsigned int it = 0; it < nbParam; it++) {
571  dprtemp[it] = dPrt[r_Ncb_t_nbParam_ + it];
572  }
573 
574  dtemp = 1. + log(Prt[r_Ncb_t_] / Pt[t]);
575 
576  for (unsigned int it = 0; it < nbParam; it++) {
577  G[it] += dtemp * dprtemp[it];
578  }
579  }
580  }
581  }
582  }
583 }
584 
586 {
587  unsigned int Ncb_ = static_cast<unsigned int>(Ncb);
588  unsigned int Nc_ = static_cast<unsigned int>(Nc);
589  unsigned int influBspline_ = static_cast<unsigned int>(influBspline);
590 
591  unsigned int Ncb2_ = Ncb_ * Ncb_ * sizeof(double);
592  unsigned int Ncb2_nbParam_ = Ncb2_ * nbParam;
593  unsigned int Ncb2_nbParam2_ = Ncb2_nbParam_ * nbParam;
594 
595  memset(Prt, 0, Ncb2_);
596  memset(dPrt, 0, Ncb2_nbParam_);
597  memset(d2Prt, 0, Ncb2_nbParam2_);
598  memset(PrtTout, 0, Nc_ * Nc_ * influBspline_ * (1 + nbParam + nbParam * nbParam) * sizeof(double));
599 }
600 
601 double vpTemplateTrackerMI::getMI(const vpImage<unsigned char> &I, int &nc, const int &bspline_, vpColVector &tp)
602 {
603  unsigned int tNcb = static_cast<unsigned int>(nc + bspline_);
604  unsigned int tinfluBspline = static_cast<unsigned int>(bspline_ * bspline_);
605  unsigned int nc_ = static_cast<unsigned int>(nc);
606 
607  double *tPrtD = new double[nc_ * nc_ * tinfluBspline];
608  double *tPrt = new double[tNcb * tNcb];
609  double *tPr = new double[tNcb];
610  double *tPt = new double[tNcb];
611 
612  double MI = 0;
613  volatile int Nbpoint = 0;
614  double IW;
615 
616  vpImage<double> GaussI;
617  vpImageFilter::filter(I, GaussI, fgG, taillef);
618 
619  memset(tPrt, 0, tNcb * tNcb * sizeof(double));
620  memset(tPrtD, 0, nc_ * nc_ * tinfluBspline * sizeof(double));
621 
622  // Warp->ComputeMAtWarp(tp);
623  Warp->computeCoeff(tp);
624  for (unsigned int point = 0; point < templateSize; point++) {
625  X1[0] = ptTemplate[point].x;
626  X1[1] = ptTemplate[point].y;
627 
628  Warp->computeDenom(X1, tp);
629  Warp->warpX(X1, X2, tp);
630  double j2 = X2[0];
631  double i2 = X2[1];
632 
633  // Tij=Templ[i-(int)Triangle->GetMiny()][j-(int)Triangle->GetMinx()];
634  if ((i2 >= 0) && (j2 >= 0) && (i2 < I.getHeight() - 1) && (j2 < I.getWidth()) - 1) {
635  Nbpoint++;
636 
637  double Tij = ptTemplate[point].val;
638  if (!blur)
639  IW = I.getValue(i2, j2);
640  else
641  IW = GaussI.getValue(i2, j2);
642 
643  int cr = static_cast<int>((IW * (nc - 1)) / 255.);
644  int ct = static_cast<int>((Tij * (nc - 1)) / 255.);
645  double er = (IW * (nc - 1)) / 255. - cr;
646  double et = (Tij * (nc - 1)) / 255. - ct;
647 
648  // Calcul de l'histogramme joint par interpolation bilineaire (Bspline_
649  // ordre 1)
650  vpTemplateTrackerMIBSpline::PutPVBsplineD(tPrtD, cr, er, ct, et, nc, 1., bspline_);
651  }
652  }
653  double *pt = tPrtD;
654  int tNcb_ = (int)tNcb;
655  int tinfluBspline_ = (int)tinfluBspline;
656  for (int r = 0; r < nc; r++)
657  for (int t = 0; t < nc; t++) {
658  for (volatile int i = 0; i < tinfluBspline_; i++) {
659  int r2, t2;
660  r2 = r + i / bspline_;
661  t2 = t + i % bspline_;
662  tPrt[r2 * tNcb_ + t2] += *pt;
663 
664  pt++;
665  }
666  }
667 
668  if (Nbpoint == 0) {
669  delete[] tPrtD;
670  delete[] tPrt;
671  delete[] tPr;
672  delete[] tPt;
673 
674  return 0;
675  } else {
676  for (unsigned int r = 0; r < tNcb; r++)
677  for (unsigned int t = 0; t < tNcb; t++)
678  // printf("%f ",tPrt[r*tNcb+t]);
679  tPrt[r * tNcb + t] = tPrt[r * tNcb + t] / Nbpoint;
680  // calcul Pr;
681  memset(tPr, 0, tNcb * sizeof(double));
682  for (unsigned int r = 0; r < tNcb; r++) {
683  for (unsigned int t = 0; t < tNcb; t++)
684  tPr[r] += tPrt[r * tNcb + t];
685  }
686 
687  // calcul Pt;
688  memset(tPt, 0, (size_t)(tNcb * sizeof(double)));
689  for (unsigned int t = 0; t < tNcb; t++) {
690  for (unsigned int r = 0; r < tNcb; r++)
691  tPt[t] += tPrt[r * tNcb + t];
692  }
693  for (unsigned int r = 0; r < tNcb; r++)
694  // if(tPr[r]!=0)
695  if (std::fabs(tPr[r]) > std::numeric_limits<double>::epsilon())
696  MI -= tPr[r] * log(tPr[r]);
697 
698  for (unsigned int t = 0; t < tNcb; t++)
699  // if(tPt[t]!=0)
700  if (std::fabs(tPt[t]) > std::numeric_limits<double>::epsilon())
701  MI -= tPt[t] * log(tPt[t]);
702 
703  for (unsigned int r = 0; r < tNcb; r++)
704  for (unsigned int t = 0; t < tNcb; t++)
705  // if(tPrt[r*tNcb+t]!=0)
706  if (std::fabs(tPrt[r * tNcb + t]) > std::numeric_limits<double>::epsilon())
707  MI += tPrt[r * tNcb + t] * log(tPrt[r * tNcb + t]);
708  }
709  delete[] tPrtD;
710  delete[] tPrt;
711  delete[] tPr;
712  delete[] tPt;
713 
714  return MI;
715 }
716 
718 {
719  vpMatrix Prt256(256, 256);
720  Prt256 = 0;
721  vpColVector Pr256(256);
722  Pr256 = 0;
723  vpColVector Pt256(256);
724  Pt256 = 0;
725 
726  volatile int Nbpoint = 0;
727  unsigned int Tij, IW;
728 
729  vpImage<double> GaussI;
730  if (blur)
731  vpImageFilter::filter(I, GaussI, fgG, taillef);
732 
733  Warp->computeCoeff(tp);
734  for (unsigned int point = 0; point < templateSize; point++) {
735  X1[0] = ptTemplate[point].x;
736  X1[1] = ptTemplate[point].y;
737 
738  Warp->computeDenom(X1, tp);
739  Warp->warpX(X1, X2, tp);
740  double j2 = X2[0];
741  double i2 = X2[1];
742 
743  // Tij=Templ[i-(int)Triangle->GetMiny()][j-(int)Triangle->GetMinx()];
744  if ((i2 >= 0) && (j2 >= 0) && (i2 < I.getHeight() - 1) && (j2 < I.getWidth()) - 1) {
745  Nbpoint++;
746 
747  Tij = static_cast<unsigned int>(ptTemplate[point].val);
748  if (!blur)
749  IW = static_cast<unsigned int>(I.getValue(i2, j2));
750  else
751  IW = static_cast<unsigned int>(GaussI.getValue(i2, j2));
752 
753  Prt256[Tij][IW]++;
754  Pr256[Tij]++;
755  Pt256[IW]++;
756  }
757  }
758 
759  if (Nbpoint == 0) {
760  throw(vpException(vpException::divideByZeroError, "Cannot get MI; number of points = 0"));
761  }
762  Prt256 = Prt256 / Nbpoint;
763  Pr256 = Pr256 / Nbpoint;
764  Pt256 = Pt256 / Nbpoint;
765 
766  double MI = 0;
767 
768  for (unsigned int t = 0; t < 256; t++) {
769  for (unsigned int r = 0; r < 256; r++) {
770  // if(Prt256[r][t]!=0)
771  if (std::fabs(Prt256[r][t]) > std::numeric_limits<double>::epsilon())
772  MI += Prt256[r][t] * log(Prt256[r][t]);
773  }
774  // if(Pt256[t]!=0)
775  if (std::fabs(Pt256[t]) > std::numeric_limits<double>::epsilon())
776  MI += -Pt256[t] * log(Pt256[t]);
777  // if(Pr256[t]!=0)
778  if (std::fabs(Pr256[t]) > std::numeric_limits<double>::epsilon())
779  MI += -Pr256[t] * log(Pr256[t]);
780  }
781  return MI;
782 }
vpTemplateTrackerMI()
Default constructor.
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:164
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:305
void computeHessien(vpMatrix &H)
Type getValue(unsigned int i, unsigned int j) const
Definition: vpImage.h:1422
vpTemplateTrackerPoint * ptTemplate
virtual void warpX(const int &i, const int &j, double &i2, double &j2, const vpColVector &ParamM)=0
error that can be emited by ViSP classes.
Definition: vpException.h:71
std::vector< double > m_dv
std::vector< std::vector< double > > m_d2u
vpImage< double > d2Ix
vpImage< double > BI
std::vector< double > m_dB
vpHessienApproximationType ApproxHessian
double getMI256(const vpImage< unsigned char > &I, const vpColVector &tp)
std::vector< double > m_A
unsigned int templateSize
std::vector< std::vector< double > > m_d2v
Error that can be emited by the vpTracker class and its derivates.
double getCost(const vpImage< unsigned char > &I, const vpColVector &tp)
void computeMI(double &MI)
std::vector< double > m_du
vpImage< double > d2Iy
std::vector< std::vector< double > > m_dA
double getNormalizedCost(const vpImage< unsigned char > &I, const vpColVector &tp)
static void filter(const vpImage< double > &I, vpImage< double > &Iu, vpImage< double > &Iv, const vpMatrix &M, bool convolve=false)
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:310
unsigned int getHeight() const
Definition: vpImage.h:186
Implementation of column vector and the associated operations.
Definition: vpColVector.h:130
vpImage< double > d2Ixy
void computeHessienNormalized(vpMatrix &H)
void setBspline(const vpBsplineType &newbs)
vpTemplateTrackerWarp * Warp
unsigned int getWidth() const
Definition: vpImage.h:244
void computeProba(int &nbpoint)
vpHessienType hessianComputation