Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
TrackerBaseAffine2.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include "TrackerBaseAffine2.hh"
26 #include "MathAlgo/SVD.hh"
27 #include "Filter/Gauss.hh"
28 #include "Base/Math/Matrix3x3.hh"
29 #include "Base/Image/ImageIO.hh"
30 #include "Image/AffineMapping.hh"
31 #include "Base/Common/FileHandling.hh"
32 #include "MathAlgo/UnscentedTransform.hh"
33 #include "Base/Image/ImageIO.hh"
34 
35 
36 const double DEFAULT_MAX_AFFINECHANGE = 0.3;
37 
38 using namespace BIAS;
39 using namespace std;
40 
41 namespace BIAS
42 {
43 
44 // functions from trackerbaseaffine.cpp
45 void Compute4by1ErrorVector(KLT_TYPE* imgdiff,
46  KLT_TYPE* gradx,
47  KLT_TYPE* grady,
48  const int hw,
49  const int hh,
51 
52 void Compute4by4GradientMatrix(KLT_TYPE* gradx,
53  KLT_TYPE* grady,
54  const int hw,
55  const int hh,
57 
60 
61 void Compute6by1ErrorVector(KLT_TYPE* imgdiff,
62  KLT_TYPE* gradx,
63  KLT_TYPE* grady,
64  const int hw,
65  const int hh,
67 
68 void Compute6by6GradientMatrix(KLT_TYPE* gradx,
69  KLT_TYPE* grady,
70  const int hw,
71  const int hh,
73 
74 /**
75  * @class AffineTransform
76  * @brief transform 6D uncertainty into 2d image uncertainty in same image
77  * @internal
78  */
79 class AffineTransform: public UnscentedTransform {
80 public:
81  AffineTransform() {
82  dx_ = 0;
83  dy_ = 0;
84  A_.SetZero();
85  tx_ = 0;
86  ty_ = 0;
87  SetAlpha(1.0);
88  }
89  virtual int Transform_(const Vector<double>& src,
90  Vector<double>& dst) const {
91  BIASASSERT(src.size()==6);
92  dst.newsize(2);
93  //cout<<"trying "<<src<<": with A "<<A_<<" and t "<<tx_<<";"<<ty_<<" ";
94  double tempx = A_[0][0] * dx_ + A_[0][1] * dy_;// + tx_;
95  double tempy = A_[1][0] * dx_ + A_[1][1] * dy_;// + ty_;
96  dst[0] = src[0] * tempx + src[1] * tempy + src[4];
97  dst[1] = src[2] * tempx + src[3] * tempy + src[5];
98  //cout<<"("<<dx_<<";"<<dy_<<")->"<<dst<<endl;
99  return 0;
100  }
101  double dx_,dy_;
103  double tx_,ty_;
104 };
105 
106 /**
107  * @class AffineBackTransform
108  * @brief transform 6D uncertainty into 2d image uncertainty in same image
109  * @internal
110  */
111 class AffineBackTransform: public UnscentedTransform {
112 public:
113  AffineBackTransform() {
114  dx_ = 0;
115  dy_ = 0;
116  A_.SetZero();
117  tx_ = 0;
118  ty_ = 0;
119  SetAlpha(1.0);
120  }
121  virtual int Transform_(const Vector<double>& src,
122  Vector<double>& dst) const {
123  BIASASSERT(src.size()==6);
124  dst.newsize(2);
125  double tempx = src[0] * dx_ + src[1] * dy_ + src[4];
126  double tempy = src[2] * dx_ + src[3] * dy_ + src[5];
127  dst[0] = A_[0][0] * tempx + A_[0][1] * tempy + tx_;
128  dst[1] = A_[1][0] * tempx + A_[1][1] * tempy + ty_;
129 
130  return 0;
131  }
132  double dx_,dy_;
134  double tx_,ty_;
135 };
136 
137 
138 template <class StorageType>
140 TrackerBaseAffine2(bool only4params)
141 {
142  BIASASSERT(!only4params);
143  _MaxAffineChange = DEFAULT_MAX_AFFINECHANGE;
144  _SimilarityTransformOnly = only4params;
145  affineNormalization_ = false;
146  initialCov_.newsize(6,6);
147  initialCov_.SetIdentity();
148  initialCov_ *= 0.001;
149  initialCov_[4][4] = 0.05;
150  initialCov_[5][5] = 0.05;
151 
152 
153 }
154 
155 template <class StorageType>
158  Vector2<KLT_TYPE>& result, KLT_TYPE& error,
159  int &iter,
160  const Matrix2x2<KLT_TYPE>& AffinePred,
161  Matrix2x2<KLT_TYPE>& AffineResult)
162 {
163 
164 #ifdef BIAS_DEBUG
165  if (AffinePred.NormFrobenius()<1e-10) {
166  BIASERR("affine guess seems unitialized, set at least identity");
167  }
168 #endif
169  residuumMAD_ = 0;
170  residuumMSD_ = 0;
171 
172  int res = TrackAffine_(p1.GetData(), p2.GetData(), AffinePred,
173  result.GetData(), AffineResult,
174  error, iter, Cov_, residuumMAD_, residuumMSD_,
175  _SimilarityTransformOnly, true);
176  return res;
177 }
178 
179 
180 // affine transformation may maginify region. in this case remove
181 // high frequencies
182 double GetBaseLevel(const Vector<double>& apar, bool backdirection) {
184  A[0][0] = apar[0];
185  A[0][1] = apar[1];
186  A[1][0] = apar[2];
187  A[1][1] = apar[3];
188 
189  Matrix<double> ATA;
190  A.GetSystemMatrix(ATA);
191  SVD mysvd(ATA);
192  Vector<double> S = mysvd.GetS();
193 
194  double basesmooth = (backdirection)
195  ? sqrt(0.5*(1.0/S[0]+1.0/S[1]))
196  : sqrt(0.5*(S[0]+S[1]));
197  if (basesmooth<=1.0) return 0;
198  else return(log2(basesmooth));
199 
200 }
201 
202 #define INVALID_PIXEL -1e10
203 
204 template <class StorageType>
206 BilinearRegion1_(KLT_TYPE x, KLT_TYPE y,
207  int hws, const Vector<double>& apar,
208  const Matrix<double>& Cov) {
209 
210  // if detATA<1 smooth this image, because we wont have high frequencies
211  // in im2, which will be magnified
212  double basesmooth = GetBaseLevel(apar, true);
213  cout<<"basesmooth for image 1 is "<<basesmooth<<" with apar "<<apar<<endl;
214  const double maxLayer = _pgradim2x.size()-1;
215 
216  AffineBackTransform AT;
218  H[0][0] = apar[0];
219  H[0][1] = apar[1];
220  H[1][0] = apar[2];
221  H[1][1] = apar[3];
222  H[0][2] = apar[4];
223  H[1][2] = apar[5];
224  H[2][2] = 1.0;
225 #ifdef BIASASSERT_ISACTIVE
226  int ires =
227 #endif
228  H.GetInverse(tmp);
229  BIASASSERT(ires ==0);
230  H = tmp;
231  cout<<"inverted A is "<<H<<endl;
232  AT.A_[0][0] = H[0][0];
233  AT.A_[0][1] = H[0][1];
234  AT.A_[1][0] = H[1][0];
235  AT.A_[1][1] = H[1][1];
236  AT.tx_ = H[0][2];
237  AT.ty_ = H[1][2];
238 
239 
240 
241  Vector<double> offset;
242  Matrix<double> dstcov;
243 
244  // Image<StorageType>& image = *_im1;
245  //Image<StorageType>& gradx = *this->_gradim1x;
246  //Image<StorageType>& grady = *this->_gradim1y;
247  Matrix<KLT_TYPE>& bl = this->_bl1;
248  Matrix<KLT_TYPE>& gx = this->_gx1;
249  Matrix<KLT_TYPE>& gy = this->_gy1;
250  bl.SetZero();
251  gx.SetZero();
252  gy.SetZero();
253 
254  // StorageType** image_ida = image.GetImageDataArray();
255  //StorageType** gradx_ida = gradx.GetImageDataArray();
256  //StorageType** grady_ida = grady.GetImageDataArray();
257 
258  int x_floor = (int)floor(x);
259  int y_floor = (int)floor(y);
260  int x_floor_end = x_floor+hws+1;
261  int y_floor_end = y_floor+hws+1;
262  KLT_TYPE brdy = y - (KLT_TYPE)(y_floor);
263  KLT_TYPE brdx = x - (KLT_TYPE)(x_floor);
264  //KLT_TYPE brdxy = brdx*brdy;
265  cout<<"affine parameters "<<apar <<"with predicted cov "<<Cov<<endl;
266  cout<<"image 1 scales: "<<endl;
267  int rf, rc, cf, cc, r, c;
268  for (rf=y_floor-hws, rc=rf+1, r=0; rf<y_floor_end; rf++, rc++, r++) {
269  for (cf=x_floor-hws, cc=cf+1, c=0; cf<x_floor_end; cf++, cc++, c++) {
270 
271  /////////// pyramid layer
272  AT.dx_ = cf-x_floor;
273  AT.dy_ = rf-y_floor;
274  AT.Transform(apar,Cov, offset,dstcov);
275  // d==0.5 => use layer 0
276  double layer = log2(sqrt(dstcov.Trace()));
277  cout<<fixed<<setprecision(2)<<setw(6)<<layer<<" ";
278  if (layer<0.0) layer = 0;
279  if (layer>maxLayer) layer=maxLayer;
280 
281  const double scale = 1.0/exp2(rint(layer));
282 
283  const double myx = cf+brdx, myy = rf+brdy;
284 
285  if (_pgradim1x[int(rint(layer))]->IsInROI(scale*myx,scale*myy)) {
286  /////////// pyramid layer
287  _pim1.GetTrilinearImageValue(myx, myy, layer, bl[r][c]);
288  BIASASSERT(!BIAS_ISINF( bl[r][c]));
289  BIASASSERT(bl[r][c]<1e10);
290  _pgradim1x.GetTrilinearImageValue(myx, myy, layer, gx[r][c]);
291  BIASASSERT(!BIAS_ISINF( gx[r][c]));
292  _pgradim1y.GetTrilinearImageValue(myx, myy, layer, gy[r][c]);
293  BIASASSERT(!BIAS_ISINF( gy[r][c]));
294  } else {
295  bl[r][c] = gx[r][c] = gy[r][c] = INVALID_PIXEL;
296  }
297  //cout<<r<<";"<<c<<" ";
298  }
299  cout<<endl;
300  }
301  if (_AffineBrightnessInvariance) dev1_ = this->NormalizeRegion_(bl, gx, gy);
302  else dev1_ = 1.0;
303 }
304 
305 
306 
307 // ***************** parts, which are not under LGPL *************************
308 // The function TrackAffine_ is based on the affine tracker by Thorsten
309 // Thormaehlen. Some of the worker functions have been rewritten, some
310 // have been adapted, see below for the conditions on this software.
311 
312 template <class StorageType>
314 TrackAffine_(KLT_TYPE op1[2], KLT_TYPE op2[2],
315  const Matrix2x2<KLT_TYPE>& op2A,
316  KLT_TYPE oresult[2], Matrix2x2<KLT_TYPE>& oresultA,
317  KLT_TYPE& error, int &iteration, Matrix<KLT_TYPE>& Cov,
318  KLT_TYPE& mad, KLT_TYPE& msd,
319  bool SimilarityTransformOnly, bool ComputeCovariance)
320 
321 {
322 
323 #ifdef BIAS_DEBUG
324  static int featurecounter = 0;
325  featurecounter++;
326 #endif
327 
328  KLT_TYPE p1[2]={op1[0],op1[1]};
329  KLT_TYPE p2[2]={op2[0],op2[1]};
330  Matrix2x2<KLT_TYPE> p2A = op2A;
331  KLT_TYPE result[2]={oresult[0], oresult[1]};
332  Matrix2x2<KLT_TYPE> resultA = oresultA;
333 
334 
335  //this->AddDebugLevel(D_TRACKERB_AFFINE | D_TRACKERB_KLT);
336  BIASDOUT(D_TRACKERB_AFFINE, "Called Affine for "
337  <<p1[0]<<";"<<p1[1]<<", guess is "<<p2[0]<<";"<<p2[1]
338  <<" affine guess is "<< p2A);
339  cout<<"window size is "<< _WinSize<<endl;
340  const int width = _WinSize;
341  const int height = _WinSize;
342  const int hw = width/2;
343  const int hh = height/2;
344 
345  const KLT_TYPE fhw = hw;
346  const KLT_TYPE fhh = hh;
347 
348  if (_minx1 >= p1[0] || _miny1 >= p1[1] || _maxx1 < p1[0] || _maxy1 < p1[1]){
349  BIASDOUT(D_TRACKERB_KLT, "original point is too close to border: "
350  <<p1[0]<<";"<<p1[1]);
351  return TRACKER_OUTOFIMAGE;
352  }
353 
354 
355  const int max_iterations = _MaxIterations;
356  const KLT_TYPE maxerr = _MaxError;
357  const KLT_TYPE th_aff = _MaxAffineChange;
358 
359  KLT_TYPE dx=0, dy=0;
360  iteration = 0;
361  int status = 0;
362 
363  const unsigned int num_params = SimilarityTransformOnly?4:6;
364 
365  Matrix<KLT_TYPE> T(num_params, num_params);
366  Vector<KLT_TYPE> a(num_params);
367 
368 
369 
370  Cov = initialCov_;
371 
372  Matrix<double> Cov2(Cov);
373 
374  resultA = p2A;
375  KLT_TYPE *Axx = &(resultA[0][0]);
376  KLT_TYPE *Axy = &(resultA[0][1]);
377  KLT_TYPE *Ayx = &(resultA[1][0]);
378  KLT_TYPE *Ayy = &(resultA[1][1]);
379 
380  result[0] = p2[0];
381  result[1] = p2[1];
382 
383  bool convergence = false;
384 
385 
386  // Allocate memory for windows
387  KLT_TYPE *imgdiff = new KLT_TYPE[width * height];
388  KLT_TYPE *gradx = new KLT_TYPE[width * height];
389  KLT_TYPE *grady = new KLT_TYPE[width * height];
390 
391  // compute reference window only ONCE
392  // BilinearRegion1_(p1[0], p1[1], hh);
393 
394 
395 
396  // we could compute pyramid size from initial parameter uncertainty here ...
397  int ps = int(rint(log2(double(_im1->GetWidth()+_im1->GetHeight()))))-6;
398 
399 
400  Image<StorageType> im1, gradim1x, gradim1y;
401  Image<StorageType> im2, gradim2x, gradim2y;
402 
404 
405  if (affineNormalization_) {
406 
407  // when encoding the affine transformation into a 3x3 matrix and operating
408  // on homogeneous points, we get
409  // x2 = A * x1
410  // If we now normalize the region in im1 on which we track (by R1) we get
411  // x2 = A' * R1 * x1
412 
414  ShapeNormalizer.SetAffineTransformation(R1_[0][0], R1_[0][1],
415  R1_[1][0], R1_[1][1],
416  R1_[0][2], R1_[1][2]);
417 
418  im1.Init(10*hw, 10*hw);
419  ShapeNormalizer.MapDirect( *this->_im1, im1);
420  gradim1x.Init(10*hw, 10*hw);
421  ShapeNormalizer.MapDirect( *this->_gradim1x, gradim1x);
422  gradim1y.Init(10*hw, 10*hw);
423  ShapeNormalizer.MapDirect( *this->_gradim1y, gradim1y);
424 
425  // adapt coordinates in first image and A prediction
426  HomgPoint2D x1(p1[0], p1[1]);
427  x1 = R1_ * x1;
428  result[0] = p1[0] = x1[0];
429  result[1] = p1[1] = x1[1];
430 
431 
432 
433  // We want to normalize the region in the other image by R2
434  // x2 = R2^-1 * A" * R1 * x1
435  // such that if the prediction is correct we end up with an identic image
436  // A=Apred => A"=id => Apred = R2^-1 * R1 => R2 = R1 * Apred^-1
437 
438 
439 
440  Matrix3x3<double> A3x3(MatrixZero), A3x3I;
441  A3x3[0][0] = resultA[0][0];
442  A3x3[0][1] = resultA[0][1];
443  A3x3[1][0] = resultA[1][0];
444  A3x3[1][1] = resultA[1][1];
445  A3x3[0][2] = p2[0];
446  A3x3[1][2] = p2[1];
447  A3x3[2][2] = 1.0;
448 
449  // compute R2
450 #ifdef BIASASSERT_ISACTIVE
451  int ires =
452 #endif
453  A3x3.GetInverse(A3x3I);
454  BIASASSERT(ires==0);
455  R2 = R1_ * A3x3I;
456  ShapeNormalizer.SetAffineTransformation(R2[0][0], R2[0][1],
457  R2[1][0], R2[1][1],
458  R2[0][2], R2[1][2]);
459  im2.Init(10*hw, 10*hw);
460  ShapeNormalizer.MapDirect( *_im2, im2);
461  gradim2x.Init(10*hw, 10*hw);
462  ShapeNormalizer.MapDirect( *_gradim2x, gradim2x);
463  gradim2y.Init(10*hw, 10*hw);
464  ShapeNormalizer.MapDirect( *_gradim2y, gradim2y);
465 
466  // adapt coordinates in second image amd prediction
467  p2A.SetIdentity();
468  resultA.SetIdentity();
469 
470 #ifdef BIAS_DEBUG
471  //ImageIO::Save("_im1", im1);
472  //ImageIO::Save("_im2", im2);
473  //ImageIO::Save("_gradim1x",gradim1x);
474  //ImageIO::Save("_gradim1y",gradim1y);
475  //ImageIO::Save("_gradim2x",gradim2x);
476  //ImageIO::Save("_gradim2y",gradim2y);
477  ImageIO::Save("_im1", im1);
478  ImageIO::Save("_im2", im2);
479  ImageIO::Save("_gradim1x",gradim1x);
480  ImageIO::Save("_gradim1y",gradim1y);
481  ImageIO::Save("_gradim2x",gradim2x);
482  ImageIO::Save("_gradim2y",gradim2y);
483 #endif
484 
485  } else {
486  im1 = *_im1;
487  gradim1x = *this->_gradim1x ;
488  gradim1y = *this->_gradim1y;
489  im2 = *_im2;
490  gradim2x = *this->_gradim2x;
491  gradim2y = *this->_gradim2y;
492  }
493 
494 
495 
496 
497 
498  BIASWARN("Create image pyramids ...");
500  theGauss.SetSigma(0.8);
501  _pim1.SetLowPassFilter(theGauss);
502  //_pim1.SetPyramidSize(ps);
503  _pgradim1x.SetLowPassFilter(theGauss);
504  //_pgradim1x.SetPyramidSize(ps);
505  _pgradim1y.SetLowPassFilter(theGauss);
506  //_pgradim1y.SetPyramidSize(ps);
507  _pim2.SetLowPassFilter(theGauss);
508  //_pim2.SetPyramidSize(ps);
509  _pgradim2x.SetLowPassFilter(theGauss);
510  //_pgradim2x.SetPyramidSize(ps);
511  _pgradim2y.SetLowPassFilter(theGauss);
512  //_pgradim2y.SetPyramidSize(ps);
513 
514  if (!_pim1.IsEmpty()) _pim1.Clear();
515  _pim1.Init(im1, ps);
516  if (!this->_pgradim1x.IsEmpty()) this->_pgradim1x.Clear();
517  this->_pgradim1x.Init(gradim1x, ps);
518  if (!this->_pgradim1y.IsEmpty()) this->_pgradim1y.Clear();
519  this->_pgradim1y.Init(gradim1y, ps);
520  if (!_pim2.IsEmpty()) _pim2.Clear();
521  _pim2.Init(im2, ps);
522  if (!_pgradim2x.IsEmpty()) _pgradim2x.Clear();
523  _pgradim2x.Init(gradim2x, ps);
524  if (!_pgradim2y.IsEmpty()) _pgradim2y.Clear();
525  _pgradim2y.Init(gradim2y, ps);
526 
527 
528 #ifdef BIAS_DEBUG
529  _pim1.WriteImages("pim1");
530  _pgradim1x.WriteImages("pgx1");
531  _pgradim1y.WriteImages("pgy1");
532  _pim2.WriteImages("pim2");
533  _pgradim2x.WriteImages("pgx2");
534  _pgradim2y.WriteImages("pgy2");
535 #endif
536 
537 
538 
539  BIASASSERT(_pim1.GetPositionOffset()==0.0);
540  Vector<double> apar(6);
541  bool lastconvergence = false;
542  do {
543  //cout<<"Cov2 is "<<Cov2<<endl;
544  apar[0] = *Axx;
545  apar[1] = *Axy;
546  apar[2] = *Ayx;
547  apar[3] = *Ayy;
548  apar[4] = result[0];
549  apar[5] = result[1];
550  BilinearRegion1_(p1[0], p1[1], hh, apar, Cov);
551 
552  KLT_TYPE ul_x = result[0] + *Axy * fhh - *Axx * fhw;
553  KLT_TYPE ul_y = result[1] + *Ayy * fhh - *Ayx * fhw;
554  KLT_TYPE ll_x = result[0] - *Axx * fhw - *Axy * fhh;
555  KLT_TYPE ll_y = result[1] - *Ayx * fhw - *Ayy * fhh;
556  KLT_TYPE ur_x = result[0] + *Axx * fhw + *Axy * fhh;
557  KLT_TYPE ur_y = result[1] + *Ayx * fhw + *Ayy * fhh;
558  KLT_TYPE lr_x = result[0] + *Axx * fhw - *Axy * fhh;
559  KLT_TYPE lr_y = result[1] + *Ayx * fhw - *Ayy * fhh;
560 
561  if ( ul_x < _minx2 || ul_x > _maxx2 ||
562  ll_x < _minx2 || ll_x > _maxx2 ||
563  ur_x < _minx2 || ur_x > _maxx2 ||
564  lr_x < _minx2 || lr_x > _maxx2 ||
565  ul_y < _miny2 || ul_y > _maxy2 ||
566  ll_y < _miny2 || ll_y > _maxy2 ||
567  ur_y < _miny2 || ur_y > _maxy2 ||
568  lr_y < _miny2 || lr_y > _maxy2) {
569  status = TRACKER_OUTOFIMAGE;
570  BIASDOUT( D_TRACKERB_KLT, "out of image");
571  break;
572  }
573 
574  // compute gradients and apply dev2_ to gradients
575  GetGradientWinAffine_(result[0], result[1],
576  *Axx, *Ayx , *Axy, *Ayy,
577  hw, hh, imgdiff, gradx, grady, Cov);
578 #ifdef BIAS_DEBUG
579  if (this->GetDebugLevel() & D_TRACKERB_AFFINE) {
580  stringstream ss;
581  ss<<"Af2_"<<setw(3)<<setfill('0')<<int(featurecounter)<<"-"
582  <<setw(4)<<setfill('0')<<int(iteration)<<"-";
583  string imname = ss.str();
584  Image<float> im1(2*hw+1, 2*hh+1), im2(2*hw+1, 2*hh+1);
585  im1.SetZero();
586  im2.SetZero();
587  for (int y=0; y<2*hh+1; y++) {
588  for (int x=0; x<2*hw+1; x++) {
589  im1.GetImageDataArray()[y][x] = float(_bl1[y][x]);
590  im2.GetImageDataArray()[y][x] = float(_bl2[y][x]);
591  }
592  }
593  //ImageIO::Save(imname+FileHandling::toString("1"), im1);
594  //ImageIO::Save(imname+FileHandling::toString("2"), im2);
595  ImageIO::Save(imname+FileHandling::toString("1"), im1);
596  ImageIO::Save(imname+FileHandling::toString("2"), im2);
597  }
598 #endif
599 
600  if (SimilarityTransformOnly){
601 
602  Compute4by1ErrorVector(imgdiff, gradx, grady, hw, hh, a);
603  Compute4by4GradientMatrix(gradx, grady, hw, hh, T);
604 
605  status = GaussJordanElimination(T,a);
606 
607  *Axx += a[0];
608  *Ayx += a[1];
609  *Ayy = *Axx;
610  *Axy = -(*Ayx);
611 
612  result[0] += dx = a[2];
613  result[1] += dy = a[3];
614 
615  BIASERR("no cov!");
616  BIASABORT;
617 
618  } else {
619 
620  Compute6by1ErrorVector(imgdiff, gradx, grady, hw, hh, a);
621  Compute6by6GradientMatrix(gradx, grady, hw, hh, T);
622 
623 
624 
625  msd = 0;
626  const unsigned int wh = width*height;
627  register KLT_TYPE* fw = imgdiff;
628  for (unsigned int h=0; h<wh ; h++) {
629  const KLT_TYPE cur = (KLT_TYPE)fabsf((float) (*fw) );
630  fw++;
631  msd += cur*cur;
632  }
633 
634  msd /= dev1_*dev1_;
635  // double sigma = msd / (double)(wh - SimilarityTransformOnly?4:6);
636  msd /= double(wh);
637  //SVD covsvd(T);
638  //too bad:
639  //Cov = covsvd.Invert() * sigma;
640 
641 
642  BIASDOUT(D_TRACKERB_KLT, "inhom. eq. system is "
643  <<setprecision(4)<<setw(6)<<T<<" "<< a);
644 
645  status = GaussJordanElimination(T,a);
646 
647  *Axx += a[0];
648  *Ayx += a[1];
649  *Axy += a[2];
650  *Ayy += a[3];
651 
652  result[0] += dx = a[4];
653  result[1] += dy = a[5];
654 
655 
656  Cov.SetZero();
657 #define DATHRESH 0.05
658  for (unsigned int i=0; i<4; i++) {
659  if (fabs(a[i])<DATHRESH) Cov[i][i] = 4.0*a[i]*a[i];
660  else Cov[i][i] = 4.0*DATHRESH*DATHRESH;
661  }
662 #define DXTHRESH 0.25
663  if (fabs(dx)<DXTHRESH) Cov[4][4] = 4.0*dx*dx;
664  else Cov[4][4]= 4.0*DXTHRESH*DXTHRESH;
665  if (fabs(dy)<DXTHRESH) Cov[5][5] = 4.0*dy*dy;
666  else Cov[5][5]= 4.0*DXTHRESH*DXTHRESH;
667 
668  cout<<"heuristic cov "<<Cov<<" and last cov "<<Cov2<<endl;
669  // make symmetric and average with 1/3 old cov from last iteration
670  for (unsigned int i=0; i<6; i++) {
671  for (unsigned int j=i; j<6; j++) {
672  Cov[i][j] = 0.25*(Cov[i][j]+Cov[j][i]+Cov2[i][j]+Cov2[j][i]);
673  }
674  }
675  for (unsigned int i=1; i<6; i++) {
676  for (unsigned int j=0; j<i; j++) {
677  Cov[i][j] = Cov[j][i];
678  }
679  }
680  // remember old cov for next iteration
681  Cov2 = Cov;
682  cout<<endl<<"Cov is now "<<Cov<<endl;
683 
684 
685 
686 
687  }
688  BIASDOUT(D_TRACKERB_KLT, "parameter update a is : "<< a);
689  double posdiag =
690  (*Axx + *Axy) * (*Axx + *Axy) + (*Ayx + *Ayy) * (*Ayx + *Ayy);
691 
692  double negdiag =
693  (*Axy - *Axx) * (*Axy - *Axx) + (*Ayy - *Ayx) * (*Ayy - *Ayx);
694 
695  double ratio = (posdiag>negdiag) ? negdiag / posdiag : posdiag / negdiag;
696 
697  // factor 3 is allowed
698  if (ratio < 0.09) {
699  status = TRACKER_ODDAFFINEWARP;
700  BIASDOUT(D_TRACKERB_KLT, "diag ratio is too big: "<< sqrt(ratio));
701  break;
702  }
703 
704  double scalex = (*Axx * *Axx) + (*Ayx * *Ayx);
705  double scaley = (*Ayy * *Ayy) + (*Axy * *Axy);
706 
707 
708  ratio = (scalex>scaley) ? scaley / scalex : scalex / scaley;
709  // factor 3 is allowed
710  if (ratio < 0.09) {
711  status = TRACKER_ODDAFFINEWARP;
712  BIASDOUT(D_TRACKERB_KLT, "axes ratio is too big: "<< sqrt(ratio));
713  break;
714  }
715 
716 
717  // old upper left corner - new upper left corner
718  ul_x -= result[0] - *Axx * fhw + *Axy * fhh;
719  ul_y -= result[1] - *Ayx * fhw + *Ayy * fhh;
720  // old lower left corner - new lower left corner
721  ll_x -= result[0] - *Axx * fhw - *Axy * fhh;
722  ll_y -= result[1] - *Ayx * fhw - *Ayy * fhh;
723  // old upper right corner - new upper right corner
724  ur_x -= result[0] + *Axx * fhw + *Axy * fhh;
725  ur_y -= result[1] + *Ayx * fhw + *Ayy * fhh;
726  // old lower right corner - new lower right corner
727  lr_x -= result[0] + *Axx * fhw - *Axy * fhh;
728  lr_y -= result[1] + *Ayx * fhw - *Ayy * fhh;
729 
730  convergence = (fabs(dx) < maxerr && fabs(dy) < maxerr &&
731  fabs(ul_x) < th_aff && fabs(ul_y) < th_aff &&
732  fabs(ll_x) < th_aff && fabs(ll_y) < th_aff &&
733  fabs(ur_x) < th_aff && fabs(ur_y) < th_aff &&
734  fabs(lr_x) < th_aff && fabs(lr_y) < th_aff);
735  if (convergence) {
736  if (!lastconvergence) {
737  // convergence is true for the first time, check another time with
738  // possibly more high-frequent image content
739  convergence = false;
740  lastconvergence = true;
741  Cov.SetZero();
742  // set small cov to see best resolution
743  for (int i=0; i<Cov.num_rows(); i++) {
744  Cov[i][i] = 0.0001;
745  }
746 
747  }
748  } else lastconvergence = false;
749 
750  if (status == TRACKER_NOSTRUCTURE) {
751  BIASDOUT( D_TRACKERB_KLT, "no structure for tracking");
752  break;
753  }
754  iteration++;
755  } while ( !convergence && iteration < max_iterations);
756  if (iteration >= max_iterations) {
757  status = TRACKER_TOOMANYITER;
758  BIASDOUT( D_TRACKERB_KLT, "too many iter: "<<iteration
759  <<" maxiter="<<max_iterations);
760  }
761  mad = 0;
762  msd = 0;
763  if ((status==TRACKER_TOOMANYITER) || (status==TRACKER_SUCCESS)) {
764 
765  // if we compute the difference here, we must check the range again
766 
767  const unsigned int wh = width*height;
768  register KLT_TYPE* fw = imgdiff;
769  for (unsigned int h=0; h<wh ; h++) {
770  const KLT_TYPE cur = (KLT_TYPE)fabsf((float) (*fw) );
771  fw++;
772  mad += cur;
773  msd += cur*cur;
774  }
775 
776  mad /= double(wh)*dev1_;
777  msd /= dev1_*dev1_;
778  double sigma = msd / (double)(wh - SimilarityTransformOnly?4:6);
779  msd /= double(wh);
780 
781  if (ComputeCovariance) {
782  if (SimilarityTransformOnly)
783  Compute4by4GradientMatrix(gradx, grady, hw, hh, T);
784  else
785  Compute6by6GradientMatrix(gradx, grady, hw, hh, T);
786  SVD covsvd(T);
787  Cov = covsvd.Invert() * sigma;
788  } else {
789  // pseudo covariance (last step size)
790  Cov.SetZero();
791  if (SimilarityTransformOnly) {
792  Cov[2][2] = dx * dx;
793  Cov[3][3] = dy * dy;
794  } else {
795  Cov[4][4] = dx * dx;
796  Cov[5][5] = dy * dy;
797  }
798  }
799  }
800 
801  error = (fabs(dx)>fabs(dy))?fabs(dx):fabs(dy);
802 
803  // Check whether window is out of bounds
804  if (result[0]<_minx2 || result[0] > _maxx2 ||
805  result[1]<_miny2 || result[1] > _maxy2)
806  status = TRACKER_OUTOFIMAGE;
807 
808 
809  // Free memory
810  delete imgdiff;
811  delete gradx;
812  delete grady;
813 
814  BIASDOUT( D_TRACKERB_KLT, "status at end is "<<status);
815 
816 
817 
818 
819  if (affineNormalization_) {
820 
821  HomgPoint2D hresult(result[0],result[1]);
822  Matrix3x3<double> R2i;
823 #ifdef BIASASSERT_ISACTIVE
824  int ires =
825 #endif
826  R2.GetInverse(R2i);
827  BIASASSERT(ires==0);
828  hresult = R2i * hresult;
829  oresult[0] = hresult[0];
830  oresult[1] = hresult[1];
831 
833  hresultA[0][0] = resultA[0][0];
834  hresultA[0][1] = resultA[0][1];
835  hresultA[1][0] = resultA[1][0];
836  hresultA[1][1] = resultA[1][1];
837 
838 
839 
840  hresultA = R2i * hresultA;
841 
842 
843  oresultA[0][0] = hresultA[0][0];
844  oresultA[0][1] = hresultA[0][1];
845  oresultA[1][0] = hresultA[1][0];
846  oresultA[1][1] = hresultA[1][1];
847 
848  BIASWARN("Covariance is not yet adapted to coordinate system transform!");
849 
850 
851 
852  } else {
853  oresult[0] = result[0];
854  oresult[1] = result[1];
855  oresultA = resultA;
856  }
857 
858 
859 
860 
861 
862  // Return appropriate value
863  return status;
864 }
865 
866 template <class StorageType>
868 EvaluateResult_(KLT_TYPE& mad, KLT_TYPE& msd, Matrix<KLT_TYPE>& CovMatrix) {
869  // these values have already been computed in the track_ function !!!
870  if (_SimilarityTransformOnly) {
871  CovMatrix.newsize(4,4);
872  } else {
873  CovMatrix.newsize(6,6);
874  }
875  CovMatrix = Cov_;
876 
877  mad = residuumMAD_;
878  msd = residuumMSD_;
879 }
880 
881 
882 /**********************************************************************
883 * CONSISTENCY CHECK OF FEATURES BY AFFINE MAPPING (BEGIN)
884 *
885 * Created by: Thorsten Thormaehlen (University of Hannover) June 2004
886 * thormae@tnt.uni-hannover.de
887 *
888 * Permission is granted to any individual or institution to use, copy, modify,
889 * and distribute this part of the software, provided that this complete
890 * authorship and permission notice is maintained, intact, in all copies.
891 *
892 * This software is provided "as is" without express or implied warranty.
893 *
894 *
895 */
896 
897 template <class StorageType>
899 GetGradientWinAffine_(const KLT_TYPE& x, const KLT_TYPE& y,
900  const KLT_TYPE& Axx, const KLT_TYPE& Ayx,
901  const KLT_TYPE& Axy, const KLT_TYPE& Ayy,
902  const int hw, const int hh,
903  KLT_TYPE* imgdiff,
904  KLT_TYPE* out_gradx,
905  KLT_TYPE* out_grady,
906  const Matrix<double>& Cov) {
907  BIASASSERT(!_ComputeFilteredImages);
908  const double maxLayer = _pgradim2x.size()-1;
909  Vector<double> apar(6);
910  apar[0] = Axx;
911  apar[1] = Axy;
912  apar[2] = Ayx;
913  apar[3] = Ayy;
914  apar[4] = x;
915  apar[5] = y;
916 
917  AffineTransform AT;
919  H[0][0] = apar[0];
920  H[0][1] = apar[1];
921  H[1][0] = apar[2];
922  H[1][1] = apar[3];
923  H[0][2] = apar[4];
924  H[1][2] = apar[5];
925  H[2][2] = 1.0;
926 #ifdef BIASASSERT_ISACTIVE
927  int ires =
928 #endif
929  H.GetInverse(tmp);
930  BIASASSERT(ires==0);
931  H = tmp;
932  AT.A_[0][0] = H[0][0];
933  AT.A_[0][1] = H[0][1];
934  AT.A_[1][0] = H[1][0];
935  AT.A_[1][1] = H[1][1];
936  AT.tx_ = H[0][2];
937  AT.ty_ = H[1][2];
938  cout<<"inverted A is "<<H<<endl;
939  Vector<double> offset;
940  Matrix<double> dstcov;
941 
942  // if detATA>1 smooth this image to avoid aliasing, because the template
943  // in image one is smaller than this
944  double basesmooth = GetBaseLevel(apar, false);
945  cout<<"basesmooth for image 2 is "<<basesmooth<<" with apar "<<apar<<endl;
946  {
947  register int i, j;
948  BIASASSERT(hh==hw);
949  KLT_TYPE* imgdifforig = imgdiff;
950 
951  mean1_ = mean2_ = 0;
952  BIASASSERT(_bl1.num_rows()==_bl1.num_cols());
953  BIASASSERT(_bl1.num_rows()==2*hw+1);
954  KLT_TYPE mi,mj;
955  KLT_TYPE *pbl1 = _bl1.GetData();
956  KLT_TYPE *pbl2 = _bl2.GetData();
957  cout<<"image 2 scales for apar "<<apar<<endl;
958  for (j = -hh ; j <= hh ; j++) {
959  for (i = -hw ; i <= hw ; i++) {
960 
961 
962  Matrix<double> pt(2,6, MatrixZero);
963  pt[0][0] = pt[1][2] = i;
964  pt[0][1] = pt[1][3] = j;
965  pt[0][4] = pt[1][5] = 1.0;
966  dstcov = pt * Cov * pt.Transpose();
967 
968  /////////// pyramid layer
969  //AT.dx_ = i;
970  //AT.dy_ = j;
971  //AT.Transform(apar,Cov, offset,dstcov);
972 
973 
974 
975  if (fabs(float(i+j))==hh+hw) {
976  cout<<apar<<" with cov "<<Cov<<" maps "<<i<<";"
977  <<j<<" with cov "<<dstcov<<endl;
978  }
979  // d==0.5 => use layer 0
980  double layer = log2(sqrt(dstcov.Trace()));
981  cout<<fixed<<setprecision(2)<<setw(6)<< layer <<" ";
982  if (layer<=0.0) layer = basesmooth;
983  else layer += basesmooth;
984  if (layer>maxLayer) layer=maxLayer;
985 
986  const double scale = 1.0/exp2(rint(layer));
987  /////////// pyramid layer
988 
989  mi = x + Axx * i + Axy * j;
990  mj = y + Ayx * i + Ayy * j;
991 
992 
993  if (_pim2[int(rint(layer))]->IsInROI(scale*mi, scale*mj) &&
994  (this->_bl1[hh+j][hw+i]>INVALID_PIXEL)) {
995 
996  _pim2.GetTrilinearImageValue(mi, mj, layer, *pbl2);
997  mean2_ += *pbl2;
998  BIASASSERT(!BIAS_ISINF(*pbl2));
999  *imgdiff = *pbl1++ - *pbl2++;
1000  } else {
1001  pbl1++;
1002  *pbl2++ = INVALID_PIXEL;
1003  *imgdiff = 0;
1004  }
1005  //cout<<setprecision(2)<<setw(5)<<*imgdiff<<" ";
1006 
1007  imgdiff++;
1008  }
1009  cout<<endl;
1010  }
1011 
1012  if (_AffineBrightnessInvariance) {
1013  pbl2 = _bl2.GetData();
1014  const KLT_TYPE thearea = (2*hh+1)*(2*hw+1);
1015  mean2_ /= thearea;
1016  dev2_ = 0;
1017  double diff;
1018  for (j = -hh ; j <= hh ; j++)
1019  for (i = -hw ; i <= hw ; i++) {
1020  diff = (*pbl2++ -= mean2_);
1021  dev2_ += diff * diff;
1022  }
1023  if (fabs(dev2_)>1e-10) dev2_ = sqrt(thearea / dev2_);
1024  else dev2_ = 1.0;
1025  imgdiff = imgdifforig;
1026  pbl1 = _bl1.GetData();
1027  pbl2 = _bl2.GetData();
1028  for (j = -hh ; j <= hh ; j++) {
1029  for (i = -hw ; i <= hw ; i++) {
1030  *imgdiff++ =(*pbl1++) - (*pbl2++ *= dev2_);
1031  }
1032  }
1033  }
1034  }
1035 
1036  register int i, j;
1037  KLT_TYPE mi, mj;
1038  if (_AffineBrightnessInvariance) {
1039  BIASWARN("no smoothing yet!");
1040  BIASABORT;
1041  for (j = -hh ; j <= hh ; j++) {
1042  for (i = -hw ; i <= hw ; i++) {
1043  mi = Axx * i + Axy * j;
1044  mj = Ayx * i + Ayy * j;
1045 
1046  // normalize by precomputed dev2_
1047  *out_gradx++ = _gradim2x->FastBilinearInterpolationGrey(x+mi,
1048  y+mj)*dev2_;
1049  *out_grady++ = _gradim2y->FastBilinearInterpolationGrey(x+mi,
1050  y+mj)*dev2_;
1051  }
1052  }
1053  } else {
1054  cout<<"Image 2 accesses: "<<endl;
1055  for (j = -hh ; j <= hh ; j++) {
1056  for (i = -hw ; i <= hw ; i++) {
1057 
1058  /////////// pyramid layer
1059  AT.dx_ = i;
1060  AT.dy_ = j;
1061  AT.Transform(apar,Cov, offset,dstcov);
1062  // d==0.5 => use layer 0
1063  double layer = log2(sqrt(dstcov.Trace()))+basesmooth;
1064  //cout<<setprecision(2)<<setw(4)<<"["<<layer<<":] ";
1065 
1066  if (layer<=0.0) layer = 0;
1067  if (layer>maxLayer) layer=maxLayer;
1068 
1069  const double scale = 1.0/exp2(layer);
1070  /////////// pyramid layer
1071 
1072  mi = x + Axx * i + Axy * j;
1073  mj = y + Ayx * i + Ayy * j;
1074 
1075  if (_pgradim2x[int(rint(layer))]->IsInROI(scale*mi, scale*mj) &&
1076  (this->_bl1[hh+j][hw+i]>INVALID_PIXEL)) {
1077  double tmp;
1078  _pgradim2x.GetTrilinearImageValue(mi,mj, layer, tmp);
1079  *out_gradx = scale * tmp;
1080  _pgradim2y.GetTrilinearImageValue(mi,mj, layer, tmp);
1081  *out_grady = scale * tmp;
1082  } else {
1083  *out_gradx = 0;
1084  *out_grady = 0;
1085  }
1086  //cout<<setprecision(2)<<setw(4)<< *out_gradx <<" "<< *out_grady<<" ";
1087  out_gradx++;
1088  out_grady++;
1089  }
1090  cout<<endl;
1091  }
1092  }
1093 
1094 }
1095 }//end namespace BIAS
1096 
1097 /**************** end affine part ********************************/
1098 
1099 
1100 //////////////////////////////////////////////////////////////////////////
1101 // instantiation
1102 //////////////////////////////////////////////////////////////////////////
1103 namespace BIAS{
1104 template class BIASMatcher2D_EXPORT TrackerBaseAffine2<unsigned char>;
1105 template class BIASMatcher2D_EXPORT TrackerBaseAffine2<float>;
1106 
1107 // fill in instances as required
1108 #ifdef BUILD_IMAGE_INT
1109 template class TrackerBaseAffine2<int>;
1110 #endif
1111 #ifdef BUILD_IMAGE_CHAR
1112 template class TrackerBaseAffine2<char>;
1113 #endif
1114 #ifdef BUILD_IMAGE_SHORT
1115 template class TrackerBaseAffine2<short>;
1116 #endif
1117 #ifdef BUILD_IMAGE_USHORT
1118 template class TrackerBaseAffine2<unsigned short>;
1119 #endif
1120 }
devel version of antialiased affine tracker
void SetIdentity()
set the elements of this matrix to the identity matrix
Definition: Matrix2x2.hh:251
void Compute4by4GradientMatrix(KLT_TYPE *gradx, KLT_TYPE *grady, const int hw, const int hh, BIAS::Matrix< KLT_TYPE > &T)
void Compute6by6GradientMatrix(KLT_TYPE *gradx, KLT_TYPE *grady, const int hw, const int hh, BIAS::Matrix< KLT_TYPE > &T)
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Definition: SVD.hh:92
virtual int Track_(Vector2< KLT_TYPE > &p1, Vector2< KLT_TYPE > &p2, Vector2< KLT_TYPE > &result, KLT_TYPE &error, int &iter, const Matrix2x2< KLT_TYPE > &AffinePred, Matrix2x2< KLT_TYPE > &AffineResult)
Interface of all tracking algorithms implemented in derived classes.
point slid out of image
Matrix< T > Transpose() const
transpose function, storing data destination matrix
Definition: Matrix.hh:823
double GetBaseLevel(const Vector< double > &apar, bool backdirection)
int TrackAffine_(KLT_TYPE p1[2], KLT_TYPE p2[2], const Matrix2x2< KLT_TYPE > &p2A, KLT_TYPE result[2], Matrix2x2< KLT_TYPE > &resultA, KLT_TYPE &error, int &iter, Matrix< KLT_TYPE > &Cov, KLT_TYPE &mad, KLT_TYPE &msd, bool SimilarityTransformOnly=false, bool ComputeCovariance=true)
track using affine warp
Matrix< T > & newsize(Subscript M, Subscript N)
Definition: cmat.h:269
void GetGradientWinAffine_(const KLT_TYPE &x, const KLT_TYPE &y, const KLT_TYPE &Axx, const KLT_TYPE &Ayx, const KLT_TYPE &Axy, const KLT_TYPE &Ayy, const int halfwidth, const int halfheight, KLT_TYPE *imgdiff, KLT_TYPE *out_gradx, KLT_TYPE *out_grady, const Matrix< double > &Cov)
const T * GetData() const
get the data pointer the member function itself is const (before {..}) because it doesn&#39;t change the ...
Definition: Vector2.hh:236
long int ComputeCovariance(long int NumErrors, long int NumParams, double *Jac, int *Permutation, double &SumOfSquaredErrors, Matrix< double > &Cov)
Compute covariance matrix from Levenberg-Marquardt resulting Jacobian matrix J(x) and permutation mat...
Definition: Minpack.cpp:289
void BilinearRegion1_(KLT_TYPE x, KLT_TYPE y, int hws, const Vector< double > &par, const Matrix< double > &Cov)
Vector< T > & newsize(Subscript N)
Definition: vec.h:220
success (error &lt; maxerror)
void SetZero()
Sets all values to zero.
Definition: Matrix.hh:856
no spatial structure is present
int GetInverse(Matrix3x3< T > &inv) const
Matrix inversion: inverts this and stores resulty in argument inv.
Definition: Matrix3x3.cpp:373
affine warp seems degenerated
virtual void EvaluateResult_(KLT_TYPE &mad, KLT_TYPE &msd, Matrix< KLT_TYPE > &cov)
fill in computed residui from Track_
void SetSigma(const double si)
Definition: Gauss.hh:162
int GaussJordanElimination(BIAS::Matrix< KLT_TYPE > &a, BIAS::Vector< KLT_TYPE > &b)
Maps image src to image sink with affine transformation.
const Vector< double > & GetS() const
return S which is a vector of the singular values of A in descending order.
Definition: SVD.hh:167
The image template class for specific storage types.
Definition: Image.hh:78
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
Definition: ImageIO.cpp:725
int MapDirect(const Image< InputStorageType > &src, Image< OutputStorageType > &sink)
direct, fast implementation of affine backward mapping with anisotropic filtering, one channel grey only
static std::string toString(const T thenumber, int numzeros=DEFAULT_LEADING_ZEROS)
Converts number to string with leading zeros.
Definition: FileHandling.hh:98
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
void Compute4by1ErrorVector(KLT_TYPE *imgdiff, KLT_TYPE *gradx, KLT_TYPE *grady, const int hw, const int hh, BIAS::Vector< KLT_TYPE > &e)
void Compute6by1ErrorVector(KLT_TYPE *imgdiff, KLT_TYPE *gradx, KLT_TYPE *grady, const int hw, const int hh, BIAS::Vector< KLT_TYPE > &e)
Matrix< double > Invert()
returns pseudoinverse of A = U * S * V^T A^+ = V * S^+ * U^T
Definition: SVD.cpp:214
uses the unscented transformation to map a normal distribututed random variable using a nonlinear tra...
T Trace() const
Definition: Matrix.hh:903
Subscript num_rows() const
Definition: cmat.h:319
double NormFrobenius() const
Return Frobenius norm = sqrt(trace(A^t * A)).
Definition: Matrix.hh:897
void SetAffineTransformation(const double &a11, const double &a12, const double &a21, const double &a22, const double &dx, const double &dy)
set A (source = A * sink) before calling Map()
void GetSystemMatrix(Matrix< T > &dest) const
compute square system matrix dest = A^T * A
Definition: Matrix.hh:1075
TrackerBaseAffine2(bool only4params=false)
void SetZero()
zeroes the image
Definition: ImageBase.hh:83
Subscript size() const
Definition: vec.h:262
maxiter is reached and error is above maxerror
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153