Main MRPT website > C++ reference for MRPT 1.5.9
CFeature.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "vision-precomp.h" // Precompiled headers
11 
12 
18 #include <mrpt/vision/CFeature.h>
19 #include <mrpt/vision/types.h>
21 #include <mrpt/math/data_utils.h>
22 #include <mrpt/system/os.h>
23 
24 using namespace mrpt;
25 using namespace mrpt::vision;
26 using namespace mrpt::math;
27 using namespace mrpt::system;
28 using namespace mrpt::utils;
29 using namespace std;
30 
32 
33 // --------------------------------------------------
34 // loadFromConfigFile
35 // --------------------------------------------------
36 /** Load all the params from a config source, in the format described in saveToConfigFile()
37  */
38 void TMultiResDescMatchOptions::loadFromConfigFile( const mrpt::utils::CConfigFileBase &cfg, const std::string &section )
39 {
40 
41  useOriFilter = cfg.read_bool(section,"useOriFilter",true,false);
42  oriThreshold = cfg.read_double(section,"oriThreshold",0.2,false);
43  lastSeenThreshold = cfg.read_int(section,"lastSeenThreshold",10,false);
44  timesSeenThreshold = cfg.read_int(section,"timesSeenThreshold",5,false);
45  minFeaturesToFind = cfg.read_int(section,"minFeaturesToFind",5,false);
46  minFeaturesToBeLost = cfg.read_int(section,"minFeaturesToBeLost",5,false);
47 
48  useDepthFilter = cfg.read_bool(section,"useDepthFilter",true,false);
49 
50  matchingThreshold = cfg.read_double(section,"matchingThreshold",1e4,false);
51  matchingRatioThreshold = cfg.read_double(section,"matchingRatioThreshold",0.5,false);
52 
53  lowScl1 = cfg.read_int(section,"lowScl1",0,false);
54  lowScl2 = cfg.read_int(section,"lowScl1",0,false);
55  highScl1 = cfg.read_int(section,"highScl1",6,false);
56  highScl2 = cfg.read_int(section,"highScl2",6,false);
57 
58  searchAreaSize = cfg.read_double(section,"searchAreaSize",20,false);
59 }
60 
61 // --------------------------------------------------
62 // saveToConfigFile
63 // --------------------------------------------------
65 {
66  if( useOriFilter )
67  {
68  cfg.write(section,"useOriFilter", "true" );
69  cfg.write(section,"oriThreshold", oriThreshold );
70  }
71  else
72  cfg.write(section,"useOriFilter", "false" );
73 
74  if( useDepthFilter )
75  cfg.write(section,"useDepthFilter", "true" );
76  else
77  cfg.write(section,"useDepthFilter", "false" );
78 
79  cfg.write(section,"matchingThreshold", matchingThreshold );
80  cfg.write(section,"matchingRatioThreshold", matchingRatioThreshold );
81  cfg.write(section,"lowScl1", lowScl1 );
82  cfg.write(section,"lowScl2", lowScl2 );
83  cfg.write(section,"highScl1", highScl1 );
84  cfg.write(section,"highScl2", highScl2 );
85 
86  cfg.write(section,"searchAreaSize", searchAreaSize );
87  cfg.write(section,"lastSeenThreshold", lastSeenThreshold );
88  cfg.write(section,"timesSeenThreshold", timesSeenThreshold );
89  cfg.write(section,"minFeaturesToFind", minFeaturesToFind );
90  cfg.write(section,"minFeaturesToBeLost", minFeaturesToBeLost );
91 } // end-saveToConfigFile
92 
93 // --------------------------------------------------
94 // dumpToTextStream
95 // --------------------------------------------------
97 {
98  out.printf("\n----------- [vision::TMultiResDescMatchOptions] ------------ \n");
99  out.printf("Use orientation filter?: ");
100  if( useOriFilter )
101  {
102  out.printf("Yes\n");
103  out.printf("· Orientation threshold: %.1f deg\n", RAD2DEG(oriThreshold) );
104  }
105  else
106  out.printf("No\n");
107  out.printf("Use depth filter?: ");
108  if( useDepthFilter )
109  out.printf("Yes\n");
110  else
111  {
112  out.printf("No\n" );
113  out.printf("Lowest scale in list1: %d\n", lowScl1 );
114  out.printf("Highest scale in list1: %d\n", highScl1 );
115  out.printf("Lowest scale in list2: %d\n", lowScl2 );
116  out.printf("Highest scale in list2: %d\n", highScl2 );
117  }
118  out.printf("#frames last seen threshold: %d\n", lastSeenThreshold );
119  out.printf("#frames to be stable threshold: %d\n", timesSeenThreshold );
120  out.printf("min. # features in system: %d\n", minFeaturesToFind );
121  out.printf("min. # features to be lost: %d\n", minFeaturesToBeLost );
122  out.printf("Matching threshold: %.2f\n", matchingThreshold );
123  out.printf("Matching ratio threshold: %.2f\n", matchingRatioThreshold );
124  out.printf("Size of the search window: %d px\n", searchAreaSize );
125  out.printf("-------------------------------------------------------- \n");
126 } // end-dumpToTextStream
127 
128 // --------------------------------------------------
129 // loadFromConfigFile
130 // --------------------------------------------------
131 /** Load all the params from a config source, in the format described in saveToConfigFile()
132  */
134 {
135  basePSize = cfg.read_double(section,"basePSize", 23, false );
136  comLScl = cfg.read_int(section,"comLScl", 0, false );
137  comHScl = cfg.read_int(section,"comHScl", 6, false );
138  sg1 = cfg.read_double(section,"sg1", 0.5, false );
139  sg2 = cfg.read_double(section,"sg2", 7.5, false );
140  sg3 = cfg.read_double(section,"sg3", 8.0, false );
141  computeDepth = cfg.read_bool(section,"computeDepth", true, false );
142  blurImage = cfg.read_bool(section,"blurImage", true, false );
143  fx = cfg.read_double(section,"fx",0.0, false);
144  cx = cfg.read_double(section,"cx",0.0, false);
145  cy = cfg.read_double(section,"cy",0.0, false);
146  baseline = cfg.read_double(section,"baseline",0.0, false);
147  computeHashCoeffs = cfg.read_bool(section,"computeHashCoeffs", false, false );
148 
149 
150  cfg.read_vector(section,"scales",vector<double>(),scales,false);
151  if(scales.size() < 1)
152  {
153  scales.resize(7);
154  scales[0] = 0.5;
155  scales[1] = 0.8;
156  scales[2] = 1.0;
157  scales[3] = 1.2;
158  scales[4] = 1.5;
159  scales[5] = 1.8;
160  scales[6] = 2.0;
161  } // end-if
162 }
163 
164 // --------------------------------------------------
165 // saveToConfigFile
166 // --------------------------------------------------
168 {
169  cfg.write(section,"basePSize", basePSize);
170  cfg.write(section,"comLScl", comLScl );
171  cfg.write(section,"comHScl", comHScl );
172  cfg.write(section,"sg1", sg1 );
173  cfg.write(section,"sg2", sg2 );
174  cfg.write(section,"sg3", sg3 );
175 
176  cfg.write(section,"computeDepth", computeDepth ? "true" : "false" );
177  cfg.write(section,"blurImage", blurImage ? "true" : "false" );
178  cfg.write(section,"fx", fx );
179  cfg.write(section,"cx", cx );
180  cfg.write(section,"cy", cy );
181  cfg.write(section,"baseline", baseline );
182  cfg.write(section,"computeHashCoeffs", computeHashCoeffs ? "true" : "false" );
183 
184  char buf[300];
185  for(unsigned int k = 0; k < scales.size(); ++k)
186  mrpt::system::os::sprintf( buf, 300, "%.2f ", scales[k] );
187  cfg.write(section,"scales", buf );
188 } // end-saveToConfigFile
189 
190 // --------------------------------------------------
191 // dumpToTextStream
192 // --------------------------------------------------
194 {
195  out.printf("\n----------- [vision::TMultiResDescOptions] ------------ \n");
196  out.printf("Base patch size: %d px\n", basePSize);
197  out.printf("Lowest scale to compute: %d\n", comLScl );
198  out.printf("Highest scale to compute: %d\n", comHScl );
199  out.printf("Image smoothing sigma: %.2f px\n", sg1 );
200  out.printf("Orientation histogram sigma: %.2f\n", sg2 );
201  out.printf("Descriptor histogram sigma: %.2f\n", sg3 );
202  out.printf("Compute depth: ");
203  if( computeDepth )
204  {
205  out.printf("Yes\n");
206  out.printf("Focal length: %.2f px\n", fx );
207  out.printf("Principal point (cx): %.2f px\n", cx );
208  out.printf("Principal point (cy): %.2f px\n", cy );
209  out.printf("Baseline: %.2f m\n", baseline );
210  }
211  else
212  out.printf("No\n");
213 
214  out.printf("Compute Hash Coeffs: ");
215  if( computeHashCoeffs )
216  out.printf("Yes\n");
217  else
218  out.printf("No\n");
219 
220  out.printf("Blur image previously: ");
221  if( blurImage )
222  out.printf("Yes\n");
223  else
224  out.printf("No\n");
225 
226  out.printf("Scales: ");
227  for(unsigned int k = 0; k < scales.size(); ++k)
228  out.printf( "%.2f ", scales[k] );
229  out.printf("\n");
230  out.printf("-------------------------------------------------------- \n");
231 } // end-dumpToTextStream
232 
234 {
235  out.printf("\n----------- [vision::CFeature] ------------ \n");
236  out.printf("Feature ID: %d\n", (int)ID);
237  out.printf("Coordinates: (%.2f,%.2f) px\n", x, y );
238  out.printf("PatchSize: %d\n", patchSize );
239  out.printf("Type: ");
240  switch( type )
241  {
242  case -1: out.printf("Not defined\n"); break;
243  case 0: out.printf("KLT\n"); break;
244  case 1: out.printf("Harris\n"); break;
245  case 2: out.printf("BCD\n"); break;
246  case 3: out.printf("SIFT\n"); break;
247  case 4: out.printf("SURF\n"); break;
248  case 5: out.printf("Beacon\n"); break;
249  case 6: out.printf("FAST\n"); break;
250  case 7: out.printf("FASTER-9\n"); break;
251  case 8: out.printf("FASTER-10\n"); break;
252  case 9: out.printf("FASTER-12\n"); break;
253  case 10:out.printf("ORB"); break;
254  }
255  out.printf("Status: ");
256  switch( track_status )
257  {
258  case 0: out.printf("Idle\n"); break;
259  case 1: out.printf("[KLT] Out of bounds [KLT]\n"); break;
260  case 5: out.printf("[KLT] Tracked\n"); break;
261  case 10: out.printf("[KLT] Lost\n"); break;
262  }
263 
264  out.printf("Response: %.2f\n", response );
265  out.printf("Main orientation: %.2f\n", orientation );
266  out.printf("Main scale: %.2f\n", scale );
267  out.printf("# frames seen: %d\n", nTimesSeen );
268  out.printf("# frames not seen: %d\n", nTimesNotSeen );
269  out.printf("# frames since last seen: %d\n", nTimesLastSeen );
270  out.printf("Initial Depth: %.2f m\n", initialDepth );
271  out.printf("Depth: %.2f m\n", depth );
272  out.printf("3D point: (%.2f,%.2f,%.2f) m\n", p3D.x, p3D.y, p3D.z );
273  out.printf("Is point feature?: ");
274  isPointFeature() ? out.printf("Yes\n") : out.printf("No\n");
275 
276  out.printf("Has SIFT descriptor?: ");
277  descriptors.hasDescriptorSIFT() ? out.printf("Yes\n") : out.printf("No\n");
278  out.printf("Has SURF descriptor?: ");
279  descriptors.hasDescriptorSURF() ? out.printf("Yes\n") : out.printf("No\n");
280  out.printf("Has Spin image descriptor?: ");
281  descriptors.hasDescriptorSpinImg() ? out.printf("Yes\n") : out.printf("No\n");
282  out.printf("Has Polar descriptor?: ");
283  descriptors.hasDescriptorPolarImg() ? out.printf("Yes\n") : out.printf("No\n");
284  out.printf("Has Log Polar descriptor?: ");
285  descriptors.hasDescriptorLogPolarImg() ? out.printf("Yes\n") : out.printf("No\n");
286  out.printf("Has ORB descriptor?: ");
287  descriptors.hasDescriptorORB() ? out.printf("Yes\n") : out.printf("No\n");
288 
289 
290  out.printf("Has multiscale?: ");
291  if( !descriptors.hasDescriptorMultiSIFT() )
292  out.printf("No\n");
293  else
294  {
295  out.printf("Yes [%d]\n", (int)multiScales.size());
296  for( int k = 0; k < (int)multiScales.size(); ++k )
297  {
298  out.printf(" · Scale %d: %.2f\n", k, multiScales[k] );
299  for( int m = 0; m < (int)multiOrientations[k].size(); ++m )
300  {
301  out.printf(" ·· Orientation %d: %.2f\n", m, multiOrientations[k][m] );
302  out.printf(" ·· [D] " );
303  for( int n = 0; n < (int)descriptors.multiSIFTDescriptors[k][m].size(); ++n )
304  out.printf("%d ", descriptors.multiSIFTDescriptors[k][m][n] );
305  out.printf("\n");
306  if( multiHashCoeffs.size() > 0 )
307  out.printf(" ·· HASH coefficients %d,%d,%d\n", multiHashCoeffs[k][m][0], multiHashCoeffs[k][m][1],multiHashCoeffs[k][m][2] );
308  }//end-for-m
309  }//end-for-k
310  } // end else
311 } // end dumpToTextStream
312 
314 {
315  CStdOutStream myOut;
316  dumpToTextStream( myOut );
317 }
318 
320 {
321  if (version)
322  *version = 2;
323  else
324  {
325  // The coordinates:
326  out << x
327  << y
328  << ID
329  << patch
330  << patchSize
331  << (uint32_t)type
332  << (uint32_t)track_status
333  << response
334  << orientation
335  << scale
336  << user_flags
337  << nTimesSeen
338  << nTimesNotSeen
339  << nTimesLastSeen
340  << depth
341  << initialDepth
342  << p3D
343  << multiScales
344  << multiOrientations
345  << multiHashCoeffs
346  << descriptors.SIFT
347  << descriptors.SURF
348  << descriptors.SpinImg
349  << descriptors.SpinImg_range_rows
350  << descriptors.PolarImg
351  << descriptors.LogPolarImg
352  << descriptors.polarImgsNoRotation
353  << descriptors.multiSIFTDescriptors
354  << descriptors.ORB;
355  }
356 }
357 
359 {
360  switch(version)
361  {
362  case 0:
363  case 1:
364  case 2:
365  {
366  // The coordinates:
367  uint32_t aux_type, aux_KLTS;
368  in >> x
369  >> y
370  >> ID
371  >> patch
372  >> patchSize
373  >> aux_type
374  >> aux_KLTS
375  >> response
376  >> orientation
377  >> scale
378  >> user_flags;
379  if( version > 0 )
380  {
381  in >> nTimesSeen
382  >> nTimesNotSeen
383  >> nTimesLastSeen
384  >> depth
385  >> initialDepth
386  >> p3D
387  >> multiScales
388  >> multiOrientations
389  >> multiHashCoeffs;
390  }
391  in >> descriptors.SIFT
392  >> descriptors.SURF
393  >> descriptors.SpinImg
394  >> descriptors.SpinImg_range_rows
395  >> descriptors.PolarImg
396  >> descriptors.LogPolarImg
397  >> descriptors.polarImgsNoRotation;
398  if( version > 0 )
399  in >> descriptors.multiSIFTDescriptors;
400  if( version > 1 )
401  in >> descriptors.ORB;
402 
403  type = (TFeatureType)aux_type;
404  track_status = (TFeatureTrackStatus)aux_KLTS;
405  } break;
406  default:
408 
409  };
410 }
411 
412 /****************************************************
413  Class CFEATURE
414 *****************************************************/
415 // CONSTRUCTOR
416 CFeature::CFeature(): x(0.0f), y(0.0f), ID(0), patchSize(21), type(featNotDefined),
417  track_status(status_IDLE), response(0.0),
418  orientation(0.0), scale(0.0), user_flags(0),
419  nTimesSeen(1), nTimesNotSeen(0), nTimesLastSeen(0), depth( 0 ), initialDepth( 0 ), p3D(),
420  multiScales(), multiOrientations(), multiHashCoeffs(), descriptors()
421 {}
422 
423 // Ctor
425  SIFT(),
426  SURF(),
427  SpinImg(), SpinImg_range_rows(0),
428  PolarImg(0,0),
429  LogPolarImg(0,0),
430  polarImgsNoRotation(false),
431  ORB()
432 { }
433 
434 // Return false only for Blob detectors (SIFT, SURF)
436 {
437  return type == featSIFT || type == featSURF;
438 }
439 
440 // --------------------------------------------------
441 // patchCorrelationTo
442 // --------------------------------------------------
443 float CFeature::patchCorrelationTo( const CFeature &oFeature) const
444 {
445  MRPT_START
446  ASSERT_( patch.getWidth()==oFeature.patch.getWidth() )
447  ASSERT_( patch.getHeight()==oFeature.patch.getHeight() )
448  ASSERT_( patch.getHeight()>0 && patch.getWidth()>0 )
449 
450  size_t x_max,y_max;
451  double max_val;
452  patch.cross_correlation( oFeature.patch, x_max,y_max,max_val );
453 
454  return 0.5 - 0.5*max_val; // Value as "distance" in the range [0,1], best = 0
455 
456  MRPT_END
457 }
458 
459 
460 // --------------------------------------------------
461 // descriptorDistanceTo
462 // --------------------------------------------------
464  const CFeature &oFeature,
465  TDescriptorType descriptorToUse,
466  bool normalize_distances ) const
467 {
468  MRPT_START
469 
470  // If we are not ask for a specific descriptor, select the first one found:
471  if (descriptorToUse==descAny)
472  {
474  descriptorToUse = descSIFT;
475  else if (descriptors.hasDescriptorSURF())
476  descriptorToUse = descSURF;
478  descriptorToUse = descSpinImages;
480  descriptorToUse = descPolarImages;
482  descriptorToUse = descLogPolarImages;
483  else if (descriptors.hasDescriptorORB())
484  descriptorToUse = descORB;
485  else THROW_EXCEPTION("Feature has no descriptors and descriptorToUse=descAny")
486  }
487 
488  switch (descriptorToUse)
489  {
490  case descSIFT:
491  return descriptorSIFTDistanceTo(oFeature,normalize_distances);
492  case descSURF:
493  return descriptorSURFDistanceTo(oFeature,normalize_distances);
494  case descSpinImages:
495  return descriptorSpinImgDistanceTo(oFeature,normalize_distances);
496  case descPolarImages:
497  {
498  float minAng;
499  return descriptorPolarImgDistanceTo(oFeature,minAng,normalize_distances);
500  }
501  case descLogPolarImages:
502  {
503  float minAng;
504  return descriptorLogPolarImgDistanceTo(oFeature,minAng,normalize_distances);
505  }
506  case descORB:
507  return float(descriptorORBDistanceTo(oFeature));
508  default:
509  THROW_EXCEPTION_FMT("Unknown value for 'descriptorToUse'=%u",(unsigned)descriptorToUse);
510  }
511 
512 
513  MRPT_END
514 }
515 
516 // --------------------------------------------------
517 // descriptorSIFTDistanceTo
518 // --------------------------------------------------
519 float CFeature::descriptorSIFTDistanceTo( const CFeature &oFeature, bool normalize_distances ) const
520 {
521  ASSERT_( this->descriptors.SIFT.size() == oFeature.descriptors.SIFT.size() );
523 
524  float dist = 0.0f;
526  for( itDesc1 = this->descriptors.SIFT.begin(), itDesc2 = oFeature.descriptors.SIFT.begin();
527  itDesc1 != this->descriptors.SIFT.end();
528  itDesc1++, itDesc2++ )
529  {
530  dist += square(*itDesc1 - *itDesc2);
531  }
532  if (normalize_distances) dist/= this->descriptors.SIFT.size();
533  dist = sqrt(dist);
534  if (normalize_distances) dist/= 64.0f;
535  return dist;
536 } // end descriptorSIFTDistanceTo
537 
538 // --------------------------------------------------
539 // descriptorSURFDistanceTo
540 // --------------------------------------------------
541 float CFeature::descriptorSURFDistanceTo( const CFeature &oFeature, bool normalize_distances ) const
542 {
543  ASSERT_( this->descriptors.SURF.size() == oFeature.descriptors.SURF.size() );
545 
546  float dist = 0.0f;
547  std::vector<float>::const_iterator itDesc1, itDesc2;
548  for( itDesc1 = this->descriptors.SURF.begin(), itDesc2 = oFeature.descriptors.SURF.begin();
549  itDesc1 != this->descriptors.SURF.end();
550  itDesc1++, itDesc2++ )
551  {
552  dist += square(*itDesc1 - *itDesc2);
553  }
554  if (normalize_distances) dist/= this->descriptors.SURF.size();
555  dist = sqrt(dist);
556  if (normalize_distances) dist/= 0.20f; // JL: Ad-hoc value! Investigate where does this come from...
557  return dist;
558 } // end descriptorSURFDistanceTo
559 
560 // --------------------------------------------------
561 // descriptorSpinImgDistanceTo
562 // --------------------------------------------------
563 float CFeature::descriptorSpinImgDistanceTo( const CFeature &oFeature, bool normalize_by_vector_length ) const
564 {
565  ASSERT_( this->descriptors.SpinImg.size() == oFeature.descriptors.SpinImg.size() );
567  ASSERT_( !this->descriptors.SpinImg.empty() )
568 
569  float dist = 0.0f;
570  std::vector<float>::const_iterator itDesc1, itDesc2;
571  for( itDesc1 = this->descriptors.SpinImg.begin(), itDesc2 = oFeature.descriptors.SpinImg.begin();
572  itDesc1 != this->descriptors.SpinImg.end();
573  itDesc1++, itDesc2++ )
574  {
575  dist += square(*itDesc1 - *itDesc2);
576  }
577 
578  if (normalize_by_vector_length)
579  dist /= 0.25*descriptors.SpinImg.size();
580 
581  return sqrt(dist);
582 } // end descriptorSpinImgDistanceTo
583 
584 
585 // --------------------------------------------------
586 // descriptorPolarImgDistanceTo
587 // --------------------------------------------------
589  const CMatrix &desc1,
590  const CMatrix &desc2,
591  float &minDistAngle,
592  bool normalize_distances,
593  bool dont_shift_angle )
594 {
595  MRPT_START
596 
597  // Find the smallest distance:
598  unsigned int delta,i,j,ii,height = desc1.getRowCount(), width = desc1.getColCount();
599  float dist, minDist=0;
600 
601 //#define LM_CORR_BIAS_MEAN
602 
603 #define LM_CORR_METHOD_EUCLID
604 //#define LM_CORR_METHOD_MANHATTAN
605 //#define LM_CORR_METHOD_CORRELATION
606 
607 #if defined(LM_CORR_BIAS_MEAN) || defined(LM_CORR_METHOD_CORRELATION)
608  const float desc1_mean = desc1.sum() / static_cast<float>(width*height);
609  const float desc2_mean = desc2.sum() / static_cast<float>(width*height);
610 #endif
611 
612  CVectorFloat distances(height,0); // Distances for each shift
613 
614  for (delta=0;delta<height;delta++)
615  {
616 
617 #if defined(LM_CORR_METHOD_CORRELATION)
618  float s11=0;
619  float s22=0;
620  float s12=0;
621 #endif
622  // Compute the mean distance between desc1[t] and desc2[t-delta]:
623  dist = 0;
624  for (i=0;i<height;i++)
625  {
626  ii = (i + delta) % height; // Shifted index
627  for (j=0;j<width;j++)
628  {
629 #ifdef LM_CORR_METHOD_EUCLID
630  #ifdef LM_CORR_BIAS_MEAN
631  dist+= square( desc1.get_unsafe(i,j) - desc1_mean - desc2.get_unsafe(ii,j) + desc2_mean );
632  #else
633  dist+= square( desc1.get_unsafe(i,j) - desc2.get_unsafe(ii,j) );
634  #endif
635 #elif defined(LM_CORR_METHOD_MANHATTAN)
636  #ifdef LM_CORR_BIAS_MEAN
637  dist+= abs( desc1.get_unsafe(i,j) - desc1_mean - desc2.get_unsafe(ii,j) + desc2_mean );
638  #else
639  dist+= abs( desc1.get_unsafe(i,j) - desc2.get_unsafe(ii,j) );
640  #endif
641 #elif defined(LM_CORR_METHOD_CORRELATION)
642  float d1 = desc1.get_unsafe(i,j) - desc1_mean;
643  float d2 = desc2.get_unsafe(ii,j) - desc2_mean;
644  s11 += square(d1);
645  s22 += square(d2);
646  s12 += d1*d2;
647 #else
648 #error A LM_CORR_METHOD_XXX method must be selected!
649 #endif
650  }
651  }
652 
653  // Average:
654  if (normalize_distances)
655  dist /= static_cast<float>(width*height);
656 
657 #ifdef LM_CORR_METHOD_EUCLID
658  dist = sqrt(dist);
659 #endif
660 
661 #if defined(LM_CORR_METHOD_CORRELATION)
662  dist = 1 - (s12 / sqrt(s11 * s22));
663 #endif
664 
665  distances[delta] = dist;
666  if (!delta && dont_shift_angle) { distances.resize(1); break; }
667  } // end for delta
668 
669  size_t minDistIdx;
670  minDist = distances.minimum(&minDistIdx);
671 
672  double dist_mean,dist_std;
673  mrpt::math::meanAndStd(distances,dist_mean,dist_std);
674 
675 #if 0
676  {
677  cout << "min dist: " << minDist << endl;
678 
679  static mrpt::gui::CDisplayWindowPlots win("distances");
680  win.plot(distances,"b.4");
681  CImage img1(desc1);
682  win.image(img1,0,-0.5,0.4*width,0.5,"img1");
683 
684  CImage img2(desc2);
685  win.image(img2,0.6*width,-0.5,0.4*width,0.5,"img2");
686 
687  //win.axis_fit();
688  win.waitForKey();
689  }
690 #endif
691 
692  // Output:
693  minDistAngle = minDistIdx * M_2PI / static_cast<float>(width) ;
694  return minDist;
695 
696  MRPT_END
697 }
698 
699 // --------------------------------------------------
700 // descriptorPolarImgDistanceTo
701 // --------------------------------------------------
703  const CFeature &oFeature,
704  float &minDistAngle,
705  bool normalize_distances) const
706 {
707  MRPT_START
708 
713 
714  // Call the common method for computing these distances:
717  oFeature.descriptors.PolarImg,
718  minDistAngle,
719  normalize_distances,
721 
722  MRPT_END
723 } // end descriptorPolarImgDistanceTo
724 
725 // --------------------------------------------------
726 // descriptorLogPolarImgDistanceTo
727 // --------------------------------------------------
729  const CFeature &oFeature,
730  float &minDistAngle,
731  bool normalize_distances) const
732 {
733  MRPT_START
734 
739 
740  // Call the common method for computing these distances:
743  oFeature.descriptors.LogPolarImg,
744  minDistAngle,
745  normalize_distances,
747 
748  MRPT_END
749 } // end descriptorPolarImgDistanceTo
750 
751 // --------------------------------------------------
752 // descriptorORBDistanceTo
753 // --------------------------------------------------
755 {
757  ASSERT_( this->descriptors.ORB.size() == oFeature.descriptors.ORB.size() )
758 
759  const std::vector<uint8_t> & t_desc = this->descriptors.ORB;
760  const std::vector<uint8_t> & o_desc = oFeature.descriptors.ORB;
761 
762  // Descriptors XOR + Hamming weight
763  uint8_t distance = 0;
764  for( uint8_t k = 0; k < t_desc.size(); ++k )
765  {
766  uint8_t x_or = t_desc[k] ^ o_desc[k];
767  uint8_t count; // from : Wegner, Peter (1960), "A technique for counting ones in a binary computer", Communications of the ACM 3 (5): 322, doi:10.1145/367236.367286
768  for( count = 0; x_or; count++ ) // ...
769  x_or &= x_or-1; // ...
770  distance += count;
771  }
772 
773  return float(distance);
774 } // end-descriptorORBDistanceTo
775 
776 // --------------------------------------------------
777 // saveToTextFile
778 // --------------------------------------------------
779 void CFeature::saveToTextFile( const std::string &filename, bool APPEND )
780 {
781  MRPT_START
782 // "%% Dump of mrpt::vision::CFeatureList. Each line format is:\n"
783 // "%% ID TYPE X Y ORIENTATION SCALE TRACK_STATUS RESPONSE HAS_SIFT [SIFT] HAS_SURF [SURF] HAS_MULTI [MULTI_i] HAS_ORB [ORB]"
784 // "%% \\---------------------- feature ------------------/ \\--------- descriptors -------/\n"
785 // "%% with:\n"
786 // "%% TYPE : The used detector: 0:KLT, 1: Harris, 2: BCD, 3: SIFT, 4: SURF, 5: Beacon, 6: FAST\n"
787 // "%% HAS_* : 1 if a descriptor of that type is associated to the feature. \n"
788 // "%% SIFT : Present if HAS_SIFT=1: N DESC_0 ... DESC_N-1 \n"
789 // "%% SURF : Present if HAS_SURF=1: N DESC_0 ... DESC_N-1 \n"
790 // "%% MULTI : Present if HAS_MULTI=1: SCALE ORI N DESC_0 ... DESC_N-1"
791 // "%% ORB : Present if HAS_ORB=1: VALUE
792 // "%%-------------------------------------------------------------------------------------------\n");
794 
795  if( !f.open(filename,APPEND) )
796  THROW_EXCEPTION( "[CFeature::saveToTextFile] ERROR: File could not be open for writing" );
797 
798  f.printf("%5u %2d %7.3f %7.3f %6.2f %6.2f %2d %6.3f ",
799  (unsigned int)this->ID, (int)this->get_type(), this->x, this->y,
800  this->orientation, this->scale,
801  (int)this->track_status, this->response );
802 
803  f.printf("%2d ", int(this->descriptors.hasDescriptorSIFT() ? 1:0) );
804  if( this->descriptors.hasDescriptorSIFT() )
805  {
806  f.printf("%4d ", int(this->descriptors.SIFT.size()) );
807  for( unsigned int k = 0; k < this->descriptors.SIFT.size(); k++ )
808  f.printf( "%4d ", this->descriptors.SIFT[k]);
809  }
810 
811  f.printf("%2d ", int(this->descriptors.hasDescriptorSURF() ? 1:0) );
812  if( this->descriptors.hasDescriptorSURF() )
813  {
814  f.printf("%4d ", int(this->descriptors.SURF.size()) );
815  for( unsigned int k = 0; k < this->descriptors.SURF.size(); k++ )
816  f.printf( "%8.5f ", this->descriptors.SURF[k]);
817  }
818 
819  f.printf("%2d ", int(this->descriptors.hasDescriptorMultiSIFT() ? 1:0) );
820  if( this->descriptors.hasDescriptorMultiSIFT() )
821  {
822  for( int k = 0; k < int(this->multiScales.size()); ++k )
823  {
824  for( int m = 0; m < int(this->multiOrientations[k].size()); ++m )
825  {
826  f.printf("%.2f %6.2f ", this->multiScales[k], this->multiOrientations[k][m] );
827  f.printf("%4d ", int(this->descriptors.multiSIFTDescriptors[k][m].size()) );
828  for( unsigned int n = 0; n < this->descriptors.multiSIFTDescriptors[k][m].size(); ++n )
829  f.printf( "%4d ", this->descriptors.multiSIFTDescriptors[k][m][n]);
830  }
831  } // end-for
832  } // end-if
833 
834  f.printf("%2d ", int(this->descriptors.hasDescriptorORB() ? 1:0) );
835  if( this->descriptors.hasDescriptorORB() )
836  for( size_t k = 0; k < this->descriptors.ORB.size(); ++k )
837  f.printf("%d ", this->descriptors.ORB[k] );
838 
839  f.printf( "\n");
840  f.close();
841 
842  MRPT_END
843 } // end saveToTextFile
844 
845 /****************************************************
846  Class CFEATURELIST
847 *****************************************************/
848 // --------------------------------------------------
849 // CONSTRUCTOR
850 // --------------------------------------------------
852 {} //end constructor
853 
854 // --------------------------------------------------
855 // DESTRUCTOR
856 // --------------------------------------------------
858 {
859 } // end destructor
860 
861 // --------------------------------------------------
862 // saveToTextFile
863 // --------------------------------------------------
864 // FORMAT: ID type x y orientation scale [descriptorSIFT] [descriptorSURF] track_status response
865 void CFeatureList::saveToTextFile( const std::string &filename, bool APPEND )
866 {
867  MRPT_START
868 
870 
871  if( !f.open(filename,APPEND) )
872  THROW_EXCEPTION( "[CFeatureList::saveToTextFile] ERROR: File could not be open for writing" );
873 
874  f.printf(
875  "%% Dump of mrpt::vision::CFeatureList. Each line format is:\n"
876  "%% ID TYPE X Y ORIENTATION SCALE TRACK_STATUS RESPONSE HAS_SIFT [SIFT] HAS_SURF [SURF]\n"
877  "%% \\---------------------- feature ------------------/ \\--------- descriptors -------/\n"
878  "%% with:\n"
879  "%% TYPE : The used detector: 0:KLT, 1: Harris, 2: BCD, 3: SIFT, 4: SURF, 5: Beacon, 6: FAST\n"
880  "%% HAS_* : 1 if a descriptor of that type is associated to the feature. \n"
881  "%% SIFT : Present if HAS_SIFT=1: N DESC_0 ... DESC_N-1 \n"
882  "%% SURF : Present if HAS_SURF=1: N DESC_0 ... DESC_N-1 \n"
883  "%%-------------------------------------------------------------------------------------------\n");
884 
885  for( CFeatureList::iterator it = this->begin(); it != this->end(); ++it )
886  {
887  f.printf("%5u %2d %7.3f %7.3f %6.2f %6.2f %2d %6.3f ",
888  (unsigned int)(*it)->ID, (int)(*it)->get_type(), (*it)->x, (*it)->y,
889  (*it)->orientation, (*it)->scale,
890  (int)(*it)->track_status, (*it)->response );
891 
892  f.printf("%2d ", int((*it)->descriptors.hasDescriptorSIFT() ? 1:0) );
893  if( (*it)->descriptors.hasDescriptorSIFT() )
894  {
895  f.printf("%4d ", int((*it)->descriptors.SIFT.size()) );
896  for( unsigned int k = 0; k < (*it)->descriptors.SIFT.size(); k++ )
897  f.printf( "%4d ", (*it)->descriptors.SIFT[k]);
898  }
899 
900  f.printf("%2d ", int((*it)->descriptors.hasDescriptorSURF() ? 1:0) );
901  if( (*it)->descriptors.hasDescriptorSURF() )
902  {
903  f.printf("%4d ", int((*it)->descriptors.SURF.size()) );
904  for( unsigned int k = 0; k < (*it)->descriptors.SURF.size(); k++ )
905  f.printf( "%8.5f ", (*it)->descriptors.SURF[k]);
906  }
907 
908  f.printf( "\n");
909  } // end for
910 
911  f.close();
912 
913  MRPT_END
914 } // end saveToTextFile
915 
916 // --------------------------------------------------
917 // loadFromTextFile
918 // --------------------------------------------------
920 {
921  MRPT_START
922 
923  mrpt::utils::CTextFileLinesParser parser(filename);
924  std::istringstream line;
925 
926  while( parser.getNextLine(line) )
927  {
928  try
929  {
930  CFeaturePtr feat_ptr = CFeature::Create();
931  CFeature* feat = feat_ptr.pointer(); // for faster access
932 
933  int _ID;
934  if (!(line >> _ID )) throw std::string("ID");
935  feat->ID = TFeatureID(_ID);
936 
937  int _type;
938  if (!(line >> _type)) throw std::string("type");
939  feat->type = TFeatureType(_type);
940 
941  if (!(line >> feat->x >> feat->y )) throw std::string("x,y");
942  if (!(line >> feat->orientation )) throw std::string("orientation");
943  if (!(line >> feat->scale )) throw std::string("scale");
944 
945  int _track_st;
946  if (!(line >> _track_st )) throw std::string("track_status");
947  feat->track_status = TFeatureTrackStatus(_track_st);
948 
949  if (!(line >> feat->response )) throw std::string("response");
950 
951  int hasSIFT;
952  if (!(line >> hasSIFT)) throw std::string("hasSIFT");
953  if (hasSIFT)
954  {
955  size_t N;
956  if (!(line >> N)) throw std::string("SIFT-len");
957  feat->descriptors.SIFT.resize(N);
958  for (size_t i=0;i<N;i++)
959  {
960  int val;
961  line >> val;
962  feat->descriptors.SIFT[i] = val; // DON'T read directly SIFT[i] since it's a uint8_t, interpreted as a cha
963  }
964 
965  if (!line) throw std::string("SIFT-data");
966  }
967 
968  int hasSURF;
969  if (!(line >> hasSURF)) throw std::string("hasSURF");
970  if (hasSURF)
971  {
972  size_t N;
973  if (!(line >> N)) throw std::string("SURF-len");
974  feat->descriptors.SURF.resize(N);
975  for (size_t i=0;i<N;i++)
976  line >> feat->descriptors.SURF[i];
977  if (!line) throw std::string("SURF-data");
978  }
979 
980  push_back( feat_ptr );
981  }
982  catch(std::string &msg)
983  {
984  THROW_EXCEPTION(format("%s:%d: Error parsing features text file (%s).",filename.c_str(), (int)parser.getCurrentLineNumber(), msg.c_str() ))
985  }
986  }
987 
988  MRPT_END
989 } // end loadFromTextFile
990 
991 // --------------------------------------------------
992 // copyListFrom()
993 // --------------------------------------------------
994 void CFeatureList::copyListFrom( const CFeatureList &otherList )
995 {
996  this->resize( otherList.size() );
999  for( it1 = otherList.begin(), it2 = this->begin(); it1 != otherList.end(); ++it1, ++it2 )
1000  (*it2) = CFeaturePtr( dynamic_cast<CFeature*>((*it1)->clone()));
1001 } // end-copyListFrom
1002 
1003 // --------------------------------------------------
1004 // getByID()
1005 // --------------------------------------------------
1006 CFeaturePtr CFeatureList::getByID( const TFeatureID &ID ) const
1007 {
1008  for( CFeatureList::const_iterator it = begin(); it != end(); ++it )
1009  if( (*it)->ID == ID )
1010  return (*it);
1011 
1012  return CFeaturePtr();
1013 } // end getByID
1014 
1015 // --------------------------------------------------
1016 // getByID()
1017 // --------------------------------------------------
1018 CFeaturePtr CFeatureList::getByID( const TFeatureID &ID, int &out_idx ) const
1019 {
1020  int k = 0;
1021  for( CFeatureList::const_iterator it = begin(); it != end(); ++it, ++k )
1022  if( (*it)->ID == ID )
1023  {
1024  out_idx = k;
1025  return (*it);
1026  }
1027  out_idx = -1;
1028  return CFeaturePtr();
1029 } // end getByID
1030 
1031 // --------------------------------------------------
1032 // getByID()
1033 // --------------------------------------------------
1034 void CFeatureList::getByMultiIDs( const vector<TFeatureID> &IDs, vector<CFeaturePtr> &out, vector<int> &outIndex ) const
1035 {
1036  out.clear();
1037  outIndex.clear();
1038  out.reserve( IDs.size() );
1039  outIndex.reserve( IDs.size() );
1040 
1041  for( int k = 0; k < int(IDs.size()); ++k )
1042  {
1043  int idx;
1044  CFeaturePtr f = getByID( IDs[k], idx );
1045  out.push_back( f );
1046  outIndex.push_back( idx );
1047  }
1048 } // end getByID
1049 
1050 // --------------------------------------------------
1051 // nearest(x,y)
1052 // --------------------------------------------------
1053 CFeaturePtr CFeatureList::nearest( const float x, const float y, double &dist_prev ) const
1054 {
1055  if (this->empty())
1056  return CFeaturePtr();
1057 
1058  float closest_x,closest_y;
1059  float closest_sqDist;
1060 
1061  // Look for the closest feature using KD-tree look up:
1062  const size_t closest_idx = this->kdTreeClosestPoint2D(x,y,closest_x,closest_y,closest_sqDist);
1063  float closest_dist = std::sqrt(closest_sqDist);
1064 
1065  if (closest_dist<=dist_prev)
1066  {
1067  dist_prev = closest_dist;
1068  return m_feats[closest_idx];
1069  }
1070  else return CFeaturePtr();
1071 } // end nearest
1072 
1073 
1074 // --------------------------------------------------
1075 // getMaxID()
1076 // --------------------------------------------------
1078 {
1079  MRPT_START
1080  ASSERT_( !empty() )
1081  vision::TFeatureID maxID = (*begin())->ID;
1082  for(CFeatureList::const_iterator itList = begin(); itList != end(); itList++)
1083  mrpt::utils::keep_max(maxID, (*itList)->ID);
1084  return maxID;
1085  MRPT_END
1086 
1087 } // end getMaxID()
1088 
1089 /****************************************************
1090  Class CMATCHEDFEATUREKLT
1091 *****************************************************/
1092 // --------------------------------------------------
1093 // CONSTRUCTOR
1094 // --------------------------------------------------
1095 CMatchedFeatureList::CMatchedFeatureList() : m_leftMaxID(0), m_rightMaxID(0) {}
1096 
1097 // --------------------------------------------------
1098 // DESTRUCTOR
1099 // --------------------------------------------------
1101 {
1102 } // end destructor
1103 
1104 // --------------------------------------------------
1105 // saveToTextFile
1106 // --------------------------------------------------
1108 {
1109  // OUTPUT FORMAT: ID_1 x_1 y_1 ID_2 x_2 y_2
1110 
1111  FILE *f = os::fopen( filename.c_str(), "wt" );
1112  if(!f) return;
1113 
1115  for( it = this->begin(); it != this->end(); it++ )
1116  {
1117  os::fprintf( f, "%d %.3f %.3f %d %.3f %.3f\n",
1118  (unsigned int)(*it->first).ID, (*it->first).x, (*it->first).y,
1119  (unsigned int)(*it->second).ID, (*it->second).x, (*it->second).y);
1120 
1121  } // end for
1122  os::fclose( f );
1123 }
1124 
1125 // --------------------------------------------------
1126 // getBothFeatureLists
1127 // --------------------------------------------------
1128 CFeaturePtr CMatchedFeatureList::getByID( const TFeatureID & ID, const TListIdx &idx )
1129 {
1131  for( it = begin(); it != end(); ++it )
1132  {
1133  CFeaturePtr feat = (idx == firstList) ? it->first : it->second;
1134  if( feat->ID == ID )
1135  return feat;
1136  }
1137  return CFeaturePtr();
1138 }
1139 
1140 // --------------------------------------------------
1141 // updateMaxID()
1142 // --------------------------------------------------
1144 {
1145  MRPT_START
1146  TFeatureID maxID1 = begin()->first->ID;
1147  TFeatureID maxID2 = begin()->second->ID;
1148  for(CMatchedFeatureList::const_iterator itList = begin(); itList != end(); itList++)
1149  {
1150  if( idx == firstList || idx == bothLists )
1151  mrpt::utils::keep_max(maxID1, itList->first->ID);
1152  if( idx == secondList || idx == bothLists )
1153  mrpt::utils::keep_max(maxID2, itList->second->ID);
1154  }
1155  if( idx == firstList || idx == bothLists )
1156  m_leftMaxID = maxID1;
1157  if( idx == secondList || idx == bothLists )
1158  m_rightMaxID = maxID2;
1159  MRPT_END
1160 }
1161 
1162 // --------------------------------------------------
1163 // getMaxID()
1164 // --------------------------------------------------
1165 void CMatchedFeatureList::getMaxID( const TListIdx &idx, TFeatureID & firstListID, TFeatureID & secondListID )
1166 {
1167  MRPT_START
1168  ASSERT_( !empty() );
1169  if( idx == firstList || idx == bothLists )
1170  if( m_leftMaxID == 0 )
1172  if( idx == secondList || idx == bothLists )
1173  if( m_rightMaxID == 0 )
1175  firstListID = m_leftMaxID;
1176  secondListID = m_rightMaxID;
1177  MRPT_END
1178 } // end getMaxID()
1179 // --------------------------------------------------
1180 // getBothFeatureLists
1181 // --------------------------------------------------
1183 {
1184  MRPT_START
1185  list1.resize( this->size() );
1186  list2.resize( this->size() );
1187 
1188  unsigned int k = 0;
1189  for( CMatchedFeatureList::iterator it = this->begin(); it != this->end(); ++it, ++k )
1190  {
1191  list1[k] = it->first;
1192  list2[k] = it->second;
1193  } // end for
1194  MRPT_END
1195 }
1196 
1197 // --------------------------------------------------
1198 // getFirstDescriptorAsMatrix
1199 // --------------------------------------------------
1201 {
1203  {
1204  desc.setSize(1,descriptors.SIFT.size());
1205  for (size_t i=0;i<descriptors.SIFT.size();i++)
1206  desc(0,i)=descriptors.SIFT[i];
1207  return true;
1208  }
1209  else if (descriptors.hasDescriptorSURF())
1210  {
1211  desc.setSize(1,descriptors.SURF.size());
1212  for (size_t i=0;i<descriptors.SURF.size();i++)
1213  desc(0,i)=descriptors.SURF[i];
1214  return true;
1215  }
1216  else if (descriptors.hasDescriptorSpinImg())
1217  {
1218  const size_t nR = descriptors.SpinImg_range_rows;
1219  const size_t nC = descriptors.SpinImg.size() / descriptors.SpinImg_range_rows;
1220  desc.resize(nR,nC);
1222  for (size_t r=0;r<nR;r++)
1223  for (size_t c=0;c<nC;c++)
1224  desc.coeffRef(r,c) = *itD++;
1225  return true;
1226  }
1228  {
1229  desc = descriptors.PolarImg;
1230  return true;
1231  }
1233  {
1234  desc = descriptors.LogPolarImg;
1235  return true;
1236  }
1237  else return false;
1238 }
void updateMaxID(const TListIdx &idx)
Updates the value of the maximum ID of the features in the matched list, i.e.
Definition: CFeature.cpp:1143
float descriptorDistanceTo(const CFeature &oFeature, TDescriptorType descriptorToUse=descAny, bool normalize_distances=true) const
Computes the Euclidean Distance between this feature&#39;s and other feature&#39;s descriptors, using the given descriptor or the first present one.
Definition: CFeature.cpp:463
int waitForKey(bool ignoreControlKeys=true, mrptKeyModifier *out_pushModifier=NULL)
Waits for any key to be pushed on the image or the console, and returns the key code.
GLuint GLuint GLsizei count
Definition: glext.h:3512
FILE BASE_IMPEXP * fopen(const char *fileName, const char *mode) MRPT_NO_THROWS
An OS-independent version of fopen.
Definition: os.cpp:255
CFeaturePtr nearest(const float x, const float y, double &max_dist) const
Get a reference to the nearest feature to the a given 2D point (version returning distance to closest...
Definition: CFeature.cpp:1053
Non-defined feature (also used for Occupancy features)
TFeatureID ID
ID of the feature.
Definition: CFeature.h:62
EIGEN_STRONG_INLINE bool empty() const
bool read_bool(const std::string &section, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
uint8_t descriptorORBDistanceTo(const CFeature &oFeature) const
Computes the Hamming distance "this" and the "other" descriptor ORB descriptor.
Definition: CFeature.cpp:754
float descriptorSpinImgDistanceTo(const CFeature &oFeature, bool normalize_distances=true) const
Computes the Euclidean Distance between "this" and the "other" descriptors.
Definition: CFeature.cpp:563
float scale
Feature scale into the scale space.
Definition: CFeature.h:69
Used in some methods to mean "any of the present descriptors".
void loadFromTextFile(const std::string &fileName)
Save feature list to a text file.
Definition: CFeature.cpp:919
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:29
Create a GUI window and display plots with MATLAB-like interfaces and commands.
The virtual base class which provides a unified interface for all persistent objects in MRPT...
Definition: CSerializable.h:39
int BASE_IMPEXP void BASE_IMPEXP fclose(FILE *f)
An OS-independent version of fclose.
Definition: os.cpp:272
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:101
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
Definition: CFeature.cpp:96
bool hasDescriptorLogPolarImg() const
Whether this feature has this kind of descriptor.
Definition: CFeature.h:102
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:5717
TFeatureTrackStatus track_status
Status of the feature tracking process (old name: KLT_status)
Definition: CFeature.h:66
size_t size() const
Definition: CFeature.h:280
void dumpToConsole() const
Definition: CFeature.cpp:313
#define THROW_EXCEPTION(msg)
float descriptorSIFTDistanceTo(const CFeature &oFeature, bool normalize_distances=true) const
Computes the Euclidean Distance between "this" and the "other" descriptors.
Definition: CFeature.cpp:519
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
GLenum GLsizei n
Definition: glext.h:4618
Scalar * iterator
Definition: eigen_plugins.h:23
float descriptorSURFDistanceTo(const CFeature &oFeature, bool normalize_distances=true) const
Computes the Euclidean Distance between "this" and the "other" descriptors.
Definition: CFeature.cpp:541
This CStdOutStream derived class allow printing to standard out, normally the console text output...
Definition: CStdOutStream.h:26
EIGEN_STRONG_INLINE iterator begin()
Definition: eigen_plugins.h:26
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
Definition: eigen_frwds.h:35
CFeaturePtr getByID(const TFeatureID &ID, const TListIdx &idx)
Returns a smart pointer to the feature with the provided ID or a empty one if not found...
Definition: CFeature.cpp:1128
EIGEN_STRONG_INLINE void push_back(Scalar val)
Insert an element at the end of the container (for 1D vectors/arrays)
std::vector< float > SURF
SURF feature descriptor.
Definition: CFeature.h:89
std::deque< double > multiScales
A set of scales where the multi-resolution descriptor has been computed.
Definition: CFeature.h:78
int BASE_IMPEXP fprintf(FILE *fil, const char *format,...) MRPT_NO_THROWS MRPT_printf_format_check(2
An OS-independent version of fprintf.
Definition: os.cpp:412
TInternalFeatList::const_iterator const_iterator
Definition: CFeature.h:262
GLint GLint GLsizei GLsizei GLsizei depth
Definition: glext.h:3545
STL namespace.
const Scalar * const_iterator
Definition: eigen_plugins.h:24
TFeatureType get_type() const
Get the type of the feature.
Definition: CFeature.h:176
mrpt::math::CMatrix LogPolarImg
A log-polar image centered at the interest point.
Definition: CFeature.h:93
float y
Coordinates in the image.
Definition: CFeature.h:61
IMPLEMENTS_SERIALIZABLE(CLogFileRecord_FullEval, CHolonomicLogFileRecord, mrpt::nav) IMPLEMENTS_SERIALIZABLE(CHolonomicFullEval
bool hasDescriptorMultiSIFT() const
Whether this feature has this kind of descriptor.
Definition: CFeature.h:103
GLenum GLsizei width
Definition: glext.h:3513
void image(const utils::CImage &img, const float &x_left, const float &y_bottom, const float &x_width, const float &y_height, const std::string &plotName=std::string("image"))
Adds a bitmap image layer.
void dumpToTextStream(mrpt::utils::CStream &out) const MRPT_OVERRIDE
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
Definition: CFeature.cpp:193
#define M_2PI
Definition: mrpt_macros.h:380
This class allows loading and storing values and vectors of different types from a configuration text...
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:52
unsigned char uint8_t
Definition: rptypes.h:43
Inactive (right after detection, and before being tried to track)
int read_int(const std::string &section, const std::string &name, int defaultValue, bool failIfNotFound=false) const
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
bool polarImgsNoRotation
If set to true (manually, default=false) the call to "descriptorDistanceTo" will not consider all the...
Definition: CFeature.h:94
TFeatureType type
Type of the feature: featNotDefined, featSIFT, featKLT, featHarris, featSURF, featBeacon.
Definition: CFeature.h:65
void getBothFeatureLists(CFeatureList &list1, CFeatureList &list2)
Returns the matching features as two separate CFeatureLists.
Definition: CFeature.cpp:1182
void saveToTextFile(const std::string &filename, bool APPEND=false)
Save the feature to a text file in this format: "%% Dump of mrpt::vision::CFeatureList. Each line format is:\n" "%% ID TYPE X Y ORIENTATION SCALE TRACK_STATUS RESPONSE HAS_SIFT [SIFT] HAS_SURF [SURF] HAS_MULTI [MULTI_i] HAS_ORB [ORB]" "%% |---------------------- feature ------------------| |---------------------- descriptors ------------------------|" "%% with:\n" "%% TYPE : The used detector: 0:KLT, 1: Harris, 2: BCD, 3: SIFT, 4: SURF, 5: Beacon, 6: FAST, 7: ORB\n" "%% HAS_* : 1 if a descriptor of that type is associated to the feature." "%% SIFT : Present if HAS_SIFT=1: N DESC_0 ... DESC_N-1" "%% SURF : Present if HAS_SURF=1: N DESC_0 ... DESC_N-1" "%% MULTI : Present if HAS_MULTI=1: SCALE ORI N DESC_0 ... DESC_N-1" "%% ORB : Present if HAS_ORB=1: DESC_0 ...
Definition: CFeature.cpp:779
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
void resize(size_t N)
Definition: CFeature.h:283
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
Definition: CFeature.cpp:319
#define MRPT_END
This CStream derived class allow using a file as a write-only, binary stream.
void getMaxID(const TListIdx &idx, TFeatureID &firstListID, TFeatureID &secondListID)
Returns the maximum ID of the features in the list.
Definition: CFeature.cpp:1165
void saveToConfigFile(mrpt::utils::CConfigFileBase &cfg, const std::string &section) const MRPT_OVERRIDE
This method saves the options to a ".ini"-like file or memory-stored string list. ...
Definition: CFeature.cpp:64
static float internal_distanceBetweenPolarImages(const mrpt::math::CMatrix &desc1, const mrpt::math::CMatrix &desc2, float &minDistAngle, bool normalize_distances, bool dont_shift_angle)
Internal function used by "descriptorLogPolarImgDistanceTo" and "descriptorPolarImgDistanceTo".
Definition: CFeature.cpp:588
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string &section) MRPT_OVERRIDE
Load all the params from a config source, in the format described in saveToConfigFile() ...
Definition: CFeature.cpp:133
const GLubyte * c
Definition: glext.h:5590
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
void cross_correlation(const CImage &patch_img, size_t &u_max, size_t &v_max, double &max_val, int u_search_ini=-1, int v_search_ini=-1, int u_search_size=-1, int v_search_size=-1, CImage *out_corr_image=NULL) const
Computes the correlation between this image and another one, encapsulating the openCV function cvMatc...
Definition: CImage.cpp:1451
Scale Invariant Feature Transform [LOWE&#39;04].
void read_vector(const std::string &section, const std::string &name, const VECTOR_TYPE &defaultValue, VECTOR_TYPE &outValues, bool failIfNotFound=false) const
Reads a configuration parameter of type vector, stored in the file as a string: "[v1 v2 v3 ...
GLuint GLuint end
Definition: glext.h:3512
std::vector< uint8_t > SIFT
SIFT feature descriptor.
Definition: CFeature.h:88
int val
Definition: mrpt_jpeglib.h:953
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
std::deque< std::vector< double > > multiOrientations
A vector of main orientations (there is a vector of orientations for each scale)
Definition: CFeature.h:79
CFeature()
Constructor.
Definition: CFeature.cpp:416
Classes for computer vision, detectors, features, etc.
uint16_t SpinImg_range_rows
The number of rows (corresponding to range bins in the 2D histogram) of the original matrix from whic...
Definition: CFeature.h:91
A generic 2D feature from an image, extracted with CFeatureExtraction Each feature may have one or mo...
Definition: CFeature.h:53
int version
Definition: mrpt_jpeglib.h:898
A class for parsing text files, returning each non-empty and non-comment line, along its line number...
void plot(const std::vector< T1 > &x, const std::vector< T2 > &y, const std::string &lineFormat=std::string("b-"), const std::string &plotName=std::string("plotXY"))
Adds a new layer with a 2D plot based on two vectors of X and Y points, using a MATLAB-like syntax...
uint64_t TFeatureID
Definition of a feature ID.
Bit-based feature descriptor.
bool hasDescriptorORB() const
Whether this feature has this kind of descriptor.
Definition: CFeature.h:106
void saveToTextFile(const std::string &fileName)
Save list of matched features to a text file.
Definition: CFeature.cpp:1107
GLsizei const GLchar ** string
Definition: glext.h:3919
A list of visual features, to be used as output by detectors, as input/output by trackers, etc.
Definition: CFeature.h:211
TDescriptorType
The bitwise OR combination of values of TDescriptorType are used in CFeatureExtraction::computeDescri...
void dumpToTextStream(mrpt::utils::CStream &out) const
Dump feature information into a text stream.
Definition: CFeature.cpp:233
TFeatureType
Types of features - This means that the point has been detected with this algorithm, which is independent of additional descriptors a feature may also have.
void saveToTextFile(const std::string &fileName, bool APPEND=false)
Save feature list to a text file.
Definition: CFeature.cpp:865
float response
A measure of the "goodness" of the feature (old name: KLT_val)
Definition: CFeature.h:67
#define MRPT_START
bool getFirstDescriptorAsMatrix(mrpt::math::CMatrixFloat &desc) const
Return the first found descriptor, as a matrix.
Definition: CFeature.cpp:1200
virtual ~CFeatureList()
Virtual destructor.
Definition: CFeature.cpp:857
#define RAD2DEG
CFeatureList()
Constructor.
Definition: CFeature.cpp:851
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLdouble GLdouble GLdouble r
Definition: glext.h:3618
void meanAndStd(const VECTORLIKE &v, double &out_mean, double &out_std, bool unbiased=true)
Computes the standard deviation of a vector.
void write(const std::string &section, const std::string &name, const data_t &value, const int name_padding_width=-1, const int value_padding_width=-1, const std::string &comment=std::string())
std::vector< float > SpinImg
The 2D histogram as a single row.
Definition: CFeature.h:90
Speeded Up Robust Feature [BAY&#39;06].
double read_double(const std::string &section, const std::string &name, double defaultValue, bool failIfNotFound=false) const
float descriptorPolarImgDistanceTo(const CFeature &oFeature, float &minDistAngle, bool normalize_distances=true) const
Returns the minimum Euclidean Distance between "this" and the "other" polar image descriptor...
Definition: CFeature.cpp:702
GLuint in
Definition: glext.h:6301
float patchCorrelationTo(const CFeature &oFeature) const
Computes the normalized cross-correlation between the patches of this and another feature (normalized...
Definition: CFeature.cpp:443
#define ASSERT_(f)
virtual ~CMatchedFeatureList()
Virtual destructor.
Definition: CFeature.cpp:1100
TFeatureID getMaxID() const
Get the maximum ID into the list.
Definition: CFeature.cpp:1077
void getByMultiIDs(const std::vector< TFeatureID > &IDs, std::vector< CFeaturePtr > &out, std::vector< int > &outIndex) const
Get a vector of references to a subset of features from their IDs.
Definition: CFeature.cpp:1034
Struct containing the options when matching multi-resolution SIFT-like descriptors.
TInternalFeatList::iterator iterator
Definition: CFeature.h:261
GLenum GLint GLint y
Definition: glext.h:3516
static CFeaturePtr Create()
int BASE_IMPEXP sprintf(char *buf, size_t bufSize, const char *format,...) MRPT_NO_THROWS MRPT_printf_format_check(3
An OS-independent version of sprintf (Notice the bufSize param, which may be ignored in some compiler...
Definition: os.cpp:191
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
Definition: CFeature.cpp:358
Intensity-domain spin image descriptors.
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
mrpt::utils::CImage patch
A patch of the image surrounding the feature.
Definition: CFeature.h:63
bool hasDescriptorPolarImg() const
Whether this feature has this kind of descriptor.
Definition: CFeature.h:101
struct VISION_IMPEXP mrpt::vision::CFeature::TDescriptors descriptors
GLsizeiptr size
Definition: glext.h:3779
CFeaturePtr getByID(const TFeatureID &ID) const
Get a reference to a Feature from its ID.
Definition: CFeature.cpp:1006
float orientation
Main orientation of the feature.
Definition: CFeature.h:68
GLenum GLint x
Definition: glext.h:3516
float descriptorLogPolarImgDistanceTo(const CFeature &oFeature, float &minDistAngle, bool normalize_distances=true) const
Returns the minimum Euclidean Distance between "this" and the "other" log-polar image descriptor...
Definition: CFeature.cpp:728
This class is a "CSerializable" wrapper for "CMatrixFloat".
Definition: CMatrix.h:30
GLenum GLsizei GLsizei height
Definition: glext.h:3523
unsigned __int32 uint32_t
Definition: rptypes.h:49
size_t getWidth() const MRPT_OVERRIDE
Returns the width of the image in pixels.
Definition: CImage.cpp:855
GLuint GLuint GLsizei GLenum type
Definition: glext.h:3512
std::deque< std::vector< std::vector< int32_t > > > multiSIFTDescriptors
A set of SIFT-like descriptors for each orientation and scale of the multiResolution feature (there i...
Definition: CFeature.h:95
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...
double BASE_IMPEXP distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
Definition: geometry.cpp:1504
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
Definition: CStream.cpp:507
mrpt::math::CMatrix PolarImg
A polar image centered at the interest point.
Definition: CFeature.h:92
void copyListFrom(const CFeatureList &otherList)
Copies the content of another CFeatureList inside this one.
Definition: CFeature.cpp:994
size_t getHeight() const MRPT_OVERRIDE
Returns the height of the image in pixels.
Definition: CImage.cpp:884
bool isPointFeature() const
Return false only for Blob detectors (SIFT, SURF)
Definition: CFeature.cpp:435
void saveToConfigFile(mrpt::utils::CConfigFileBase &cfg, const std::string &section) const MRPT_OVERRIDE
This method saves the options to a ".ini"-like file or memory-stored string list. ...
Definition: CFeature.cpp:167
bool hasDescriptorSURF() const
Whether this feature has this kind of descriptor.
Definition: CFeature.h:99
std::vector< uint8_t > ORB
ORB feature descriptor.
Definition: CFeature.h:96



Page generated by Doxygen 1.8.14 for MRPT 1.5.9 Git: 690a4699f Wed Apr 15 19:29:53 2020 +0200 at mié abr 15 19:30:12 CEST 2020