40 #include <visp3/core/vpException.h> 41 #include <visp3/tt_mi/vpTemplateTrackerMI.h> 42 #include <visp3/tt_mi/vpTemplateTrackerMIBSpline.h> 106 Pt =
new double[
Ncb];
107 Pr =
new double[
Ncb];
142 Pt =
new double[
Ncb];
143 Pr =
new double[
Ncb];
154 unsigned int Ncb_ = (
unsigned int)
Ncb;
155 unsigned int Nc_ = (
unsigned int)
Nc;
156 unsigned int influBspline_ = (
unsigned int)
influBspline;
158 memset(
Prt, 0, Ncb_ * Ncb_ *
sizeof(
double));
159 memset(
PrtD, 0, Nc_ * Nc_ * influBspline_ *
sizeof(
double));
162 Warp->computeCoeff(tp);
163 for (
unsigned int point = 0; point <
templateSize; point++) {
167 Warp->computeDenom(
X1, tp);
173 if ((i2 >= 0) && (j2 >= 0) && (i2 < I.
getHeight() - 1) && (j2 < I.
getWidth() - 1)) {
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;
192 vpTemplateTrackerMIBSpline::PutPVBsplineD(
PrtD, cr, er, ct, et,
Nc, 1.,
bspline);
199 for (
int r = 0; r <
Nc; r++)
200 for (
int t = 0; t <
Nc; t++) {
205 Prt[r2 *
Ncb + t2] += *pt;
213 for (
unsigned int r = 0; r < Ncb_; r++) {
214 for (
unsigned int t = 0; t < Ncb_; t++) {
215 Prt[r * Ncb_ + t] /= Nbpoint;
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];
228 for (
unsigned int r = 0; r < Ncb_; r++) {
230 if (std::fabs(
Pr[r]) > std::numeric_limits<double>::epsilon()) {
231 MI -=
Pr[r] * log(
Pr[r]);
233 if (std::fabs(
Pt[r]) > std::numeric_limits<double>::epsilon()) {
234 MI -=
Pt[r] * log(
Pt[r]);
236 for (
unsigned int t = 0; t < Ncb_; t++) {
237 unsigned int r_Ncb_t_ = r * Ncb_ + t;
239 if (std::fabs(
Prt[r_Ncb_t_]) > std::numeric_limits<double>::epsilon()) {
240 MI +=
Prt[r_Ncb_t_] * log(
Prt[r_Ncb_t_]);
260 double Prt_[256][256];
262 memset(Pr_, 0, 256 *
sizeof(
double));
263 memset(Pt_, 0, 256 *
sizeof(
double));
264 memset(Prt_, 0, 256 * 256 *
sizeof(
double));
266 for (
unsigned int point = 0; point <
templateSize; point++) {
270 Warp->computeDenom(
X1, tp);
275 if ((i2 >= 0) && (j2 >= 0) && (i2 < I.
getHeight() - 1) && (j2 < I.
getWidth() - 1)) {
278 int Tij_ =
static_cast<int>(Tij);
280 IW = I[(int)i2][(
int)j2];
285 int IW_ =
static_cast<int>(IW);
294 for (
int r = 0; r < 256; r++) {
297 if (std::fabs(Pr_[r]) > std::numeric_limits<double>::epsilon()) {
298 MI -= Pr_[r] * log(Pr_[r]);
300 if (std::fabs(Pt_[r]) > std::numeric_limits<double>::epsilon()) {
301 MI -= Pt_[r] * log(Pt_[r]);
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]));
311 if (std::fabs(denom) > std::numeric_limits<double>::epsilon())
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);
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++;
373 unsigned int indd, indd2;
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;
380 for (
unsigned int k = 0; k <
nbParam; k++) {
381 d2Prt[indd2] /= nbpoint;
390 unsigned int Ncb_ = (
unsigned int)
Ncb;
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];
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]);
408 if (std::fabs(
Pt[r]) > std::numeric_limits<double>::epsilon()) {
409 MI -=
Pt[r] * log(
Pt[r]);
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_]);
423 double seuilevitinf = 1e-200;
426 unsigned int Ncb_ =
static_cast<unsigned int>(
Ncb);
429 for (
unsigned int t = 0; t < Ncb_; t++) {
431 if (
Pt[t] > seuilevitinf) {
432 for (
unsigned int r = 0; r < Ncb_; r++) {
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++) {
441 dtemp = 1. + log(
Prt[r * Ncb_ + t] /
Pt[t]);
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++) {
450 d2Prt[r_Ncb_t_nbParam2_it_nbParam_ + jt] * dtemp;
452 Hessian[it][jt] +=
d2Prt[r_Ncb_t_nbParam2_it_nbParam_ + jt] * dtemp;
465 double seuilevitinf = 1e-200;
467 double u = 0, v = 0, B = 0;
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);
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);
492 memset(
dprtemp, 0, nbParam *
sizeof(
double));
494 unsigned int Ncb_ =
static_cast<unsigned int>(
Ncb);
495 unsigned int nbParam2 = nbParam *
nbParam;
497 for (
unsigned int t = 0; t < Ncb_; t++) {
499 if (
Pt[t] > seuilevitinf) {
500 for (
unsigned int r = 0; r < Ncb_; r++) {
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++) {
509 double log_Pt_Pr_ = log(
Pt[t] *
Pr[r]);
510 double log_Prt_ = log(
Prt[r_Ncb_t_]);
513 u +=
Prt[r_Ncb_t_] * log_Pt_Pr_;
515 v +=
Prt[r_Ncb_t_] * log_Prt_;
517 double log_Prt_1_ = 1 + log(
Prt[r_Ncb_t_]);
518 for (
unsigned int it = 0; it <
nbParam; it++) {
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++) {
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_;
542 for (
unsigned int it = 0; it <
nbParam; it++) {
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++) {
552 Hessian[it][jt] = (
m_dA[it][jt] * B - A_it_dB_it_) / B2;
559 double seuilevitinf = 1e-200;
561 unsigned int Ncb_ =
static_cast<unsigned int>(
Ncb);
563 for (
unsigned int t = 0; t < Ncb_; t++) {
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++) {
574 dtemp = 1. + log(
Prt[r_Ncb_t_] /
Pt[t]);
576 for (
unsigned int it = 0; it <
nbParam; it++) {
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);
591 unsigned int Ncb2_ = Ncb_ * Ncb_ *
sizeof(double);
592 unsigned int Ncb2_nbParam_ = Ncb2_ *
nbParam;
593 unsigned int Ncb2_nbParam2_ = Ncb2_nbParam_ *
nbParam;
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));
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);
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];
613 volatile int Nbpoint = 0;
619 memset(tPrt, 0, tNcb * tNcb *
sizeof(
double));
620 memset(tPrtD, 0, nc_ * nc_ * tinfluBspline *
sizeof(
double));
623 Warp->computeCoeff(tp);
624 for (
unsigned int point = 0; point <
templateSize; point++) {
628 Warp->computeDenom(
X1, tp);
634 if ((i2 >= 0) && (j2 >= 0) && (i2 < I.
getHeight() - 1) && (j2 < I.
getWidth()) - 1) {
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;
650 vpTemplateTrackerMIBSpline::PutPVBsplineD(tPrtD, cr, er, ct, et, nc, 1., bspline_);
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++) {
660 r2 = r + i / bspline_;
661 t2 = t + i % bspline_;
662 tPrt[r2 * tNcb_ + t2] += *pt;
676 for (
unsigned int r = 0; r < tNcb; r++)
677 for (
unsigned int t = 0; t < tNcb; t++)
679 tPrt[r * tNcb + t] = tPrt[r * tNcb + t] / Nbpoint;
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];
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];
693 for (
unsigned int r = 0; r < tNcb; r++)
695 if (std::fabs(tPr[r]) > std::numeric_limits<double>::epsilon())
696 MI -= tPr[r] * log(tPr[r]);
698 for (
unsigned int t = 0; t < tNcb; t++)
700 if (std::fabs(tPt[t]) > std::numeric_limits<double>::epsilon())
701 MI -= tPt[t] * log(tPt[t]);
703 for (
unsigned int r = 0; r < tNcb; r++)
704 for (
unsigned int t = 0; t < tNcb; t++)
706 if (std::fabs(tPrt[r * tNcb + t]) > std::numeric_limits<double>::epsilon())
707 MI += tPrt[r * tNcb + t] * log(tPrt[r * tNcb + t]);
726 volatile int Nbpoint = 0;
727 unsigned int Tij, IW;
733 Warp->computeCoeff(tp);
734 for (
unsigned int point = 0; point <
templateSize; point++) {
738 Warp->computeDenom(
X1, tp);
744 if ((i2 >= 0) && (j2 >= 0) && (i2 < I.
getHeight() - 1) && (j2 < I.
getWidth()) - 1) {
749 IW =
static_cast<unsigned int>(I.
getValue(i2, j2));
751 IW =
static_cast<unsigned int>(GaussI.
getValue(i2, j2));
762 Prt256 = Prt256 / Nbpoint;
763 Pr256 = Pr256 / Nbpoint;
764 Pt256 = Pt256 / Nbpoint;
768 for (
unsigned int t = 0; t < 256; t++) {
769 for (
unsigned int r = 0; r < 256; r++) {
771 if (std::fabs(Prt256[r][t]) > std::numeric_limits<double>::epsilon())
772 MI += Prt256[r][t] * log(Prt256[r][t]);
775 if (std::fabs(Pt256[t]) > std::numeric_limits<double>::epsilon())
776 MI += -Pt256[t] * log(Pt256[t]);
778 if (std::fabs(Pr256[t]) > std::numeric_limits<double>::epsilon())
779 MI += -Pr256[t] * log(Pr256[t]);
vpTemplateTrackerMI()
Default constructor.
Implementation of a matrix and operations on matrices.
double NMI_postEstimation
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
void computeHessien(vpMatrix &H)
vpMatrix covarianceMatrix
Type getValue(unsigned int i, unsigned int j) const
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.
std::vector< double > m_dv
std::vector< std::vector< double > > m_d2u
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
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)
unsigned int getHeight() const
Implementation of column vector and the associated operations.
void computeHessienNormalized(vpMatrix &H)
void setBspline(const vpBsplineType &newbs)
virtual ~vpTemplateTrackerMI()
vpTemplateTrackerWarp * Warp
unsigned int getWidth() const
void computeProba(int &nbpoint)
vpHessienType hessianComputation