Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
vpTemplateTrackerWarpHomographySL3.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 * Template tracker.
32 */
33
34#include <visp3/tt/vpTemplateTrackerWarpHomographySL3.h>
35
37// findWarp special a SL3 car methode additionnelle ne marche pas (la derivee
38// n est calculable qu en p=0)
39// => resout le probleme de maniere compositionnelle
50 void vpTemplateTrackerWarpHomographySL3::findWarp(const double *ut0, const double *vt0, const double *u,
51 const double *v, int nb_pt, vpColVector &p)
52{
54 vpMatrix dW_(2, nbParam);
55 vpMatrix dX(2, 1);
57 vpMatrix G_(nbParam, 1);
58
59 // vpMatrix *dW_ddp0=new vpMatrix[nb_pt];
60 double **dW_ddp0 = new double *[static_cast<unsigned int>(nb_pt)];
61 for (int i = 0; i < nb_pt; i++) {
62 // dW_ddp0[i].resize(2,nbParam);
63 dW_ddp0[i] = new double[2 * nbParam];
64 // getdWdp0(vt0[i],ut0[i],dW_ddp0[i]);
65 // std::cout<<"findWarp"<<v[i]<<","<<u[i]<<std::endl;
66 getdWdp0(v[i], u[i], dW_ddp0[i]);
67 }
68
69 int cpt = 0;
70 vpColVector X1(2);
71 vpColVector fX1(2);
72 vpColVector X2(2);
73 double erreur = 0;
74 double erreur_prec;
75 double lambda = 0.00001;
76 do {
77 erreur_prec = erreur;
78 H = 0;
79 G_ = 0;
80 erreur = 0;
81 computeCoeff(p);
82 for (int i = 0; i < nb_pt; i++) {
83 X1[0] = ut0[i];
84 X1[1] = vt0[i];
85 computeDenom(X1, p);
86 warpX(X1, fX1, p);
87 // dWarpCompo(X1,fX1,p,dW_ddp0[i],dW);
88 // dWarp(X1,fX1,p,dW);
89 for (unsigned int ip = 0; ip < nbParam; ip++) {
90 dW_[0][ip] = dW_ddp0[i][ip];
91 dW_[1][ip] = dW_ddp0[i][ip + nbParam];
92 }
93
94 H += dW_.AtA();
95
96 X2[0] = u[i];
97 X2[1] = v[i];
98
99 dX = X2 - fX1;
100 G_ += dW_.t() * dX;
101
102 erreur += ((u[i] - fX1[0]) * (u[i] - fX1[0]) + (v[i] - fX1[1]) * (v[i] - fX1[1]));
103 }
104
105 vpMatrix::computeHLM(H, lambda, HLM);
106 try {
107 dp = HLM.inverseByLU() * G_;
108 }
109 catch (const vpException &e) {
110 // std::cout<<"Cannot inverse the matrix by LU "<<std::endl;
111 throw(e);
112 }
113 pRondp(p, dp, p);
114
115 cpt++;
116 // std::cout<<"erreur ="<<erreur<<std::endl;
117 }
118 // while((cpt<1500));
119 while ((cpt < 150) && (sqrt((erreur_prec - erreur) * (erreur_prec - erreur)) > 1e-20));
120
121 // std::cout<<"erreur apres transformation="<<erreur<<std::endl;
122 for (int i = 0; i < nb_pt; i++)
123 delete[] dW_ddp0[i];
124 delete[] dW_ddp0;
125}
126
131{
132 nbParam = 8;
133 G.resize(3, 3);
134 dGx.resize(3, nbParam);
135
136 A.resize(8);
137 for (unsigned int i = 0; i < 8; i++) {
138 A[i].resize(3, 3);
139 A[i] = 0;
140 }
141 A[0][0][2] = 1;
142 A[1][1][2] = 1;
143 A[2][0][1] = 1;
144 A[3][1][0] = 1;
145 A[4][0][0] = 1;
146 A[4][1][1] = -1;
147 A[5][1][1] = -1;
148 A[5][2][2] = 1;
149 A[6][2][0] = 1;
150 A[7][2][1] = 1;
151}
152
153// get the parameter corresponding to the lower level of a gaussian pyramid
154// a refaire de facon analytique
162{
163 double *u, *v;
164 u = new double[4];
165 v = new double[4];
166 // u[0]=0;v[0]=0;u[1]=640;v[1]=0;u[2]=640;v[2]=480;u[3]=0;v[3]=480;
167 u[0] = 0;
168 v[0] = 0;
169 u[1] = 160;
170 v[1] = 0;
171 u[2] = 160;
172 v[2] = 120;
173 u[3] = 0;
174 v[3] = 120;
175 double *u2, *v2;
176 u2 = new double[4];
177 v2 = new double[4];
178 warp(u, v, 4, p, u2, v2);
179 // p=0;findWarp(u,v,u2,v2,4,p);
180 for (int i = 0; i < 4; i++) {
181 u[i] = u[i] / 2.;
182 v[i] = v[i] / 2.;
183 u2[i] = u2[i] / 2.;
184 v2[i] = v2[i] / 2.;
185 // std::cout<<"recherche "<<u2[i]<<","<<v2[i]<<std::endl;
186 }
187 p_down = p;
188 findWarp(u, v, u2, v2, 4, p_down);
189 delete[] u;
190 delete[] v;
191 delete[] u2;
192 delete[] v2;
193}
194
202{
203 double *u, *v;
204 u = new double[4];
205 v = new double[4];
206 // u[0]=0;v[0]=0;u[1]=640;v[1]=0;u[2]=640;v[2]=480;u[3]=0;v[3]=480;
207 u[0] = 0;
208 v[0] = 0;
209 u[1] = 160;
210 v[1] = 0;
211 u[2] = 160;
212 v[2] = 120;
213 u[3] = 0;
214 v[3] = 120;
215 // u[0]=40;v[0]=30;u[1]=160;v[1]=30;u[2]=160;v[2]=120;u[3]=40;v[3]=120;
216 double *u2, *v2;
217 u2 = new double[4];
218 v2 = new double[4];
219
220 // p_up=p;
221
222 /*vpColVector ptest=pup;
223 warp(u,v,4,ptest,u2,v2);
224 for(int i=0;i<4;i++)
225 std::cout<<"test "<<u2[i]<<","<<v2[i]<<std::endl;*/
226
227 warp(u, v, 4, p, u2, v2);
228 // p=0;findWarp(u,v,u2,v2,4,p);
229
230 for (int i = 0; i < 4; i++) {
231 u[i] = u[i] * 2.;
232 v[i] = v[i] * 2.;
233 u2[i] = u2[i] * 2.;
234 v2[i] = v2[i] * 2.;
235 /*std::cout<<"#########################################################################################"<<std::endl;
236 std::cout<<"#########################################################################################"<<std::endl;
237 std::cout<<"#########################################################################################"<<std::endl;
238 std::cout<<"recherche "<<u2[i]<<","<<v2[i]<<std::endl;*/
239 }
240 findWarp(u, v, u2, v2, 4, p_up);
241
242 delete[] u;
243 delete[] v;
244 delete[] u2;
245 delete[] v2;
246}
247
257{
258 denom = X[0] * G[2][0] + X[1] * G[2][1] + G[2][2];
259}
260
267{
268 vpMatrix pA(3, 3);
269 pA[0][0] = p[4];
270 pA[0][1] = p[2];
271 pA[0][2] = p[0];
272
273 pA[1][0] = p[3];
274 pA[1][1] = -p[4] - p[5];
275 pA[1][2] = p[1];
276
277 pA[2][0] = p[6];
278 pA[2][1] = p[7];
279 pA[2][2] = p[5];
280
281 G = pA.expm();
282}
283
293{
294 double u = X1[0], v = X1[1];
295 X2[0] = (u * G[0][0] + v * G[0][1] + G[0][2]) / denom;
296 X2[1] = (u * G[1][0] + v * G[1][1] + G[1][2]) / denom;
297}
298
309void vpTemplateTrackerWarpHomographySL3::warpX(const int &v1, const int &u1, double &v2, double &u2,
310 const vpColVector &)
311{
312 u2 = (u1 * G[0][0] + v1 * G[0][1] + G[0][2]) / denom;
313 v2 = (u1 * G[1][0] + v1 * G[1][1] + G[1][2]) / denom;
314}
315
321{
322 vpHomography H;
323 for (unsigned int i = 0; i < 3; i++)
324 for (unsigned int j = 0; j < 3; j++)
325 H[i][j] = G[i][j];
326 return H;
327}
328
343 vpMatrix &dM)
344{
345 vpMatrix dhdx(2, 3);
346 dhdx = 0;
347 dhdx[0][0] = 1. / denom;
348 dhdx[1][1] = 1. / denom;
349 dhdx[0][2] = -X2[0] / (denom);
350 dhdx[1][2] = -X2[1] / (denom);
351 dGx = 0;
352 for (unsigned int i = 0; i < 3; i++) {
353 dGx[i][0] = G[i][0];
354 dGx[i][1] = G[i][1];
355 dGx[i][2] = G[i][0] * X1[1];
356 dGx[i][3] = G[i][1] * X1[0];
357 dGx[i][4] = G[i][0] * X1[0] - G[i][1] * X1[1];
358 dGx[i][5] = G[i][2] - G[i][1] * X1[1];
359 dGx[i][6] = G[i][2] * X1[0];
360 dGx[i][7] = G[i][2] * X1[1];
361 }
362 dM = dhdx * dGx;
363}
364
373void vpTemplateTrackerWarpHomographySL3::getdW0(const int &v, const int &u, const double &dv, const double &du,
374 double *dIdW)
375{
376 vpMatrix dhdx(1, 3);
377 dhdx = 0;
378 dhdx[0][0] = du;
379 dhdx[0][1] = dv;
380 dhdx[0][2] = -u * du - v * dv;
381 G.eye();
382
383 dGx = 0;
384 for (unsigned int par = 0; par < 3; par++) {
385 dGx[par][0] = G[par][0];
386 dGx[par][1] = G[par][1];
387 dGx[par][2] = G[par][0] * v;
388 dGx[par][3] = G[par][1] * u;
389 dGx[par][4] = G[par][0] * u - G[par][1] * v;
390 dGx[par][5] = G[par][2] - G[par][1] * v;
391 dGx[par][6] = G[par][2] * u;
392 dGx[par][7] = G[par][2] * v;
393 }
394
395 for (unsigned int par = 0; par < nbParam; par++) {
396 double res = 0;
397 for (unsigned int par2 = 0; par2 < 3; par2++)
398 res += dhdx[0][par2] * dGx[par2][par];
399 dIdW[par] = res;
400 }
401}
402
413void vpTemplateTrackerWarpHomographySL3::getdWdp0(const int &v, const int &u, double *dIdW)
414{
415 vpMatrix dhdx(2, 3);
416 dhdx = 0;
417 dhdx[0][0] = 1.;
418 dhdx[1][1] = 1.;
419 dhdx[0][2] = -u;
420 dhdx[1][2] = -v;
421 G.eye();
422
423 dGx = 0;
424 for (unsigned int par = 0; par < 3; par++) {
425 dGx[par][0] = G[par][0];
426 dGx[par][1] = G[par][1];
427 dGx[par][2] = G[par][0] * v;
428 dGx[par][3] = G[par][1] * u;
429 dGx[par][4] = G[par][0] * u - G[par][1] * v;
430 dGx[par][5] = G[par][2] - G[par][1] * v;
431 dGx[par][6] = G[par][2] * u;
432 dGx[par][7] = G[par][2] * v;
433 }
434 vpMatrix dIdW_temp(2, nbParam);
435 dIdW_temp = dhdx * dGx;
436
437 for (unsigned int par = 0; par < nbParam; par++) {
438 dIdW[par] = dIdW_temp[0][par];
439 dIdW[par + nbParam] = dIdW_temp[1][par];
440 }
441}
442
454void vpTemplateTrackerWarpHomographySL3::getdWdp0(const double &v, const double &u, double *dIdW)
455{
456 vpMatrix dhdx(2, 3);
457 dhdx = 0;
458 dhdx[0][0] = 1.;
459 dhdx[1][1] = 1.;
460 dhdx[0][2] = -u;
461 dhdx[1][2] = -v;
462 G.eye();
463
464 dGx = 0;
465 for (unsigned int par = 0; par < 3; par++) {
466 dGx[par][0] = G[par][0];
467 dGx[par][1] = G[par][1];
468 dGx[par][2] = G[par][0] * v;
469 dGx[par][3] = G[par][1] * u;
470 dGx[par][4] = G[par][0] * u - G[par][1] * v;
471 dGx[par][5] = G[par][2] - G[par][1] * v;
472 dGx[par][6] = G[par][2] * u;
473 dGx[par][7] = G[par][2] * v;
474 }
475 vpMatrix dIdW_temp(2, nbParam);
476 dIdW_temp = dhdx * dGx;
477
478 for (unsigned int par = 0; par < nbParam; par++) {
479 dIdW[par] = dIdW_temp[0][par];
480 dIdW[par + nbParam] = dIdW_temp[1][par];
481 }
482}
483
494
496 const double *dwdp0, vpMatrix &dM)
497{
498 for (unsigned int i = 0; i < nbParam; i++) {
499 dM[0][i] = denom * ((G[0][0] - X[0] * G[2][0]) * dwdp0[i] + (G[0][1] - X[0] * G[2][1]) * dwdp0[i + nbParam]);
500 dM[1][i] = denom * ((G[1][0] - X[1] * G[2][0]) * dwdp0[i] + (G[1][1] - X[1] * G[2][1]) * dwdp0[i + nbParam]);
501 }
502}
503
511
521{
522 // vrai que si commutatif ...
523 p12 = p1 + p2;
524}
525END_VISP_NAMESPACE
Implementation of column vector and the associated operations.
error that can be emitted by ViSP classes.
Definition vpException.h:60
Implementation of an homography and operations on homographies.
Implementation of a matrix and operations on matrices.
Definition vpMatrix.h:175
vpMatrix expm() const
vpMatrix inverseByLU() const
vpMatrix AtA() const
static void computeHLM(const vpMatrix &H, const double &alpha, vpMatrix &HLM)
vpMatrix t() const
void getdW0(const int &v, const int &u, const double &dv, const double &du, double *dIdW)
void computeDenom(vpColVector &X, const vpColVector &)
void warpX(const vpColVector &X1, vpColVector &X2, const vpColVector &)
void pRondp(const vpColVector &p1, const vpColVector &p2, vpColVector &p12) const
void dWarpCompo(const vpColVector &, const vpColVector &X, const vpColVector &, const double *dwdp0, vpMatrix &dW)
void getParamPyramidDown(const vpColVector &p, vpColVector &p_down)
void findWarp(const double *ut0, const double *vt0, const double *u, const double *v, int nb_pt, vpColVector &p)
void getdWdp0(const int &v, const int &u, double *dIdW)
void getParamInverse(const vpColVector &p, vpColVector &p_inv) const
void dWarp(const vpColVector &X1, const vpColVector &X2, const vpColVector &, vpMatrix &dW)
void getParamPyramidUp(const vpColVector &p, vpColVector &p_up)
unsigned int nbParam
Number of parameters used to model warp transformation.
double denom
Internal value used by homography warp model.
void warp(const double *ut0, const double *vt0, int nb_pt, const vpColVector &p, double *u, double *v)