Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpTemplateTrackerMIForwardAdditional.cpp
1/*
2 * ViSP, open source Visual Servoing Platform software.
3 * Copyright (C) 2005 - 2025 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 * Example of template tracking.
32 *
33 * Authors:
34 * Amaury Dame
35 * Aurelien Yol
36 */
37
38#include <visp3/tt_mi/vpTemplateTrackerMIForwardAdditional.h>
39
40#ifdef VISP_HAVE_OPENMP
41#include <omp.h>
42#endif
43
46 : vpTemplateTrackerMI(_warp), minimizationMethod(USE_NEWTON), p_prec(), G_prec(), KQuasiNewton()
47{
48 useCompositionnal = false;
49}
50
52{
53 dW = 0;
54
55 int Nbpoint = 0;
56
57 if (blur)
61
62 double Tij;
63 double IW, dx, dy;
64 int cr, ct;
65 double er, et;
66
67 Nbpoint = 0;
68
70 Warp->computeCoeff(p);
71 for (unsigned int point = 0; point < templateSize; point++) {
72 int i = ptTemplate[point].y;
73 int j = ptTemplate[point].x;
74 X1[0] = j;
75 X1[1] = i;
76 X2[0] = j;
77 X2[1] = i;
78
79 Warp->computeDenom(X1, p);
80 Warp->warpX(X1, X2, p);
81
82 double j2 = X2[0];
83 double i2 = X2[1];
84
85 if ((i2 >= 0) && (j2 >= 0) && (i2 < I.getHeight() - 1) && (j2 < I.getWidth() - 1)) {
86 Nbpoint++;
87 Tij = ptTemplate[point].val;
88 if (!blur)
89 IW = I.getValue(i2, j2);
90 else
91 IW = BI.getValue(i2, j2);
92
93 dx = dIx.getValue(i2, j2) * (Nc - 1) / 255.;
94 dy = dIy.getValue(i2, j2) * (Nc - 1) / 255.;
95
96 ct = static_cast<int>((IW * (Nc - 1)) / 255.);
97 cr = static_cast<int>((Tij * (Nc - 1)) / 255.);
98 et = (IW * (Nc - 1)) / 255. - ct;
99 er = (static_cast<double>(Tij) * (Nc - 1)) / 255. - cr;
100 Warp->dWarp(X1, X2, p, dW);
101
102 double *tptemp = new double[nbParam];
103 for (unsigned int it = 0; it < nbParam; it++)
104 tptemp[it] = dW[0][it] * dx + dW[1][it] * dy;
105
107 vpTemplateTrackerMIBSpline::PutTotPVBsplineNoSecond(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam, bspline);
109 vpTemplateTrackerMIBSpline::PutTotPVBspline(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam, bspline);
110
111 delete[] tptemp;
112 }
113 }
114
115 if (Nbpoint > 0) {
116 double MI;
117 computeProba(Nbpoint);
118 computeMI(MI);
120
122 try {
123 HLMdesireInverse = HLMdesire.inverseByLU();
124 }
125 catch (const vpException &e) {
126 throw(e);
127 }
128 }
129}
130
132{
133 dW = 0;
134
135 int Nbpoint = 0;
136 if (blur)
140
141 double MI = 0, MIprec = -1000;
142
144
145 double alpha = 2.;
146
147 unsigned int iteration = 0;
148
150 double evolRMS_init = 0;
151 double evolRMS_prec = 0;
152 double evolRMS_delta;
153
154 do {
155 if (iteration % 5 == 0)
157 Nbpoint = 0;
158 MIprec = MI;
159 MI = 0;
160 // erreur=0;
161
163
164 Warp->computeCoeff(p);
165#ifdef VISP_HAVE_OPENMP
166 int nthreads = omp_get_num_procs();
167 // std::cout << "file: " __FILE__ << " line: " << __LINE__ << " function:
168 // " << __FUNCTION__ << " nthread: " << nthreads << std::endl;
169 omp_set_num_threads(nthreads);
170#pragma omp parallel for default(shared)
171#endif
172 for (int point = 0; point < static_cast<int>(templateSize); point++) {
173 int i = ptTemplate[point].y;
174 int j = ptTemplate[point].x;
175 X1[0] = j;
176 X1[1] = i;
177
178 Warp->computeDenom(X1, p);
179 Warp->warpX(X1, X2, p);
180
181 double j2 = X2[0];
182 double i2 = X2[1];
183
184 if ((i2 >= 0) && (j2 >= 0) && (i2 < I.getHeight() - 1) && (j2 < I.getWidth() - 1)) {
185 Nbpoint++;
186 double Tij = ptTemplate[point].val;
187 double IW;
188 if (!blur)
189 IW = I.getValue(i2, j2);
190 else
191 IW = BI.getValue(i2, j2);
192
193 double dx = dIx.getValue(i2, j2) * (Nc - 1) / 255.;
194 double dy = dIy.getValue(i2, j2) * (Nc - 1) / 255.;
195
196 int ct = static_cast<int>((IW * (Nc - 1)) / 255.);
197 int cr = static_cast<int>((Tij * (Nc - 1)) / 255.);
198 double et = (IW * (Nc - 1)) / 255. - ct;
199 double er = (static_cast<double>(Tij) * (Nc - 1)) / 255. - cr;
200
201 Warp->dWarp(X1, X2, p, dW);
202
203 double *tptemp = new double[nbParam];
204 for (unsigned int it = 0; it < nbParam; it++)
205 tptemp[it] = (dW[0][it] * dx + dW[1][it] * dy);
207 vpTemplateTrackerMIBSpline::PutTotPVBsplineNoSecond(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam, bspline);
209 vpTemplateTrackerMIBSpline::PutTotPVBspline(PrtTout, cr, er, ct, et, Nc, tptemp, nbParam, bspline);
210
211 delete[] tptemp;
212 }
213 }
214
215 if (Nbpoint == 0) {
216 diverge = true;
217 MI = 0;
218 throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template"));
219 }
220 else {
221 computeProba(Nbpoint);
222 computeMI(MI);
225
227 try {
228 switch (hessianComputation) {
231 break;
233 if (HLM.cond() > HLMdesire.cond())
235 else
236 dp = gain * 0.2 * HLM.inverseByLU() * G;
237 break;
238 default:
239 dp = gain * 0.2 * HLM.inverseByLU() * G;
240 break;
241 }
242 }
243 catch (const vpException &e) {
244 throw(e);
245 }
246 }
247
248 switch (minimizationMethod) {
250 vpColVector p_test_LMA(nbParam);
252 p_test_LMA = p - 100000.1 * dp;
253 else
254 p_test_LMA = p + dp;
255 MI = -getCost(I, p);
256 double MI_LMA = -getCost(I, p_test_LMA);
257 if (MI_LMA > MI) {
258 p = p_test_LMA;
259 lambda = (lambda / 10. < 1e-6) ? lambda / 10. : 1e-6;
260 }
261 else {
262 lambda = (lambda * 10. < 1e6) ? 1e6 : lambda * 10.;
263 }
264 } break;
266 dp = -gain * 6.0 * G;
267 if (useBrent) {
268 alpha = 2.;
269 computeOptimalBrentGain(I, p, -MI, dp, alpha);
270 dp = alpha * dp;
271 }
272 p += dp;
273 break;
274 }
275
277 if (iterationGlobale != 0) {
278 vpColVector s_quasi = p - p_prec;
279 vpColVector y_quasi = G - G_prec;
280 double s_scal_y = s_quasi.t() * y_quasi;
281 if (std::fabs(s_scal_y) > std::numeric_limits<double>::epsilon()) {
282 KQuasiNewton = KQuasiNewton + 0.001 * (s_quasi * s_quasi.t() / s_scal_y -
283 KQuasiNewton * y_quasi * y_quasi.t() * KQuasiNewton /
284 (y_quasi.t() * KQuasiNewton * y_quasi));
285 }
286 }
287 dp = -KQuasiNewton * G;
288 p_prec = p;
289 G_prec = G;
290 p -= 1.01 * dp;
291 } break;
292
293 default: {
295 dp = -0.1 * dp;
296 if (useBrent) {
297 alpha = 2.;
298 computeOptimalBrentGain(I, p, -MI, dp, alpha);
299 dp = alpha * dp;
300 }
301
302 p += dp;
303 break;
304 }
305 }
306
308
309 if (iteration == 0) {
310 evolRMS_init = evolRMS;
311 }
312 iteration++;
314
315 evolRMS_delta = std::fabs(evolRMS - evolRMS_prec);
316 evolRMS_prec = evolRMS;
317
318 } while ((std::fabs(MI - MIprec) > std::fabs(MI) * std::numeric_limits<double>::epsilon()) &&
319 (iteration < iterationMax) && (evolRMS_delta > std::fabs(evolRMS_init) * evolRMS_eps));
320
321 if (Nbpoint == 0) {
322 throw(vpTrackingException(vpTrackingException::notEnoughPointError, "No points in the template"));
323 }
324
325 nbIteration = iteration;
329 }
330}
331END_VISP_NAMESPACE
Implementation of column vector and the associated operations.
vpRowVector t() const
error that can be emitted by ViSP classes.
Definition vpException.h:60
static void getGradXGauss2D(const vpImage< ImageType > &I, vpImage< FilterType > &dIx, const FilterType *gaussianKernel, const FilterType *gaussianDerivativeKernel, unsigned int size, const vpImage< bool > *p_mask=nullptr)
static void filter(const vpImage< ImageType > &I, vpImage< FilterType > &If, const vpArray2D< FilterType > &M, bool convolve=false, const vpImage< bool > *p_mask=nullptr)
static void getGradYGauss2D(const vpImage< ImageType > &I, vpImage< FilterType > &dIy, const FilterType *gaussianKernel, const FilterType *gaussianDerivativeKernel, unsigned int size, const vpImage< bool > *p_mask=nullptr)
Definition of the vpImage class member functions.
Definition vpImage.h:131
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
void initHessienDesired(const vpImage< unsigned char > &I)
vpHessienApproximationType ApproxHessian
vpHessienType hessianComputation
double getCost(const vpImage< unsigned char > &I, const vpColVector &tp) VP_OVERRIDE
void computeProba(int &nbpoint)
void computeHessien(vpMatrix &H)
vpTemplateTrackerMI(const vpTemplateTrackerMI &)=delete
vpImage< double > dIx
vpImage< double > dIy
void computeEvalRMS(const vpColVector &p)
void computeOptimalBrentGain(const vpImage< unsigned char > &I, vpColVector &tp, double tMI, vpColVector &direction, double &alpha)
unsigned int iterationMax
void initPosEvalRMS(const vpColVector &p)
vpTemplateTrackerPoint * ptTemplate
vpTemplateTrackerWarp * Warp
unsigned int iterationGlobale
vpImage< double > BI
unsigned int templateSize
Error that can be emitted by the vpTracker class and its derivatives.
@ notEnoughPointError
Not enough point to track.