27 #include "TrackerBaseSimple.hh"
28 #include "TrackerBaseAffine.hh"
29 #include "TrackerBaseAffine2.hh"
30 #include "TrackerBaseHomography.hh"
31 #include "TrackerBaseWeighted.hh"
32 #include "TrackerBaseWeighted1D.hh"
33 #include <Base/Image/ImageIO.hh>
34 #include <Base/Common/BIASpragma.hh>
35 #include <Base/Image/ImageConvert.hh>
36 #include <Filter/GradientSobel3x3.hh>
37 #include <Filter/Binomial.hh>
41 #include <Base/Debug/TimeMeasure.hh>
48 double totalitersum=0.0;
58 template <
class StorageType,
class CalculationType>
62 SetTrackerType(tracker_type);
66 MaxIter_.newsize(DFLT_PYSIZE);
67 for (
int i=0; i<DFLT_PYSIZE; i++) MaxIter_[i]=5;
69 HalfWinSize_.newsize(DFLT_PYSIZE);
70 for (
int i=0; i<DFLT_PYSIZE; i++) HalfWinSize_[i]=3;
72 MaxError_.newsize(DFLT_PYSIZE);
73 for (
int i=0; i<DFLT_PYSIZE; i++) MaxError_[i]=0.1;
75 MaxResiduumMAD_.newsize(DFLT_PYSIZE);
76 for (
int i=0; i<DFLT_PYSIZE; i++) MaxResiduumMAD_[i]=10.0;
78 UseCoarserPointIfLost_ =
false;
94 template <
class StorageType,
class CalculationType>
102 template <
class StorageType,
class CalculationType>
112 if (LastImage_) {
delete LastImage_; LastImage_ = NULL; }
113 if (LastGradX_) {
delete LastGradX_; LastGradX_ = NULL; }
114 if (LastGradY_) {
delete LastGradY_; LastGradY_ = NULL; }
125 template <
class StorageType,
class CalculationType>
130 PredictedPoints_.clear();
132 DisplInLastIter_.clear();
139 template <
class StorageType,
class CalculationType>
143 if (Points_.size() != (unsigned)pysize){
144 Points_.resize(pysize);
145 PredictedPoints_.resize(pysize);
146 NumIter_.resize(pysize);
147 DisplInLastIter_.resize(pysize);
148 ResiduiMAD_.resize(pysize);
149 ResiduiMSD_.resize(pysize);
152 AffineResults_.resize(pysize);
156 template <
class StorageType,
class CalculationType>
160 ResizeInternals_(pysize);
163 if ((
int)Points_[PyIndex_].size() != num_points){
165 p2tracked_.resize(num_points, pz);
166 AffinePrediction_.resize(num_points);
167 for (
int p = PyIndex_; p < pysize; p++){
168 res_[p].resize(num_points);
169 Points_[p].resize(num_points);
170 PredictedPoints_[p].resize(num_points);
171 NumIter_[p].resize(num_points);
172 DisplInLastIter_[p].resize(num_points);
173 ResiduiMAD_[p].resize(num_points);
174 ResiduiMSD_[p].resize(num_points);
175 Cov_[p].resize(num_points);
176 AffineResults_[p].resize(num_points);
181 template <
class StorageType,
class CalculationType>
185 int pyindex = PyIndex_;
186 for (
int p=pyindex; p<pysize; p++){
187 res_[p].reserve(newsize);
188 Points_[p].reserve(newsize);
189 PredictedPoints_[p].reserve(newsize);
190 NumIter_[p].reserve(newsize);
191 DisplInLastIter_[p].reserve(newsize);
192 ResiduiMAD_[p].reserve(newsize);
193 ResiduiMSD_[p].reserve(newsize);
194 Cov_[p].reserve(newsize);
195 AffineResults_[p].resize(newsize);
200 template <
class StorageType,
class CalculationType>
205 ReplaceLastImages(NULL, NULL, NULL);
208 template <
class StorageType,
class CalculationType>
212 BIASASSERT(LastImage_ && LastGradX_ && LastGradY_);
213 (*LastImage_)[PyIndex_]->GetROI()->GetCorners(tlx, tly, brx, bry);
214 int gxtlx, gxtly, gxbrx, gxbry;
215 (*LastGradX_)[PyIndex_]->GetROI()->GetCorners(gxtlx, gxtly, gxbrx, gxbry);
216 int gytlx, gytly, gybrx, gybry;
217 (*LastGradY_)[PyIndex_]->GetROI()->GetCorners(gytlx, gytly, gybrx, gybry);
219 tlx = max(tlx, max(gxtlx, gytlx));
220 tly = max(tly, max(gxtly, gytly));
221 brx = min(brx, min(gxbrx, gybrx));
222 bry = min(bry, min(gxbry, gybry));
224 tlx += HalfWinSize_[PyIndex_];
225 tly += HalfWinSize_[PyIndex_];
226 brx -= HalfWinSize_[PyIndex_];
227 bry -= HalfWinSize_[PyIndex_];
231 template <
class StorageType,
class CalculationType>
234 const vector<float>& qual)
237 int lpx, lpy, gx, gy;
238 LowpassFM_.GetSize(lpx, lpy);
239 GradXFM_.GetSize(gx, gy);
241 max((lpx-1)/2, (lpy-1)/2) +
242 max((gx-1)/2, (gy-1)/2) +
243 HalfWinSize_[PyIndex_];
246 BIASASSERT(LastImage_!=NULL);
247 BIASASSERT(Points_.size()>0);
248 const int pysize=(int)LastImage_->size();
249 const double factor=1.0/LastImage_->GetRescaleFactor();
250 const double offset=LastImage_->GetPositionOffset();
251 int numnew=points.size();
252 const int size=Points_[0].size();
253 const int pyindex=PyIndex_;
256 BIASCDOUT(D_TRACKER_INIT,
"min distance to image border "
257 <<MinBorderDist<<endl);
258 int tlx, tly, brx, bry;
259 (*LastImage_)[pyindex]->GetROI()->GetCorners(tlx, tly, brx, bry);
260 const double minx=MinBorderDist+tlx;
261 const double miny=MinBorderDist+tly;
262 const double maxx=brx-MinBorderDist;
263 const double maxy=bry-MinBorderDist;
266 BIASCDOUT(D_TRACKER_FILL_UP,
"minx" << minx <<
"miny" << miny <<
267 "maxx" << maxx <<
"maxy" << maxy << endl);
270 while (n<numnew && (points[n].IsAtInfinity() ||
271 !(points[n][0]>minx && points[n][1]>miny &&
272 points[n][0]<maxx && points[n][1]<maxy)))
276 BIASCDOUT(D_TRACKER_FILL_UP,
"next new point is "<<points[n]<<endl);
278 for (
int i=0; i<size; i++){
280 if (Points_[pyindex][i].IsAtInfinity()){
283 BIASCDOUT(D_TRACKER_FILL_UP, setw(3)<<i<<
" : replacing "
284 <<Points_[pyindex][i]<<
" with "<<p2d<<endl);
285 for (
int p=pyindex; p<pysize; p++){
288 DisplInLastIter_[p][i]=-1.0;
289 ResiduiMAD_[p][i]=-1.0;
290 ResiduiMSD_[p][i]=-1.0;
295 res_[p][i]=(int)rint(qual[n]);
299 while (n<numnew && ( points[n].IsAtInfinity() ||
300 !(points[n][0]>minx && points[n][1]>miny &&
301 points[n][0]<maxx && points[n][1]<maxy)))
305 BIASCDOUT(D_TRACKER_FILL_UP,
"next new point is "<<points[n]<<endl);
309 BIASCDOUT(D_TRACKER_FILL_UP, setw(3)<<i<<
" : "<<Points_[pyindex][i]
310 <<
" is still valid: ");
311 for (
int p=pyindex+1; p<pysize; p++){
312 BIASCDOUT(D_TRACKER_FILL_UP, p<<
": "<<Points_[p][i]);
314 BIASCDOUT(D_TRACKER_FILL_UP, endl);
319 BIASCDOUT(D_TRACKER_FILL_UP,
"not enought points in points "
328 template <
class StorageType,
class CalculationType>
331 const vector<float>& qual)
333 assert(
"deprecated, uese ReplaceAllPoints instead" &&
false);
335 BIASASSERT(LastImage_!=NULL);
336 BIASASSERT(Points_.size()>0);
337 const int pysize=(int)LastImage_->size();
338 const double factor=1.0/LastImage_->GetRescaleFactor();
339 const double offset=LastImage_->GetPositionOffset();
340 const int numnew=points.size();
341 #ifdef BIASASSERT_ISACTIVE
342 const int size=Points_[0].size();
343 BIASASSERT(size==numnew);
345 const int pyindex=PyIndex_;
351 while (n<numnew && points[n].IsAtInfinity()) n++;
354 BIASCDOUT(D_TRACKER_FILL_UP,
"next new point is "<<points[n]<<endl);
358 BIASCDOUT(D_TRACKER_FILL_UP, setw(3)<<n<<
" : replacing "
359 <<Points_[pyindex][n]<<
" with "<<p2d<<endl);
360 for (
int p=pyindex; p<pysize; p++){
363 DisplInLastIter_[p][n]=-1.0;
364 ResiduiMAD_[p][n]=-1.0;
365 ResiduiMSD_[p][n]=-1.0;
370 res_[p][n]=(int)rint(qual[n]);
376 BIASCDOUT(D_TRACKER_FILL_UP,
"replaced "<<num<<
" points"<<endl);
381 template <
class StorageType,
class CalculationType>
384 const vector<float>& qual)
387 BIASASSERT(LastImage_!=NULL);
388 const int numnew=points.size();
389 const int pysize=(int)LastImage_->size();
390 const double factor=1.0/LastImage_->GetRescaleFactor();
391 const double offset=LastImage_->GetPositionOffset();
392 const int pyindex=PyIndex_;
394 if ((
int)Points_.size() != pysize || (int)Points_[pyindex].size()!=numnew) {
396 ResizeInternals_(pysize, numnew);
402 for (
int n=0; n<numnew; n++){
406 BIASCDOUT(D_TRACKER_FILL_UP, setw(3)<<n<<
" : replacing "
407 <<Points_[pyindex][n]);
408 for (
int p=pyindex; p<pysize; p++){
409 res_[p][n] = (int)rint(qual[n]);
411 PredictedPoints_[p][n] = p2d;
412 BIASASSERT(!Points_[p][n].IsAtInfinity());
413 BIASASSERT(!PredictedPoints_[p][n].IsAtInfinity());
415 DisplInLastIter_[p][n] = -1.0;
416 ResiduiMAD_[p][n] = -1.0;
417 ResiduiMSD_[p][n] = -1.0;
418 Cov_[p][n] = zero2x2;
425 BIASCDOUT(D_TRACKER_FILL_UP,
" with "<<Points_[pyindex][n]<<endl);
427 BIASCDOUT(D_TRACKER_FILL_UP,
"replaced "<<numnew<<
" points"<<endl);
436 static int Tracker_GlobalImageCounter=0;
439 template <
class StorageType,
class CalculationType>
460 const unsigned py_size = pim.
size();
465 pim.
Init(im2,py_size);
489 cerr <<
"initializing pyramid images took "<<timer.
GetRealTime()<<
" us\n";
496 if (DebugLevelIsSet(D_TRACKER_WRITE_IM)){
498 os <<
"input-im"<<setw(3)<<setfill(
'0')<<Tracker_GlobalImageCounter
503 BIASERR(
"error writing "<<os.str());
511 if((fres=lowpass.
Filter(im, *(pim[0])))!=0){
512 BIASERR(
"filtering failed "<<fres);
517 if (DebugLevelIsSet(D_TRACKER_WRITE_IM)){
519 os <<
"pyim-lowpass-im"<<setw(3)<<setfill(
'0')<<Tracker_GlobalImageCounter
520 <<
"-pyind"<<setw(1)<<setfill(
'0')<<0<<
".mip";
523 BIASERR(
"error writing "<<os.str());
531 cerr <<
"lowpass took "<<timer.
GetRealTime()<<
" us\n";
540 cerr <<
"downsampling took "<<timer.
GetRealTime()<<
" us\n";
545 const int pysize=pim.
size();
546 for (
int p=0; p<pysize; p++){
547 if((gres=grad.
Filter(*pim[p], *gx[p], *gy[p]))!=0){
548 BIASERR(
"gradient failed "<<gres);
552 if (DebugLevelIsSet(D_TRACKER_WRITE_IM)){
554 os <<
"pyim-im"<<setw(3)<<setfill(
'0')<<Tracker_GlobalImageCounter
555 <<
"-pyind"<<setw(1)<<setfill(
'0')<<p<<
".mip";
558 BIASERR(
"error writing "<<os.str());
561 os <<
"pygx-im"<<setw(3)<<setfill(
'0')<<Tracker_GlobalImageCounter
562 <<
"-pyind"<<setw(1)<<setfill(
'0')<<p<<
".mip";
565 BIASERR(
"error writing "<<os.str());
568 os <<
"pygy-im"<<setw(3)<<setfill(
'0')<<Tracker_GlobalImageCounter
569 <<
"-pyind"<<setw(1)<<setfill(
'0')<<p<<
".mip";
572 BIASERR(
"error writing "<<os.str());
578 Tracker_GlobalImageCounter++;
582 cerr <<
"gradients took "<<timer.
GetRealTime()<<
" us\n";
586 return (fres==0 && gres==0)?0:-1;
589 template <
class StorageType,
class CalculationType>
599 const unsigned py_size = pim.
size();
618 template <
class StorageType,
class CalculationType>
627 return PreparePyramide(im, pim, gx, gy, grad, lowpass);
630 template <
class StorageType,
class CalculationType>
634 return Track(pim, Points_[PyIndex_]);
637 template <
class StorageType,
class CalculationType>
640 const vector<HomgPoint2D>& prediction,
648 const int pysize=(int)pim.
size();
656 BIASASSERT(PyIndex_>=0 && PyIndex_<pysize);
660 if ((&pim)==LastImage_){
661 BIASERR(
"do not remove image between successive calls of Track\n"
662 <<&pim<<
"!="<<LastImage_);
666 BIASASSERT((&pim)!=LastImage_);
668 if (DebugLevelIsSet(D_TRACKER_IMAGES)){
669 pim.
WriteImages(
"act-py"); LastImage_->WriteImages(
"last-py");
673 const int pyindex=PyIndex_;
674 const int nump=Points_[pyindex].size();
677 PredictedPoints_[pyindex]=prediction;
679 const double ifac=1.0/factor;
680 for (
int p=pyindex+1; p<pysize; p++){
681 for (
int i=0; i<nump; i++){
682 Points_[p][i][0]=(Points_[p-1][i][0]-offset)*ifac;
683 Points_[p][i][1]=(Points_[p-1][i][1]-offset)*ifac;
684 PredictedPoints_[p][i][0]=(PredictedPoints_[p-1][i][0]-offset)*ifac;
685 PredictedPoints_[p][i][1]=(PredictedPoints_[p-1][i][1]-offset)*ifac;
691 if ((
int)AffinePred.size()==nump) {
693 AffinePrediction_ = AffinePred;
696 AffinePrediction_.resize(nump);
697 for (
int i=0; i<nump; i++) {
698 AffinePrediction_[i].SetIdentity();
705 cerr <<
"initializing "<<nump<<
" points took "<<timer.
GetRealTime()<<
" us\n";
711 for (
int p=pysize-1;p>=pyindex; p--){
712 BIASCDOUT(D_TRACKER_TRACK,
"---- pyramid level "<<p<<
" ----\n");
714 tb_->SetHalfWinSize(HalfWinSize_[p]);
715 tb_->SetMaxIterations(MaxIter_[p]);
716 tb_->SetMaxError(MaxError_[p]);
717 tb_->SetMaxResiduumMAD(MaxResiduumMAD_[p]);
720 if ((
int)WeightMatrices_.size() == pysize)
722 tb_->SetWeightMatrix(WeightMatrices_[p]);
726 if (DebugLevelIsSet(D_TRACKER_IMAGES)){
727 pim.
WriteImages(
"act1-py"); LastImage_->WriteImages(
"last1-py");
729 tb_->Init(*(*LastImage_)[p], *pim[p], LowpassFM_,
733 cerr <<
"initializing tb took "<<timer.
GetRealTime()<<
" us\n";
738 tb_->Track(Points_[p], PredictedPoints_[p], p2tracked_,
739 DisplInLastIter_[p], NumIter_[p], ResiduiMAD_[p],
740 ResiduiMSD_[p], res_[p],Cov_[p], AffinePrediction_,
745 AffinePrediction_ = AffineResults_[p];
750 cerr <<
"tracking tb took "<<timer.
GetRealTime()<<
" us\n";
756 for (
int i=0; i<nump; i++){
757 BIASCDOUT(D_TRACKER_TRACK, setw(3)<<i<<
" ("<<Points_[p][i][0]<<
", "
758 <<Points_[p][i][1]<<
") <--> ("<<PredictedPoints_[p][i][0]
759 <<
", "<<PredictedPoints_[p][i][1]<<
") ");
761 Points_[p][i]=p2tracked_[i];
762 BIASCDOUT(D_TRACKER_TRACK,
" -> ("<<p2tracked_[i][0]<<
", "
763 <<p2tracked_[i][1]<<
") in "<<NumIter_[p][i]
764 <<
" iterations with err "<<DisplInLastIter_[p][i]
765 <<
" code "<<res_[p][i]
766 <<
" residuumMAD "<<ResiduiMAD_[p][i]
767 <<
" residuumMSD "<<ResiduiMSD_[p][i]<<endl);
771 PredictedPoints_[p-1][i][0]=Points_[p][i][0]*factor+offset;
772 PredictedPoints_[p-1][i][1]=Points_[p][i][1]*factor+offset;
775 BIASCDOUT((D_TRACKER_ERROR | D_TRACKER_TRACK),
" error tracking: "
776 <<Points_[p][i]<<
" on py level "<<p<<
" result code "
783 if ( UseCoarserPointIfLost_ &&
784 (p!=(pysize-1) && res_[p+1][i]>=0 && p!=pyindex) ) {
785 PredictedPoints_[p-1][i][0]=Points_[p+1][i][0]*factor+offset;
786 PredictedPoints_[p-1][i][1]=Points_[p+1][i][1]*factor+offset;
788 if (res_[p+1][i]!=0){
789 res_[p][i]=res_[p+1][i];
790 NumIter_[p][i]=NumIter_[p+1][i];
791 DisplInLastIter_[p][i]=DisplInLastIter_[p+1][i]*factor;
792 ResiduiMAD_[p][i]=ResiduiMAD_[p+1][i];
793 ResiduiMSD_[p][i]=ResiduiMSD_[p+1][i];
799 Cov_[p][i]=(factor*factor)*Cov_[p+1][i];
803 for (
int k=pyindex; k<pysize; k++)
804 Points_[k][i][2]=0.0;
811 cerr <<
"checking results of tb took "<<timer.
GetRealTime()<<
" us\n";
817 if (DebugLevelIsSet(D_TRACKER_NUMITER)){
820 for (
unsigned h=0; h<NumIter_[p].size(); h++)
821 itersum+=NumIter_[p][h];
824 totalitersum+=itersum;
825 BIASCDOUT(D_TRACKER_NUMITER,
"totalitersum "<<totalitersum<<endl);
834 cerr <<
"propagating result codes through pyramide took "<<timer.
GetRealTime()<<
" us\n";
841 if (DebugLevelIsSet(D_TRACKER_WRITE_IM)){
847 LastImage_->GetSingleImage(wim);
855 BIASCDOUT(D_TRACKER_TRACK,
"initialization call\n");
858 ReplaceLastImages(&pim, NULL, NULL);
862 cerr <<
"updateing iternals took "<<timer.
GetRealTime()<<
" us\n";
872 template <
class StorageType,
class CalculationType>
878 return Track(pim, gradx, grady, Points_[PyIndex_]);
881 template <
class StorageType,
class CalculationType>
886 const vector<HomgPoint2D>& prediction,
894 const int pysize=(int)pim.
size();
902 BIASASSERT(PyIndex_>=0 && PyIndex_<pysize);
904 if (LastImage_ && LastGradX_ && LastGradY_){
906 if ((&pim)==LastImage_ || (&gradx)==LastGradX_ || (&grady)==LastGradY_ ){
912 BIASERR(
"do not remove image between successive calls of Track\n"
913 <<&pim<<
"!="<<LastImage_<<
","<<&gradx<<
"!="
914 <<LastGradX_<<
","<<&grady<<
"!="<<LastGradY_);
916 BIASASSERT((&pim)!=LastImage_ && (&gradx)!=LastGradX_ &&
917 (&grady)!=LastGradY_ );
918 if (DebugLevelIsSet(D_TRACKER_IMAGES)){
919 pim.
WriteImages(
"act-py"); LastImage_->WriteImages(
"last-py");
920 gradx.
WriteImages(
"act-gx"); LastGradX_->WriteImages(
"last-gx");
921 grady.
WriteImages(
"act-gy"); LastGradY_->WriteImages(
"last-gy");
928 const int pyindex=PyIndex_;
929 const int nump=Points_[pyindex].size();
932 PredictedPoints_[pyindex]=prediction;
934 const double ifac=1.0/factor;
935 for (
int p=pyindex+1; p<pysize; p++){
936 for (
int i=0; i<nump; i++){
937 Points_[p][i][0]=(Points_[p-1][i][0]-offset)*ifac;
938 Points_[p][i][1]=(Points_[p-1][i][1]-offset)*ifac;
939 PredictedPoints_[p][i][0]=(PredictedPoints_[p-1][i][0]-offset)*ifac;
940 PredictedPoints_[p][i][1]=(PredictedPoints_[p-1][i][1]-offset)*ifac;
946 if ((
int)AffinePred.size()==nump) {
948 AffinePrediction_ = AffinePred;
951 AffinePrediction_.resize(nump);
952 for (
int i=0; i<nump; i++) {
953 AffinePrediction_[i].SetIdentity();
960 cerr <<
"initializing "<<nump<<
" points took "<<timer.
GetRealTime()<<
" us\n";
966 for (
int p=pysize-1;p>=pyindex; p--){
967 BIASCDOUT(D_TRACKER_TRACK,
"---- pyramid level "<<p<<
" ----\n");
969 tb_->SetHalfWinSize(HalfWinSize_[p]);
970 tb_->SetMaxIterations(MaxIter_[p]);
971 tb_->SetMaxError(MaxError_[p]);
972 tb_->SetMaxResiduumMAD(MaxResiduumMAD_[p]);
975 if ((
int)WeightMatrices_.size() == pysize)
977 tb_->SetWeightMatrix(WeightMatrices_[p]);
980 tb_->Init(*(*LastImage_)[p], *pim[p], *(*LastGradX_)[p],
981 *(*LastGradY_)[p], *gradx[p], *grady[p]);
984 cerr <<
"initializing tb took "<<timer.
GetRealTime()<<
" us\n";
989 tb_->Track(Points_[p], PredictedPoints_[p], p2tracked_,
990 DisplInLastIter_[p], NumIter_[p], ResiduiMAD_[p],
991 ResiduiMSD_[p], res_[p],Cov_[p], AffinePrediction_,
996 AffinePrediction_ = AffineResults_[p];
1001 cerr <<
"tracking tb took "<<timer.
GetRealTime()<<
" us\n";
1007 for (
int i=0; i<nump; i++){
1008 BIASCDOUT(D_TRACKER_TRACK, setw(3)<<i<<
" ("<<Points_[p][i][0]<<
", "
1009 <<Points_[p][i][1]<<
") <--> ("<<PredictedPoints_[p][i][0]
1010 <<
", "<<PredictedPoints_[p][i][1]<<
") ");
1012 Points_[p][i]=p2tracked_[i];
1013 BIASCDOUT(D_TRACKER_TRACK,
" -> ("<<p2tracked_[i][0]<<
", "
1014 <<p2tracked_[i][1]<<
") in "<<NumIter_[p][i]
1015 <<
" iterations with err "<<DisplInLastIter_[p][i]
1016 <<
" code "<<res_[p][i]
1017 <<
" residuumMAD "<<ResiduiMAD_[p][i]
1018 <<
" residuumMSD "<<ResiduiMSD_[p][i]
1019 <<
" cov "<<Cov_[p][i] <<endl);
1023 PredictedPoints_[p-1][i][0]=Points_[p][i][0]*factor+offset;
1024 PredictedPoints_[p-1][i][1]=Points_[p][i][1]*factor+offset;
1027 BIASCDOUT((D_TRACKER_ERROR | D_TRACKER_TRACK),
" error tracking: "
1028 <<Points_[p][i]<<
" on py level "<<p<<
" result code "
1029 <<res_[p][i]<<endl);
1034 if (!UseCoarserPointIfLost_) {
1038 for (
int k=p; k<pysize; k++)
1039 Points_[k][i][2]=0.0;
1042 if (p!=(pysize-1) && res_[p+1][i]>=0){
1044 PredictedPoints_[p-1][i][0]=Points_[p+1][i][0]*factor+offset;
1045 PredictedPoints_[p-1][i][1]=Points_[p+1][i][1]*factor+offset;
1047 if (res_[p+1][i]!=0){
1048 res_[p][i]=res_[p+1][i];
1049 NumIter_[p][i]=NumIter_[p+1][i];
1050 DisplInLastIter_[p][i]=DisplInLastIter_[p+1][i]*factor;
1051 ResiduiMAD_[p][i]=ResiduiMAD_[p+1][i];
1052 ResiduiMSD_[p][i]=ResiduiMSD_[p+1][i];
1057 Cov_[p][i]=(factor*factor)*Cov_[p+1][i];
1066 cerr <<
"checking results of tb took "<<timer.
GetRealTime()<<
" us\n";
1072 if (DebugLevelIsSet(D_TRACKER_NUMITER)){
1075 for (
unsigned h=0; h<NumIter_[p].size(); h++)
1076 itersum+=NumIter_[p][h];
1079 totalitersum+=itersum;
1080 BIASCDOUT(D_TRACKER_NUMITER,
"totalitersum "<<totalitersum<<endl);
1089 cerr <<
"propagating result codes through pyramide took "<<timer.
GetRealTime()<<
" us\n";
1096 if (DebugLevelIsSet(D_TRACKER_WRITE_IM)){
1102 LastImage_->GetSingleImage(wim);
1108 LastGradX_->GetSingleImage(gim);
1114 LastGradY_->GetSingleImage(gim);
1122 BIASCDOUT(D_TRACKER_TRACK,
"initialization call\n");
1125 ReplaceLastImages(&pim, &gradx, &grady);
1129 cerr <<
"updateing iternals took "<<timer.
GetRealTime()<<
" us\n";
1140 template <
class StorageType,
class CalculationType>
1144 static bool first =
true;
1145 static int img_num = 0;
1146 const int min_err_code = -7;
1147 static ofstream os(
"tracker.log");
1151 BIASERR(
"error opening \"tracker.log\"");
1155 os <<
"# reasons for lost tracks\n"
1156 <<
"#" << setw(4)<<
"no"
1158 << setw(7) <<
"lost"
1159 << setw(7) <<
"ignrd";
1160 for (
int r = 0; r >= min_err_code; r--){
1167 const int pyindex = PyIndex_;
1168 if (!Points_.empty()){
1169 const int nump = Points_[pyindex].size();
1172 vector<int> reason(-min_err_code + 1, 0);
1174 for (
int i=0; i<nump; i++){
1175 reas = res_[pyindex][i];
1177 if (reas<min_err_code) {
1187 os << setw(5) << img_num
1189 << setw(7) << nump - num - reason[6]
1190 << setw(7) << reason[6];
1191 for (
int r = 0; r <= -min_err_code; r++){
1192 os << setw(7) << reason[r];
1194 os << endl << flush;
1201 template <
class StorageType,
class CalculationType>
1208 ofstream os(name.c_str());
1210 BIASERR(
"error opening "<<name);
1214 os <<
"Feel free to place comments here.\n\n";
1216 os <<
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
1217 os <<
"!!! Warning: This is a KLT data file. Do not modify below this line !!!\n\n";
1219 os <<
"------------------------------\n";
1220 os <<
"KLT Feature Table\n";
1221 os <<
"------------------------------\n\n";
1223 os <<
"nFrames = "<<p.size()<<
", nFeatures = "<<p[0].size()<<
"\n\n";
1225 os <<
"feature | frame\n";
1227 for (i = 0 ; i < (int)p.size() ; i++)
1228 os << setw(width)<<i;
1231 for (i = 0 ; i < (int)p.size() ; i++)
1232 for (k=0; k<width; k++) os <<
"-";
1235 BIASERR(
"error writing "<<name);
1241 FILE *fp=fopen(name.c_str(),
"ab");
1242 for (k=0; k<(int)p[0].size(); k++){
1243 fprintf(fp,
"%7d | ", k);
1244 for (i=0; i<(int)p.size(); i++){
1247 if (!p[i][k].IsAtInfinity()){
1248 fprintf(fp,
"(%7.3f,%7.3f)=%5d ", p[i][k][0], p[i][k][1],
1251 fprintf(fp,
"(%7.3f,%7.3f)=%5d ", -1.0, -1.0, results[i][k]);
1261 template <
class StorageType,
class CalculationType>
1265 const int pysize = (int)LastImage_->size();
1266 const int pyindex = PyIndex_;
1267 const int num =
static_cast<int>(Points_[pyindex].size());
1268 for (
int i=start; i<num; i++){
1269 for (
int p=pyindex; p<pysize; p++){
1270 Points_[p][i][2] = 0.0;
1275 template <
class StorageType,
class CalculationType>
1306 template <
class StorageType,
class CalculationType>
1314 switch(tracker_type){
1337 BIASERR(
"Unknown tracker type");
1343 template <
class StorageType,
class CalculationType>
1349 if (input.
Size()<2u){
1350 BIASERR(
"invalid vector size "<<input.
Size());
1353 const int hsize = (int)rint(input[0]), vsize = (int)rint(input[1]);
1354 if ((
int)input.
Size() != hsize + vsize + 2){
1355 BIASERR(
"invalid vector entries");
1359 for (
int i=0; i<hsize; i++){
1360 hkernel[i] = (float)(CalculationType)input[i+2];
1363 for (
int i=0; i<vsize; i++){
1364 vkernel[i] = (float)(CalculationType)input[i+2+hsize];
1366 mask.
Init(hkernel, vkernel);
1369 if (input.
Size()<2u){
1370 BIASERR(
"invalid vector size "<<input.
Size());
1373 const int rows = (int)rint(input[0]), cols = (int)rint(input[1]);
1374 const int num = cols * rows;
1375 if ((
int)input.
Size() != num + 2){
1376 BIASERR(
"invalid vector entries");
1380 for (
int i=0; i<num; i++){
1381 kernel.
GetData()[i] = (float)(CalculationType)input[i+2];
1395 #ifdef BUILD_IMAGE_INT
1398 #ifdef BUILD_IMAGE_CHAR
1401 #ifdef BUILD_IMAGE_SHORT
1403 #ifdef BUILD_IMAGE_USHORT
1405 #ifdef BUILD_IMAGE_INT
1409 #ifdef BUILD_IMAGE_UINT
1411 #ifdef BUILD_IMAGE_DOUBLE
devel version of antialiased affine tracker
int GetTrackerType()
return trackerbase type currently active
virtual void Init(const Image< StorageType > &image, const unsigned py_size)=0
void ReserveInternals_(const int pysize, const int pointsize)
int PreparePyramide(const Image< StorageType > &im, PyramidImageInterface< CalculationType > &pim, PyramidImageInterface< CalculationType > &gx, PyramidImageInterface< CalculationType > &gy, FilterNTo2N< CalculationType, CalculationType > &grad, FilterNToN< StorageType, CalculationType > &lowpass)
Prepares the pyramid images: Filters im to pim[0], downsamples pim[0] and calculates the gradients gx...
int FillUpPoints(const std::vector< HomgPoint2D > &points, const std::vector< float > &qual)
Replaces points to which no correspondence could be established in the internal data structures...
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
dst.GetChannelCount()==2*src.GetCHannelCount()
int ReplaceAllPoints(const std::vector< HomgPoint2D > &points, const std::vector< float > &qual)
Place every point from points even those at infinity, in the internal data structure Points_...
unsigned size() const
deprecated interface
virtual double GetRescaleFactor() const =0
void SetTrackerType(int tracker_type)
int WriteTrackFile(std::deque< std::vector< HomgPoint2D > > &p, std::deque< std::vector< int > > &results, const std::string &name)
write a track file in Birchfeld-style.
virtual bool IsEmpty() const =0
int ReplacePoints(const std::vector< HomgPoint2D > &points, const std::vector< float > &qual)
Place every point from points which is not at infinity, in the internal data structure Points_...
HomgPoint2D & Homogenize()
homogenize class data member elements to W==1 by divison by W
void PadPoints_(const int start)
sets all points with index>=start in the internal data structures to infinity
Matrix< T > & newsize(Subscript M, Subscript N)
void ReplaceLastImages(PyramidImageInterface< CalculationType > *pim, PyramidImageInterface< CalculationType > *gradx, PyramidImageInterface< CalculationType > *grady)
This function allows the replacement of the last images.
void ResizeInternals_(const int pysize)
gradient calculation with sobel 3 by 3 masks
unsigned int Size() const
length of the vector
unsigned int GetWidth() const
Tracker(int tracker_type=TT_Simple)
Default constructor without param object.
void Reset()
Calls ClearPoints and sets pointer to last image and gradients to zero.
void ClearPoints()
Clears the internal data structures, i.e.
virtual PyramidImageInterface< StorageType > * ShallowClone() const =0
Vector< T > & newsize(Subscript N)
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)=0
virtual function for interface definition
void DetermineROI_(int &tlx, int &tly, int &brx, int &bry) const
bool IsAtInfinity() const
virtual void GetSingleImage(Image< StorageType > &im) const =0
static int ConvertST(const BIAS::ImageBase &source, BIAS::ImageBase &dest, ImageBase::EStorageType targetST)
Function to convert the storage type of images e.g.
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
unsigned int GetHeight() const
The image template class for specific storage types.
T * GetData()
get the pointer to the data array of the matrix (for faster direct memeory access) ...
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same "size" as Image of other type
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.
void Vector2FilterMask_(Vector< double > &input, FilterMask &mask, bool separable)
class Vector3 contains a Vector of fixed dim.
double GetRealTime() const
return real time (=wall time clock) in usec JW For Win32: real-time is measured differently from user...
enum EColorModel GetColorModel() const
matrix class with arbitrary size, indexing is row major.
virtual int WriteImages(const std::string &prefix) const =0
void WriteTrackLog_(int num)
logs reasons for lost tracks into tracker.log
virtual int Track(PyramidImageInterface< CalculationType > &pim, PyramidImageInterface< CalculationType > &gradx, PyramidImageInterface< CalculationType > &grady)
Tracks all points from the internal data structure Points_.
enum EStorageType GetStorageType() const
virtual int Downsample()=0
virtual double GetPositionOffset() const =0
void Init(const Matrix< FM_INT > &kernel, int rs, bool ResetOtherType=FM_RESET_OTHER)
sets _sKernel and also _fKernel.
A filter mask (or a kernel) used for convolution.
void SetZero()
set the elements of this matrix to zero
binomial low pass filter class
class TimeMeasure contains functions for timing real time and cpu time.
High level tracking class.