Visual Servoing Platform  version 3.6.1 under development (2024-12-17)
vpTemplateTrackerWarp.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
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 https://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 
34 #include <visp3/core/vpDebug.h>
35 #include <visp3/tt/vpTemplateTrackerWarp.h>
36 
37 BEGIN_VISP_NAMESPACE
40 {
41  if (p.size() < 2) {
42  vpCTRACE << "Bad template tracker warp parameters dimension. Should "
43  "never occur. "
44  << std::endl;
45  throw(vpException(vpException::dimensionError, "Bad template tracker warp parameters dimension"));
46  }
47  vpColVector S1(2), S2(2), S3(2);
48  vpColVector rS1(2), rS2(2), rS3(2);
49  in.getCorners(S1, S2, S3);
50  computeDenom(S1, p);
51  warpX(S1, rS1, p);
52  computeDenom(S2, p);
53  warpX(S2, rS2, p);
54  computeDenom(S3, p);
55  warpX(S3, rS3, p);
56  out.init(rS1, rS2, rS3);
57 }
59 {
61  out.clear();
62  for (unsigned int i = 0; i < in.getNbTriangle(); i++) {
63  in.getTriangle(i, TR);
64  warpTriangle(TR, p, TT);
65  out.add(TT);
66  }
67 }
68 
70 {
71  unsigned int nb_corners = Z.getNbTriangle() * 3;
72  computeCoeff(p);
73  vpColVector X1(2), X2(2);
74 
75  double res = 0;
77  for (unsigned int i = 0; i < Z.getNbTriangle(); i++) {
78  Z.getTriangle(i, triangle);
79  for (unsigned int j = 0; j < 3; j++) {
80  triangle.getCorner(j, X1[0], X1[1]);
81 
82  computeDenom(X1, p);
83  warpX(X1, X2, p);
84  res += sqrt((X2[0] - X1[0]) * (X2[0] - X1[0]) + (X2[1] - X1[1]) * (X2[1] - X1[1]));
85  }
86  }
87 
88  return res / nb_corners;
89 }
90 
91 void vpTemplateTrackerWarp::warp(const double *ut0, const double *vt0, int nb_pt, const vpColVector &p, double *u,
92  double *v)
93 {
94  computeCoeff(p);
95  vpColVector X1(2), X2(2);
96  for (int i = 0; i < nb_pt; i++) {
97  X1[0] = ut0[i];
98  X1[1] = vt0[i];
99  computeDenom(X1, p);
100  warpX(X1, X2, p);
101  u[i] = X2[0];
102  v[i] = X2[1];
103  // std::cout<<"warp "<<X2[0]<<","<<X2[1]<<std::endl;
104  }
105 }
106 
107 #ifndef DOXYGEN_SHOULD_SKIP_THIS
108 void vpTemplateTrackerWarp::findWarp(const double *ut0, const double *vt0, const double *u, const double *v, int nb_pt,
109  vpColVector &p)
110 {
111  vpMatrix dW_(2, nbParam);
112  vpMatrix dX(2, 1);
114  vpMatrix G(nbParam, 1);
115 
116  int cpt = 0;
117  vpColVector X1(2);
118  vpColVector fX1(2);
119  vpColVector X2(2);
120  double erreur = 0;
121  double erreur_prec;
122  double lambda = 0.01;
123  do {
124  erreur_prec = erreur;
125  H = 0;
126  G = 0;
127  erreur = 0;
128  computeCoeff(p);
129  for (int i = 0; i < nb_pt; i++) {
130  X1[0] = ut0[i];
131  X1[1] = vt0[i];
132  computeDenom(X1, p);
133  warpX(X1, fX1, p);
134  dWarp(X1, fX1, p, dW_);
135  H += dW_.AtA();
136 
137  X2[0] = u[i];
138  X2[1] = v[i];
139 
140  dX = X2 - fX1;
141  G += dW_.t() * dX;
142 
143  erreur += ((u[i] - fX1[0]) * (u[i] - fX1[0]) + (v[i] - fX1[1]) * (v[i] - fX1[1]));
144  }
145 
146  vpMatrix::computeHLM(H, lambda, HLM);
147  try {
148  p += (vpColVector)(HLM.inverseByLU() * G, 0u);
149  }
150  catch (const vpException &e) {
151  // std::cout<<"Cannot inverse the matrix by LU " << std::endl;
152  throw(e);
153  }
154  cpt++;
155  } while ((cpt < 150) && (sqrt((erreur_prec - erreur) * (erreur_prec - erreur)) > 1e-20));
156  // std::cout<<"erreur apres transformation="<<erreur<<std::endl;
157 }
158 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
159 END_VISP_NAMESPACE
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:349
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ dimensionError
Bad dimension.
Definition: vpException.h:71
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:169
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
Definition: vpMatrix.cpp:1869
vpColVector getCorner(unsigned int i) const
void init(const vpColVector &c1, const vpColVector &c2, const vpColVector &c3)
void getCorners(vpColVector &c1, vpColVector &c2, vpColVector &c3) const
void warpTriangle(const vpTemplateTrackerTriangle &in, const vpColVector &p, vpTemplateTrackerTriangle &out)
unsigned int nbParam
Number of parameters used to model warp transformation.
virtual void dWarp(const vpColVector &X1, const vpColVector &X2, const vpColVector &p, vpMatrix &dM)=0
void warpZone(const vpTemplateTrackerZone &in, const vpColVector &p, vpTemplateTrackerZone &out)
double getDistanceBetweenZoneAndWarpedZone(const vpTemplateTrackerZone &Z, const vpColVector &p)
virtual void warpX(const int &v1, const int &u1, double &v2, double &u2, const vpColVector &p)=0
void warp(const double *ut0, const double *vt0, int nb_pt, const vpColVector &p, double *u, double *v)
void getTriangle(unsigned int i, vpTemplateTrackerTriangle &T) const
unsigned int getNbTriangle() const
void add(const vpTemplateTrackerTriangle &t)