rpp.cpp
Go to the documentation of this file.
1 /* ========================================================================
2  * PROJECT: ARToolKitPlus
3  * ========================================================================
4  *
5  * The robust pose estimator algorithm has been provided by G. Schweighofer
6  * and A. Pinz (Inst.of El.Measurement and Measurement Signal Processing,
7  * Graz University of Technology). Details about the algorithm are given in
8  * a Technical Report: TR-EMT-2005-01, available at:
9  * http://www.emt.tu-graz.ac.at/publications/index.htm
10  *
11  * Ported from MATLAB to C by T.Pintaric (Vienna University of Technology).
12  *
13  * Copyright of the derived and new portions of this work
14  * (C) 2006 Graz University of Technology
15  *
16  * This framework is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 2 of the License, or
19  * (at your option) any later version.
20  *
21  * This framework is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  * You should have received a copy of the GNU General Public License
27  * along with this framework; if not, write to the Free Software
28  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29  *
30  * For further information please contact
31  * Dieter Schmalstieg
32  * <schmalstieg@icg.tu-graz.ac.at>
33  * Graz University of Technology,
34  * Institut for Computer Graphics and Vision,
35  * Inffeldgasse 16a, 8010 Graz, Austria.
36  * ========================================================================
37  ** @author Thomas Pintaric
38  *
39  * $Id: rpp.cpp 162 2006-04-19 21:28:10Z grabner $
40  * @file
41  * ======================================================================== */
42 
43 
44 #ifndef _NO_LIBRPP_
45 
46 
47 #include <vector>
48 #include <cstring>
49 #include "assert.h"
50 
51 #include "rpp.h"
52 #include "rpp_const.h"
53 #include "rpp_vecmat.h"
54 
55 namespace rpp {
56 
57 // ===========================================================================================
58 void Quaternion_byAngleAndVector(quat_t &Q, const real_t &q_angle, const vec3_t &q_vector)
59 {
60  vec3_t rotation_axis;
61  normRv(rotation_axis, q_vector);
62  real_t f = _sin(q_angle/2.0f);
63  vec3_copy(Q.v,rotation_axis);
64  vec3_mult(Q.v,f);
65  Q.s = _cos(q_angle/2.0f);
66  quat_mult(Q, 1.0f / quat_norm(Q));
67 }
68 
69 // ===========================================================================================
70 
71 void GetRotationbyVector(mat33_t &R, const vec3_t &v1, const vec3_t &v2)
72 {
73  real_t winkel = _acos(vec3_dot(v1,v2));
74  quat_t QU;
75  vec3_t vc;
76  vec3_cross(vc,v2,v1);
77  Quaternion_byAngleAndVector(QU,winkel,vc);
78  mat33_from_quat(R,QU);
79 }
80 
81 // ===========================================================================================
82 void xform(vec3_array &Q, const vec3_array &P, const mat33_t &R, const vec3_t &t)
83 {
84  const unsigned int n = (unsigned int) P.size();
85  for(unsigned int i=0; i<n; i++)
86  {
87  vec3_mult(Q.at(i),R,P.at(i));
88  vec3_add(Q.at(i),t);
89  }
90 }
91 // ===========================================================================================
92 
93 void xformproj(vec3_array &Qp, const vec3_array &P, const mat33_t &R, const vec3_t &t)
94 {
95  const unsigned int n = (unsigned int) P.size();
96  vec3_array Q;
97  Q.resize(n);
98 
99  for(unsigned int i=0; i<n; i++)
100  {
101  vec3_mult(Q.at(i),R,P.at(i));
102  vec3_add(Q.at(i),t);
103  Qp.at(i).v[0] = Q.at(i).v[0] / Q.at(i).v[2];
104  Qp.at(i).v[1] = Q.at(i).v[1] / Q.at(i).v[2];
105  Qp.at(i).v[2] = 1.0;
106  }
107 }
108 
109 // ===========================================================================================
110 void rpyMat(mat33_t &R, const vec3_t &rpy) // rpy: roll,pitch,yaw
111 {
112  const real_t cosA = _cos(rpy.v[2]);
113  const real_t sinA = _sin(rpy.v[2]);
114  const real_t cosB = _cos(rpy.v[1]);
115  const real_t sinB = _sin(rpy.v[1]);
116  const real_t cosC = _cos(rpy.v[0]);
117  const real_t sinC = _sin(rpy.v[0]);
118  const real_t cosAsinB = cosA * sinB;
119  const real_t sinAsinB = sinA * sinB;
120 
121  R.m[0][0] = cosA*cosB;
122  R.m[0][1] = cosAsinB*sinC-sinA*cosC;
123  R.m[0][2] = cosAsinB*cosC+sinA*sinC;
124 
125  R.m[1][0] = sinA*cosB;
126  R.m[1][1] = sinAsinB*sinC+cosA*cosC;
127  R.m[1][2] = sinAsinB*cosC-cosA*sinC;
128 
129  R.m[2][0] = -sinB;
130  R.m[2][1] = cosB*sinC;
131  R.m[2][2] = cosB*cosC;
132 }
133 // ===========================================================================================
134 void rpyAng(vec3_t &angs, const mat33_t &R)
135 {
136  const real_t sinB = -(R.m[2][0]);
137  const real_t cosB = _sqrt(R.m[0][0]*R.m[0][0] + R.m[1][0]*R.m[1][0]);
138 
139  if(_abs(cosB) > real_t(1E-15))
140  {
141  const real_t sinA = R.m[1][0] / cosB;
142  const real_t cosA = R.m[0][0] / cosB;
143  const real_t sinC = R.m[2][1] / cosB;
144  const real_t cosC = R.m[2][2] / cosB;
145  vec3_assign(angs,_atan2(sinC,cosC),_atan2(sinB,cosB),_atan2(sinA,cosA));
146  }
147  else
148  {
149  const real_t sinC = (R.m[0][1] - R.m[1][2]) / 2.0f;
150  const real_t cosC = (R.m[1][1] - R.m[0][2]) / 2.0f;
151  vec3_assign(angs,_atan2(sinC,cosC),CONST_PI_OVER_2, 0.0f);
152  }
153 }
154 
155 // ===========================================================================================
156 
157 void rpyAng_X(vec3_t &ang_zyx, const mat33_t &R)
158 {
159  rpyAng(ang_zyx,R);
160 
161  if(_abs(ang_zyx.v[0]) > CONST_PI_OVER_2)
162  {
163  while(_abs(ang_zyx.v[0]) > CONST_PI_OVER_2)
164  {
165  if(ang_zyx.v[0] > 0)
166  {
167  vec3_assign(ang_zyx, ang_zyx.v[0]+CONST_PI,
168  3*CONST_PI-ang_zyx.v[1],
169  ang_zyx.v[2]+CONST_PI);
170  vec3_sub(ang_zyx,CONST_2_PI);
171  }
172  else
173  {
174  vec3_assign(ang_zyx, ang_zyx.v[0]+CONST_PI,
175  3*CONST_PI-ang_zyx.v[1],
176  ang_zyx.v[2]+CONST_PI);
177  }
178  }
179  }
180 }
181 
182 // ===========================================================================================
183 void decomposeR(mat33_t &Rz, const mat33_t &R)
184 {
185  real_t cl = _atan2(R.m[2][1],R.m[2][0]);
186  vec3_t rpy;
187  vec3_assign(rpy,0,0,cl);
188  rpyMat(Rz,rpy);
189 }
190 
191 // ===========================================================================================
192 void abskernel(mat33_t &R, vec3_t &t, vec3_array &Qout, real_t &err2,
193  const vec3_array _P, const vec3_array _Q,
194  const mat33_array F, const mat33_t G)
195 
196 {
197  unsigned i,j;
198 
199  vec3_array P(_P.begin(),_P.end());
200  vec3_array Q(_Q.begin(),_Q.end());
201  const unsigned int n = (unsigned int) P.size();
202 
203  for(i=0; i<n; i++)
204  {
205  vec3_t _q;
206  vec3_mult(_q,F.at(i),_Q.at(i));
207  vec3_copy(Q.at(i),_q);
208  }
209 
210  vec3_t pbar;
211  vec3_array_sum(pbar,P);
212  vec3_div(pbar,real_t(n));
213  vec3_array_sub(P,pbar);
214 
215  vec3_t qbar;
216  vec3_array_sum(qbar,Q);
217  vec3_div(qbar,real_t(n));
218  vec3_array_sub(Q,qbar);
219 
220  mat33_t M;
221  mat33_clear(M);
222  for(j=0; j<n; j++)
223  {
224  mat33_t _m;
225  vec3_mul_vec3trans(_m,P.at(j),Q.at(j));
226  mat33_add(M,_m);
227  }
228 
229  mat33_t _U;
230  mat33_t _S;
231  mat33_t _V;
232  mat33_clear(_U);
233  mat33_clear(_S);
234  mat33_clear(_V);
235  mat33_svd2(_U,_S,_V,M);
236 
237  mat33_t _Ut;
238  mat33_transpose(_Ut,_U);
239  mat33_mult(R,_V,_Ut);
240 
241  vec3_t _sum;
242  vec3_clear(_sum);
243  for(i=0; i<n; i++)
244  {
245  vec3_t _v1,_v2;
246  vec3_mult(_v1,R,P.at(i));
247  vec3_mult(_v2,F.at(i),_v1);
248  vec3_add(_sum,_v2);
249  }
250 
251  vec3_mult(t,G,_sum);
252  xform(Qout,P,R,t);
253  err2 = 0;
254  for(i=0; i<n; i++)
255  {
256  mat33_t _m1;
257  vec3_t _v1;
258  mat33_eye(_m1);
259  mat33_sub(_m1,F.at(i));
260  vec3_mult(_v1,_m1,Qout.at(i));
261  err2 += vec3_dot(_v1,_v1);
262  }
263 }
264 // ===========================================================================================
265 
266 void objpose(mat33_t &R, vec3_t &t, unsigned int &it, real_t &obj_err, real_t &img_err,
267  bool calc_img_err, const vec3_array _P, const vec3_array Qp, const options_t options)
268 {
269  unsigned int i,j;
270  vec3_array P(_P.begin(),_P.end());
271 
272  const unsigned int n = (unsigned int) P.size();
273  vec3_t pbar;
274  vec3_array_sum(pbar,P);
275  vec3_div(pbar,real_t(n));
276  vec3_array_sub(P,pbar);
277  vec3_array Q(Qp.begin(),Qp.end());
278  vec3_t ones;
279  ones.v[0] = 1;
280  ones.v[1] = 1;
281  ones.v[2] = 1;
282  const bool mask_z[3] = {0,0,1};
283  vec3_array_set(Q,ones,mask_z);
284  mat33_array F;
285  F.resize(n);
286  vec3_t V;
287  for(i=0; i<n; i++)
288  {
289  V.v[0] = Q.at(i).v[0] / Q.at(i).v[2];
290  V.v[1] = Q.at(i).v[1] / Q.at(i).v[2];
291  V.v[2] = 1.0;
292  mat33_t _m;
293  vec3_mul_vec3trans(_m,V,V);
294  mat33_div(_m,vec3trans_mul_vec3(V,V));
295  F.at(i) = _m;
296  }
297 
298  mat33_t tFactor;
299  {
300  mat33_t _m1,_m2,_m3;
301  mat33_eye(_m1);
302  mat33_array_sum(_m2,F);
303  mat33_div(_m2,real_t(n));
304  mat33_sub(_m3,_m1,_m2);
305  mat33_inv(tFactor,_m3);
306  mat33_div(tFactor,real_t(n));
307  }
308 
309  it = 0;
310  bool initR_approximate = mat33_all_zeros(options.initR);
311  mat33_t Ri;
312  vec3_t ti;
313  vec3_array Qi; Qi.resize(n);
314  real_t old_err, new_err;
315 
316  // ----------------------------------------------------------------------------------------
317  if(!initR_approximate)
318  {
319  mat33_copy(Ri,options.initR);
320  vec3_t _sum;
321  vec3_clear(_sum);
322  for(j=0; j<n; j++)
323  {
324  vec3_t _v1, _v2;
325  mat33_t _m1,_m2;
326  mat33_eye(_m1);
327  mat33_sub(_m2,F.at(j),_m1);
328  vec3_mult(_v1,Ri,P.at(j));
329  vec3_mult(_v2,_m2,_v1);
330  vec3_add(_sum,_v2);
331  }
332  vec3_mult(ti,tFactor,_sum);
333  xform(Qi,P,Ri,ti);
334  old_err = 0;
335  vec3_t _v;
336  for(j=0; j<n; j++)
337  {
338  mat33_t _m1,_m2;
339  mat33_eye(_m1);
340  mat33_sub(_m2,F.at(j),_m1);
341  vec3_mult(_v,_m2,Qi.at(j));
342  old_err += vec3_dot(_v,_v);
343  }
344  // ----------------------------------------------------------------------------------------
345  }
346  else
347  {
348  abskernel(Ri,ti,Qi,old_err,P,Q,F,tFactor);
349  it = 1;
350  }
351  // ----------------------------------------------------------------------------------------
352 
353  abskernel(Ri,ti,Qi,new_err,P,Qi,F,tFactor);
354  it = it + 1;
355 
356  while((_abs((old_err-new_err)/old_err) > options.tol) && (new_err > options.epsilon) &&
357  (options.max_iter == 0 || it<options.max_iter))
358  {
359  old_err = new_err;
360  abskernel(Ri,ti,Qi,new_err,P,Qi,F,tFactor);
361  it = it + 1;
362  }
363 
364 
365  mat33_copy(R,Ri);
366  vec3_copy(t,ti);
367  obj_err = _sqrt(new_err/real_t(n));
368 
369  if(calc_img_err)
370  {
371  vec3_array Qproj; Qproj.resize(n);
372  xformproj(Qproj, P, Ri, ti);
373  img_err = 0;
374 
375  vec3_t _v;
376  for(unsigned int j=0; j<n; j++)
377  {
378  vec3_sub(_v,Qproj.at(j),Qp.at(j));
379  img_err += vec3_dot(_v,_v);
380  }
381  img_err = _sqrt(img_err/real_t(n));
382  }
383 
384  if(t.v[2] < 0)
385  {
386  mat33_mult(R,-1.0);
387  vec3_mult(t,-1.0);
388  }
389 
390  vec3_t _ts;
391  vec3_mult(_ts,Ri,pbar);
392  vec3_sub(t,_ts);
393 }
394 
395 // =====================================================================================
396 
397 void getRotationY_wrtT(scalar_array &al_ret, vec3_array &tnew, const vec3_array &v,
398  const vec3_array &p, const vec3_t &t, const real_t &DB,
399  const mat33_t &Rz)
400 {
401  unsigned int i,j;
402  const unsigned int n = (unsigned int) v.size();
403  mat33_array V;
404  V.resize(n);
405  for(i=0; i<n; i++)
406  {
407  vec3_mul_vec3trans(V.at(i),v.at(i),v.at(i));
408  mat33_div(V.at(i), vec3trans_mul_vec3(v.at(i),v.at(i)));
409  }
410 
411  mat33_t G, _g1, _g2, _g3;
412  mat33_array_sum(_g1,V);
413  mat33_eye(_g2);
414  mat33_div(_g1,real_t(n));
415  mat33_sub(_g3,_g2,_g1);
416  mat33_inv(G, _g3);
417  mat33_div(G,real_t(n));
418  mat33_t _opt_t;
419  mat33_clear(_opt_t);
420 
421  for(i=0; i<n; i++)
422  {
423  const real_t v11 = V.at(i).m[0][0];
424  const real_t v21 = V.at(i).m[1][0];
425  const real_t v31 = V.at(i).m[2][0];
426  const real_t v12 = V.at(i).m[0][1];
427  const real_t v22 = V.at(i).m[1][1];
428  const real_t v32 = V.at(i).m[2][1];
429  const real_t v13 = V.at(i).m[0][2];
430  const real_t v23 = V.at(i).m[1][2];
431  const real_t v33 = V.at(i).m[2][2];
432  const real_t px = p.at(i).v[0];
433  const real_t py = p.at(i).v[1];
434  const real_t pz = p.at(i).v[2];
435  const real_t r1 = Rz.m[0][0];
436  const real_t r2 = Rz.m[0][1];
437  const real_t r3 = Rz.m[0][2];
438  const real_t r4 = Rz.m[1][0];
439  const real_t r5 = Rz.m[1][1];
440  const real_t r6 = Rz.m[1][2];
441  const real_t r7 = Rz.m[2][0];
442  const real_t r8 = Rz.m[2][1];
443  const real_t r9 = Rz.m[2][2];
444 
445  mat33_t _o;
446  _o.m[0][0] = (((v11-real_t(1))*r2+v12*r5+v13*r8)*py+(-(v11-real_t(1))*r1-v12*r4-v13*r7)*px+(-(v11-real_t(1))*r3-v12*r6-v13*r9)*pz);
447  _o.m[0][1] = ((real_t(2)*(v11-real_t(1))*r1+real_t(2)*v12*r4+real_t(2)*v13*r7)*pz+(-real_t(2)*(v11-real_t(1))*r3-real_t(2)*v12*r6-real_t(2)*v13*r9)*px);
448  _o.m[0][2] = ((v11-real_t(1))*r1+v12*r4+v13*r7)*px+((v11-real_t(1))*r3+v12*r6+v13*r9)*pz+((v11-real_t(1))*r2+v12*r5+v13*r8)*py;
449 
450  _o.m[1][0] = ((v21*r2+(v22-real_t(1))*r5+v23*r8)*py+(-v21*r1-(v22-real_t(1))*r4-v23*r7)*px+(-v21*r3-(v22-real_t(1))*r6-v23*r9)*pz);
451  _o.m[1][1] = ((real_t(2)*v21*r1+real_t(2)*(v22-real_t(1))*r4+real_t(2)*v23*r7)*pz+(-real_t(2)*v21*r3-real_t(2)*(v22-real_t(1))*r6-real_t(2)*v23*r9)*px);
452  _o.m[1][2] = (v21*r1+(v22-real_t(1))*r4+v23*r7)*px+(v21*r3+(v22-real_t(1))*r6+v23*r9)*pz+(v21*r2+(v22-real_t(1))*r5+v23*r8)*py;
453 
454  _o.m[2][0] = ((v31*r2+v32*r5+(v33-real_t(1))*r8)*py+(-v31*r1-v32*r4-(v33-real_t(1))*r7)*px+(-v31*r3-v32*r6-(v33-real_t(1))*r9)*pz);
455  _o.m[2][1] = ((real_t(2)*v31*r1+real_t(2)*v32*r4+real_t(2)*(v33-real_t(1))*r7)*pz+(-real_t(2)*v31*r3-real_t(2)*v32*r6-real_t(2)*(v33-real_t(1))*r9)*px);
456  _o.m[2][2] = (v31*r1+v32*r4+(v33-real_t(1))*r7)*px+(v31*r3+v32*r6+(v33-real_t(1))*r9)*pz+(v31*r2+v32*r5+(v33-real_t(1))*r8)*py;
457 
458  mat33_add(_opt_t,_o);
459  }
460 
461  mat33_t opt_t;
462  mat33_mult(opt_t,G,_opt_t);
463  real_t E_2[5] = {0,0,0,0,0};
464  for(i=0; i<n; i++)
465  {
466 #if 0
467  const real_t v11 = V.at(i).m[0][0];
468  const real_t v21 = V.at(i).m[1][0];
469  const real_t v31 = V.at(i).m[2][0];
470  const real_t v12 = V.at(i).m[0][1];
471  const real_t v22 = V.at(i).m[1][1];
472  const real_t v32 = V.at(i).m[2][1];
473  const real_t v13 = V.at(i).m[0][2];
474  const real_t v23 = V.at(i).m[1][2];
475  const real_t v33 = V.at(i).m[2][2];
476 #endif
477  const real_t px = p.at(i).v[0];
478  const real_t py = p.at(i).v[1];
479  const real_t pz = p.at(i).v[2];
480 
481  mat33_t Rpi;
482  mat33_assign(Rpi,-px,real_t(2)*pz,px,py,real_t(0),py,-pz,-real_t(2)*px,pz);
483 
484  mat33_t E,_e1,_e2;
485  mat33_eye(_e1);
486  mat33_sub(_e1,V.at(i));
487  mat33_mult(_e2,Rz,Rpi);
488  mat33_add(_e2,opt_t);
489  mat33_mult(E,_e1,_e2);
490  vec3_t e2,e1,e0;
491  mat33_to_col_vec3(e2,e1,e0,E);
492  vec3_t _E2_0,_E2_1,_E2_2,_E2_3,_E2_4;
493  vec3_copy(_E2_0,e2);
494  vec3_mult(_E2_0,e2);
495  vec3_copy(_E2_1,e1);
496  vec3_mult(_E2_1,e2);
497  vec3_mult(_E2_1,2.0f);
498  vec3_copy(_E2_2,e0);
499  vec3_mult(_E2_2,e2);
500  vec3_mult(_E2_2,2.0f);
501  vec3_t _e1_sq;
502  vec3_copy(_e1_sq,e1);
503  vec3_mult(_e1_sq,e1);
504  vec3_add(_E2_2,_e1_sq);
505  vec3_copy(_E2_3,e0);
506  vec3_mult(_E2_3,e1);
507  vec3_mult(_E2_3,2.0f);
508  vec3_copy(_E2_4,e0);
509  vec3_mult(_E2_4,e0);
510  E_2[0] += vec3_sum(_E2_0);
511  E_2[1] += vec3_sum(_E2_1);
512  E_2[2] += vec3_sum(_E2_2);
513  E_2[3] += vec3_sum(_E2_3);
514  E_2[4] += vec3_sum(_E2_4);
515  }
516 
517  scalar_array _a;
518  _a.resize(5);
519  _a[4] = -E_2[1];
520  _a[3] = real_t(4)*E_2[0] - real_t(2)*E_2[2];
521  _a[2] = -real_t(3)*E_2[3] + real_t(3)*E_2[1];
522  _a[1] = -real_t(4)*E_2[4] + real_t(2)*E_2[2];
523  _a[0] = E_2[3];
524 
525  scalar_array at_sol;
526  int num_sol = solve_polynomial(at_sol, _a);
527  scalar_array e;
528  e.resize(num_sol);
531  scalar_array_add(e,_a[0]);
532  at.clear();
533  at.assign(at_sol.begin(),at_sol.end());
534  scalar_array_mult(at,_a[1]);
535  scalar_array_add(e,at);
536 
537  for(j=2; j<=4; j++)
538  {
539  at.clear();
540  at.assign(at_sol.begin(),at_sol.end());
541  scalar_array_pow(at,real_t(j));
542  scalar_array_mult(at,_a[j]);
543  scalar_array_add(e,at);
544  }
545 
546  scalar_array at_;
547  at_.clear();
548  for(i=0; i<at.size(); i++)
549  {
550  if(_abs(e[i]) < real_t(1e-3)) at_.push_back(at_sol[i]);
551  }
552 
553  scalar_array p1(at_.begin(),at_.end());
554  scalar_array_pow(p1,2);
555  scalar_array_add(p1,1);
556  scalar_array_pow(p1,3);
557 
558  at.clear();
559  for(i=0; i<at_.size(); i++)
560  {
561  if(_abs(p1[i]) > real_t(0.1f)) at.push_back(at_[i]);
562  }
563 
564  scalar_array sa(at.begin(),at.end());
565  scalar_array_mult(sa,2);
566  scalar_array _ca1(at.begin(),at.end());
567  scalar_array_pow(_ca1,2);
568  scalar_array_add(_ca1,1);
569  scalar_array ca(at.begin(),at.end());
570  scalar_array_pow(ca,2);
572  scalar_array_add(ca,1);
573  scalar_array_div(ca,_ca1);
574  scalar_array_div(sa,_ca1);
575  scalar_array al;
576  scalar_array_atan2(al,sa,ca);
578  scalar_array _c_tMaxMin;
579  _c_tMaxMin.resize(at.size());
580  scalar_array_clear(_c_tMaxMin);
581  scalar_array_add(_c_tMaxMin,_a[1]);
582  scalar_array _at;
583  _at.clear();
584  _at.assign(at.begin(),at.end());
585  scalar_array_mult(_at,_a[2]);
586  scalar_array_mult(_at,2);
587  scalar_array_add(_c_tMaxMin,_at);
588 
589  for(j=3; j<=4; j++)
590  {
591  _at.clear();
592  _at.assign(at.begin(),at.end());
593  scalar_array_pow(_at,(real_t)real_t(j)-real_t(1.0f));
594  scalar_array_mult(_at,_a[j]);
595  scalar_array_mult(_at,real_t(j));
596  scalar_array_add(_c_tMaxMin,_at);
597  }
598 
599  scalar_array tMaxMin(_c_tMaxMin.begin(),_c_tMaxMin.end());
600  scalar_array al_;
601  al_.clear();
602  for(i=0; i<tMaxMin.size(); i++)
603  {
604  if(tMaxMin.at(i) > 0) al_.push_back(al.at(i));
605  }
606 
607  tnew.resize(al_.size());
608  for(unsigned int a=0; a<al_.size(); a++)
609  {
610  vec3_t rpy;
611  vec3_assign(rpy,real_t(0),real_t(al_[a] * CONST_PI / real_t(180)), real_t(0));
612  mat33_t R,Ry_;
613  rpyMat(Ry_,rpy);
614  mat33_mult(R,Rz,Ry_);
615  vec3_t t_opt;
616  vec3_clear(t_opt);
617 
618  for(i=0; i<n; i++)
619  {
620  mat33_t _m1,_eye3;
621  mat33_eye(_eye3);
622  mat33_copy(_m1,V.at(i));
623  mat33_sub(_m1,_eye3);
624  vec3_t _v1,_v2;
625  vec3_mult(_v1,R,p.at(i));
626  vec3_mult(_v2,_m1,_v1);
627  vec3_add(t_opt,_v2);
628  }
629 
630  vec3_t t_opt_;
631  vec3_mult(t_opt_,G,t_opt);
632  tnew.at(a) = t_opt_;
633  }
634  al_ret.assign(al_.begin(),al_.end());
635 }
636 
637 // =====================================================================================
638 
639 void getRfor2ndPose_V_Exact(pose_vec &sol, const vec3_array &v, const vec3_array &P,
640  const mat33_t R, const vec3_t t, const real_t DB)
641 {
642 
643  mat33_t RzN;
644  decomposeR(RzN, R);
645  mat33_t R_;
646  mat33_mult(R_,R,RzN);
647  mat33_t RzN_tr;
648  mat33_transpose(RzN_tr,RzN);
649  vec3_array P_;
650  vec3_array_mult(P_,RzN_tr,P);
651  vec3_t ang_zyx;
652  rpyAng_X(ang_zyx,R_);
653  vec3_t rpy;
654  mat33_t Ry,Rz;
655  vec3_assign(rpy,0,ang_zyx.v[1],0);
656  rpyMat(Ry,rpy);
657  vec3_assign(rpy,0,0,ang_zyx.v[2]);
658  rpyMat(Rz,rpy);
659  scalar_array bl;
660  vec3_array Tnew;
661  getRotationY_wrtT(bl,Tnew, v ,P_, t, DB, Rz);
662  scalar_array_div(bl,180.0f/CONST_PI);
663  const unsigned int n = (unsigned int) v.size();
664  mat33_array V;
665  V.resize(n);
666  for(unsigned int i=0; i<n; i++)
667  {
668  vec3_mul_vec3trans(V.at(i),v.at(i),v.at(i));
669  mat33_div(V.at(i),vec3trans_mul_vec3(v.at(i),v.at(i)));
670  }
671 
672  sol.clear();
673  sol.resize(bl.size());
674 
675  for(unsigned int j=0; j<(unsigned int)bl.size(); j++)
676  {
677  mat33_clear(Ry);
678  vec3_assign(rpy,0,bl[j],0);
679  rpyMat(Ry,rpy);
680  mat33_t _m1;
681  mat33_mult(_m1,Rz,Ry);
682  mat33_mult(sol[j].R,_m1,RzN_tr);
683  vec3_copy(sol[j].t,Tnew[j]);
684  real_t E = 0;
685  for(unsigned int i=0; i<n; i++)
686  {
687  mat33_t _m2;
688  mat33_eye(_m2);
689  mat33_sub(_m2,V.at(i));
690  vec3_t _v1;
691  vec3_mult(_v1,sol[j].R,P.at(i));
692  vec3_add(_v1,sol[j].t);
693  vec3_t _v2;
694  vec3_mult(_v2,_m2,_v1);
695  vec3_mult(_v2,_v2);
696  E += vec3_sum(_v2);
697  }
698  sol[j].E = E;
699  }
700 }
701 
702 // =====================================================================================
703 
704 void get2ndPose_Exact(pose_vec &sol, const vec3_array &v, const vec3_array &P,
705  const mat33_t R, const vec3_t t, const real_t DB)
706 {
707  vec3_t cent, _v1;
708  vec3_array _va1;
709  normRv(_va1,v);
710  vec3_array_mean(_v1,_va1);
711  normRv(cent,_v1);
712  mat33_t Rim;
713  vec3_clear(_v1);
714  _v1.v[2] = 1.0f;
715  GetRotationbyVector(Rim,_v1,cent);
716  vec3_array v_;
717  vec3_array_mult(v_,Rim,v);
718  normRv(_va1,v_);
719  vec3_array_mean(_v1,_va1);
720  normRv(cent,_v1);
721  mat33_t R_;
722  vec3_t t_;
723  mat33_mult(R_,Rim,R);
724  vec3_mult(t_,Rim,t);
725  getRfor2ndPose_V_Exact(sol,v_,P,R_,t_,DB);
726  mat33_t Rim_tr;
727  mat33_transpose(Rim_tr,Rim);
728  for(unsigned int i=0; i<sol.size(); i++)
729  {
730  vec3_t _t;
731  mat33_t _R;
732  vec3_mult(_t,Rim_tr,sol[i].t);
733  mat33_mult(_R,Rim_tr,sol[i].R);
734 
735  vec3_copy(sol[i].t,_t);
736  mat33_copy(sol[i].R,_R);
737  }
738 }
739 
740 // =====================================================================================
741 void robust_pose(real_t &err, mat33_t &R, vec3_t &t,
742  const vec3_array &_model, const vec3_array &_iprts,
743  const options_t _options)
744 {
745  mat33_t Rlu_;
746  vec3_t tlu_;
747  unsigned int it1_;
748  real_t obj_err1_;
749  real_t img_err1_;
750 
751  vec3_array model(_model.begin(),_model.end());
752  vec3_array iprts(_iprts.begin(),_iprts.end());
754  memcpy(&options,&_options,sizeof(options_t));
755 
756  mat33_clear(Rlu_);
757  vec3_clear(tlu_);
758  it1_ = 0;
759  obj_err1_ = 0;
760  img_err1_ = 0;
761 
762  objpose(Rlu_, tlu_, it1_, obj_err1_, img_err1_, true, model, iprts, options);
763 
764  pose_vec sol;
765  sol.clear();
766  get2ndPose_Exact(sol,iprts,model,Rlu_,tlu_,0);
767  int min_err_idx = (-1);
768  real_t min_err = MAX_FLOAT;
769  for(unsigned int i=0; i<sol.size(); i++)
770  {
771  mat33_copy(options.initR,sol[i].R);
772  objpose(Rlu_, tlu_, it1_, obj_err1_, img_err1_, true, model, iprts, options);
773  mat33_copy(sol[i].PoseLu_R,Rlu_);
774  vec3_copy(sol[i].PoseLu_t,tlu_);
775  sol[i].obj_err = obj_err1_;
776  if(sol[i].obj_err < min_err)
777  {
778  min_err = sol[i].obj_err;
779  min_err_idx = i;
780  }
781  }
782 
783  if(min_err_idx >= 0)
784  {
785  mat33_copy(R,sol[min_err_idx].PoseLu_R);
786  vec3_copy(t,sol[min_err_idx].PoseLu_t);
787  err = sol[min_err_idx].obj_err;
788  }
789  else
790  {
791  mat33_clear(R);
792  vec3_clear(t);
793  err = MAX_FLOAT;
794  }
795 }
796 
797 // ----------------------------------------
798 } // namespace rpp
799 
800 
801 #endif //_NO_LIBRPP_
real_t epsilon
Definition: rpp_types.h:107
vec3_t v
Definition: rpp_types.h:99
real_t vec3trans_mul_vec3(const vec3_t &va, const vec3_t &vb)
Definition: rpp_vecmat.cpp:511
void scalar_array_clear(scalar_array &sa)
Definition: rpp_vecmat.cpp:872
std::vector< pose_t > pose_vec
Definition: rpp_types.h:95
void mat33_eye(mat33_t &m)
Definition: rpp_vecmat.cpp:560
real_t _sin(real_t a)
Definition: rpp_vecmat.cpp:69
void mat33_svd2(mat33_t &u, mat33_t &s, mat33_t &v, const mat33_t &m)
Definition: rpp_vecmat.cpp:730
f
void rpyAng_X(vec3_t &ang_zyx, const mat33_t &R)
Definition: rpp.cpp:157
void mat33_to_col_vec3(vec3_t &c0, vec3_t &c1, vec3_t &c2, const mat33_t &m)
Definition: rpp_vecmat.cpp:536
void normRv(vec3_t &n, const vec3_t &v)
Definition: rpp_vecmat.cpp:792
void objpose(mat33_t &R, vec3_t &t, unsigned int &it, real_t &obj_err, real_t &img_err, bool calc_img_err, const vec3_array _P, const vec3_array Qp, const options_t options)
Definition: rpp.cpp:266
void mat33_div(mat33_t &m, const real_t f)
Definition: rpp_vecmat.cpp:547
void vec3_array_sub(vec3_array &va, const vec3_t &a)
Definition: rpp_vecmat.cpp:457
void mat33_mult(mat33_t &m0, const mat33_t &m1, const mat33_t &m2)
Definition: rpp_vecmat.cpp:682
Definition: rpp.cpp:55
std::vector< mat33_t > mat33_array
Definition: rpp_types.h:77
void abskernel(mat33_t &R, vec3_t &t, vec3_array &Qout, real_t &err2, const vec3_array _P, const vec3_array _Q, const mat33_array F, const mat33_t G)
Definition: rpp.cpp:192
void Quaternion_byAngleAndVector(quat_t &Q, const real_t &q_angle, const vec3_t &q_vector)
Definition: rpp.cpp:58
void scalar_array_negate(scalar_array &sa)
Definition: rpp_vecmat.cpp:850
#define MAX_FLOAT
Definition: rpp_const.h:62
real_t vec3_dot(const vec3_t &va, const vec3_t &vb)
Definition: rpp_vecmat.cpp:424
void rpyAng(vec3_t &angs, const mat33_t &R)
Definition: rpp.cpp:134
void scalar_array_mult(scalar_array &sa, real_t f)
Definition: rpp_vecmat.cpp:909
bool mat33_all_zeros(const mat33_t &m)
Definition: rpp_vecmat.cpp:585
void rpyMat(mat33_t &R, const vec3_t &rpy)
Definition: rpp.cpp:110
std::vector< vec3_t > vec3_array
Definition: rpp_types.h:71
void quat_mult(quat_t &q, const real_t s)
Definition: rpp_vecmat.cpp:758
#define CONST_2_PI
Definition: rpp_const.h:50
#define CONST_PI_OVER_2
Definition: rpp_const.h:48
void mat33_clear(mat33_t &m)
Definition: rpp_vecmat.cpp:517
void vec3_cross(vec3_t &va, const vec3_t &vb, const vec3_t &vc)
Definition: rpp_vecmat.cpp:429
options
void mat33_assign(mat33_t &m, const real_t m00, const real_t m01, const real_t m02, const real_t m10, const real_t m11, const real_t m12, const real_t m20, const real_t m21, const real_t m22)
Definition: rpp_vecmat.cpp:184
real_t _cos(real_t a)
Definition: rpp_vecmat.cpp:70
void vec3_array_mult(vec3_array &va, const scalar_array &c)
Definition: rpp_vecmat.cpp:479
std::vector< real_t > scalar_array
Definition: rpp_types.h:81
static SVD_FLOAT at
Definition: rpp_svd.cpp:50
void scalar_array_atan2(scalar_array &sa, const scalar_array &sb, const scalar_array &sc)
Definition: rpp_vecmat.cpp:877
void mat33_from_quat(mat33_t &m, const quat_t &q)
Definition: rpp_vecmat.cpp:771
void scalar_array_add(scalar_array &sa, const scalar_array &sb)
Definition: rpp_vecmat.cpp:865
void GetRotationbyVector(mat33_t &R, const vec3_t &v1, const vec3_t &v2)
Definition: rpp.cpp:71
void get2ndPose_Exact(pose_vec &sol, const vec3_array &v, const vec3_array &P, const mat33_t R, const vec3_t t, const real_t DB)
Definition: rpp.cpp:704
void mat33_sub(mat33_t &mr, const mat33_t &ma, const mat33_t &mb)
Definition: rpp_vecmat.cpp:621
void xform(vec3_array &Q, const vec3_array &P, const mat33_t &R, const vec3_t &t)
Definition: rpp.cpp:82
real_t _sqrt(real_t a)
Definition: rpp_vecmat.cpp:74
double real_t
Definition: rpp_types.h:64
real_t vec3_sum(const vec3_t &v)
Definition: rpp_vecmat.cpp:441
void vec3_add(vec3_t &va, const real_t f)
Definition: rpp_vecmat.cpp:382
void mat33_inv(mat33_t &mi, const mat33_t &ma)
Definition: rpp_vecmat.cpp:666
int solve_polynomial(scalar_array &r_sol, const scalar_array &coefficients)
Definition: rpp_vecmat.cpp:821
void scalar_array_pow(scalar_array &sa, const real_t f)
Definition: rpp_vecmat.cpp:845
void decomposeR(mat33_t &Rz, const mat33_t &R)
Definition: rpp.cpp:183
unsigned int max_iter
Definition: rpp_types.h:108
void mat33_array_sum(mat33_t &s, const mat33_array &ma)
Definition: rpp_vecmat.cpp:605
real_t quat_norm(const quat_t &q)
Definition: rpp_vecmat.cpp:764
void vec3_mul_vec3trans(mat33_t &m, const vec3_t &va, const vec3_t &vb)
Definition: rpp_vecmat.cpp:498
void vec3_array_mean(vec3_t &v_mean, const vec3_array &va)
Definition: rpp_vecmat.cpp:490
void vec3_clear(vec3_t &v)
Definition: rpp_vecmat.cpp:304
real_t _abs(real_t a)
Definition: rpp_vecmat.cpp:72
void getRotationY_wrtT(scalar_array &al_ret, vec3_array &tnew, const vec3_array &v, const vec3_array &p, const vec3_t &t, const real_t &DB, const mat33_t &Rz)
Definition: rpp.cpp:397
void vec3_sub(vec3_t &va, const real_t f)
Definition: rpp_vecmat.cpp:403
mat33_t initR
Definition: rpp_types.h:105
void vec3_array_sum(vec3_t &v_sum2, const vec3_array &va)
Definition: rpp_vecmat.cpp:319
void mat33_copy(mat33_t &md, const mat33_t &ms)
Definition: rpp_vecmat.cpp:526
void vec3_div(vec3_t &va, const real_t n)
Definition: rpp_vecmat.cpp:354
void getRfor2ndPose_V_Exact(pose_vec &sol, const vec3_array &v, const vec3_array &P, const mat33_t R, const vec3_t t, const real_t DB)
Definition: rpp.cpp:639
real_t _atan2(real_t a, real_t b)
Definition: rpp_vecmat.cpp:71
void robust_pose(real_t &err, mat33_t &R, vec3_t &t, const vec3_array &_model, const vec3_array &_iprts, const options_t _options)
Definition: rpp.cpp:741
void mat33_transpose(mat33_t &t, const mat33_t m)
Definition: rpp_vecmat.cpp:704
void mat33_add(mat33_t &mr, const mat33_t &ma, const mat33_t &mb)
Definition: rpp_vecmat.cpp:639
#define CONST_PI
Definition: rpp_const.h:49
void vec3_array_set(vec3_array &va, const vec3_t &a, const bool mask[3])
Definition: rpp_vecmat.cpp:468
void vec3_copy(vec3_t &a, const vec3_t &b)
Definition: rpp_vecmat.cpp:311
void scalar_array_div(scalar_array &sa, real_t f)
Definition: rpp_vecmat.cpp:894
real_t _acos(real_t a)
Definition: rpp_vecmat.cpp:73
void vec3_assign(vec3_t &v, const real_t x, const real_t y, const real_t z)
Definition: rpp_vecmat.cpp:297
void xformproj(vec3_array &Qp, const vec3_array &P, const mat33_t &R, const vec3_t &t)
Definition: rpp.cpp:93
real_t s
Definition: rpp_types.h:100
void vec3_mult(vec3_t &va, const real_t n)
Definition: rpp_vecmat.cpp:368


tuw_artoolkitplus
Author(s): Markus Bader
autogenerated on Sun Sep 4 2016 03:24:33