Main MRPT website > C++ reference
MRPT logo
TSimpleFeature.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 #ifndef _mrpt_vision_TSimpleFeature_H
29 #define _mrpt_vision_TSimpleFeature_H
30 
31 #include <mrpt/utils/TPixelCoord.h>
34 #include <mrpt/vision/types.h>
35 
37 
38 namespace mrpt
39 {
40  namespace vision
41  {
42  /** \addtogroup mrptvision_features
43  @{ */
44 
45  /** A simple structure for representing one image feature (without descriptor nor patch) - This is
46  * the template which allows you to select if pixels are represented as integers or floats.
47  * \sa TSimpleFeature, TSimpleFeaturef
48  */
49  template <typename PIXEL_COORD_TYPE>
51  {
52  typedef PIXEL_COORD_TYPE pixel_coords_t; //!< The type of \a pt
53  typedef typename PIXEL_COORD_TYPE::pixel_coord_t pixel_coord_t; //!< The type of pt.x and pt.y
54 
55  pixel_coords_t pt; //!< Coordinates in the image
56  TFeatureID ID; //!< ID of the feature
57  TFeatureTrackStatus track_status; //!< Status of the feature tracking process
58  float response; //!< A measure of the "goodness" of the feature (typically, the KLT_response value)
59  uint8_t octave; //!< The image octave the image was found in: 0=original image, 1=1/2 image, 2=1/4 image, etc.
60  uint8_t user_flags; //!< A field for any other flags needed by the user (this has not a predefined meaning)
61 
62  /** Constructor that only sets the pt.{x,y} values, leaving all other values to *undefined values*. */
63  template <typename COORD_TYPE>
64  inline TSimpleFeature_templ(const COORD_TYPE x, const COORD_TYPE y) : pt(x,y) { }
65 
66  /** Default constructor, leaves all fields uninitialized */
68 
69  template <typename OTHER_TSIMPLEFEATURE>
70  explicit TSimpleFeature_templ(const OTHER_TSIMPLEFEATURE &o) :
71  pt(o.pt.x,o.pt.y),
72  ID(o.ID),
74  response(o.response),
75  octave(o.octave),
77  {
78  }
79  };
80 
81  /** A simple structure for representing one image feature (without descriptor nor patch).
82  * \sa TSimpleFeaturef, CFeature, TSimpleFeatureList
83  */
85 
86  /** A version of TSimpleFeature with subpixel precision */
88 
89 
90  template <typename FEATURE> struct TSimpleFeatureTraits;
91 
92  template <> struct TSimpleFeatureTraits<TSimpleFeature> {
93  typedef int coord_t;
94 
95  static inline coord_t f2coord(float f) { return mrpt::utils::round(f); }
96  };
97 
98  template <> struct TSimpleFeatureTraits<TSimpleFeaturef> {
99  typedef float coord_t;
100 
101  static inline coord_t f2coord(float f) { return f; }
102  };
103 
104 
105 
106  /** A list of image features using the structure TSimpleFeature for each feature - capable of KD-tree computations
107  * Users normally use directly the typedef's: TSimpleFeatureList & TSimpleFeaturefList
108  */
109  template <typename FEATURE>
111  {
112  public:
113  typedef std::vector<FEATURE> TFeatureVector;
114  typedef FEATURE feature_t;
115 
116  /** @name Utilities
117  @{ */
118 
119  /** Returns a const ref to the actual std::vector<> container */
120  const TFeatureVector& getVector() const { return m_feats; }
121 
122  /** Returns the maximum ID of all features in the list, or 0 if it's empty */
124  if (this->empty()) return 0;
125  TFeatureID maxID = m_feats[0].ID;
126  size_t N = m_feats.size()-1;
127  for ( ; N ; --N) mrpt::utils::keep_max(maxID, m_feats[N].ID);
128  return maxID;
129  }
130 
131  /** Returns a vector with a LUT of the first feature index per row, to efficiently look for neighbors, etc.
132  * By default this vector is empty, so if a feature detector is used that doesn't fill this out, it will remain empty and useless.
133  * \note FASTER detectors do fill this out. In general, a feature list that dynamically changes will not use this LUT.
134  */
135  const std::vector<size_t> & getFirstIndexPerRowLUT() const { return m_first_index_per_row; }
136  /// \overload
137  std::vector<size_t> & getFirstIndexPerRowLUT() { return m_first_index_per_row; }
138 
139  /** Get a ref to the occupation matrix: this is a user-defined matrix, which is not updated automatically by this class. */
142 
143  /** @} */
144 
145  /** @name Method and datatypes to emulate a STL container
146  @{ */
149 
150  typedef typename TFeatureVector::reverse_iterator reverse_iterator;
151  typedef typename TFeatureVector::const_reverse_iterator const_reverse_iterator;
152 
153  inline iterator begin() { return m_feats.begin(); }
154  inline iterator end() { return m_feats.end(); }
155  inline const_iterator begin() const { return m_feats.begin(); }
156  inline const_iterator end() const { return m_feats.end(); }
157 
158  inline reverse_iterator rbegin() { return m_feats.rbegin(); }
159  inline reverse_iterator rend() { return m_feats.rend(); }
160  inline const_reverse_iterator rbegin() const { return m_feats.rbegin(); }
161  inline const_reverse_iterator rend() const { return m_feats.rend(); }
162 
163  inline iterator erase(const iterator it) { return m_feats.erase(it); }
164 
165  inline bool empty() const { return m_feats.empty(); }
166  inline size_t size() const { return m_feats.size(); }
167 
168  inline void clear() { m_feats.clear(); m_first_index_per_row.clear(); }
169  inline void resize(size_t N) { m_feats.resize(N); }
170  inline void reserve(size_t N) { m_feats.reserve(N); }
171 
172  inline void push_back(const FEATURE &f) { m_feats.push_back(f); }
173  inline void push_back_fast (const FEATURE &f) { m_feats.push_back(f); }
174  inline void push_back_fast (const int x, const int y) { m_feats.push_back (FEATURE(x,y)); }
175 
176  inline FEATURE & operator [](const unsigned int index) { return m_feats[index]; }
177  inline const FEATURE & operator [](const unsigned int index) const { return m_feats[index]; }
178 
179  inline FEATURE & back() { return m_feats.back(); }
180  inline const FEATURE & back() const { return m_feats.back(); }
181 
182  inline FEATURE & front() { return m_feats.front(); }
183  inline const FEATURE & front() const { return m_feats.front(); }
184 
185  /** @} */
186 
187  /** @name getFeature*() methods for template-based access to feature list
188  @{ */
189  inline typename TSimpleFeatureTraits<FEATURE>::coord_t getFeatureX(size_t i) const { return m_feats[i].pt.x; }
190  inline typename TSimpleFeatureTraits<FEATURE>::coord_t getFeatureY(size_t i) const { return m_feats[i].pt.y; }
191  inline TFeatureID getFeatureID(size_t i) const { return m_feats[i].ID; }
192  inline float getFeatureResponse(size_t i) const { return m_feats[i].response; }
193  inline bool isPointFeature(size_t i) const { return true; }
194  inline float getScale(size_t i) const { return static_cast<float>(1<<m_feats[i].octave); }
195  inline TFeatureTrackStatus getTrackStatus(size_t i) { return m_feats[i].track_status; }
196 
197  inline void setFeatureX(size_t i,typename TSimpleFeatureTraits<FEATURE>::coord_t x) { m_feats[i].pt.x=x; }
198  inline void setFeatureY(size_t i,typename TSimpleFeatureTraits<FEATURE>::coord_t y) { m_feats[i].pt.y=y; }
199 
200  inline void setFeatureXf(size_t i,float x) { m_feats[i].pt.x=TSimpleFeatureTraits<FEATURE>::f2coord(x); }
201  inline void setFeatureYf(size_t i,float y) { m_feats[i].pt.y=TSimpleFeatureTraits<FEATURE>::f2coord(y); }
202 
203  inline void setFeatureID(size_t i,TFeatureID id) { m_feats[i]->ID=id; }
204  inline void setFeatureResponse(size_t i,float r) { m_feats[i]->response=r; }
205  inline void setScale(size_t i,float s) { m_feats[i]->octave=mrpt::utils::round(std::log(s)/std::log(2)); }
206  inline void setTrackStatus(size_t i,TFeatureTrackStatus s) { m_feats[i].track_status=s; }
207 
208  inline void mark_as_outdated() const { }
209  /** @} */
210 
211  private:
212  TFeatureVector m_feats; //!< The actual container with the list of features
213  std::vector<size_t> m_first_index_per_row; //!< A LUT of the first feature index per row, to efficiently look for neighbors, etc.
215 
216  }; // end of class
217 
218  /** A list of image features using the structure TSimpleFeature for each feature - capable of KD-tree computations */
220 
221  /** A list of image features using the structure TSimpleFeaturef for each feature - capable of KD-tree computations */
223 
224 
225  /** A helper struct to sort keypoints by their response: It can be used with these types:
226  * - std::vector<cv::KeyPoint>
227  * - mrpt::vision::TSimpleFeatureList
228  */
229  template <typename FEATURE_LIST>
230  struct KeypointResponseSorter : public std::binary_function<size_t,size_t,bool>
231  {
232  const FEATURE_LIST &m_data;
233  KeypointResponseSorter( const FEATURE_LIST &data ) : m_data(data) { }
234  bool operator() (size_t k1, size_t k2 ) const {
235  return (m_data[k1].response > m_data[k2].response);
236  }
237  };
238 
239 
240  /** Helper class: KD-tree search class for vector<KeyPoint>:
241  * Call mark_as_outdated() to force rebuilding the kd-tree after modifying the linked feature list.
242  * \tparam FEAT Can be cv::KeyPoint or mrpt::vision::TSimpleFeature
243  */
244  template <typename FEAT>
245  class CFeatureListKDTree : public mrpt::math::KDTreeCapable<CFeatureListKDTree<FEAT> >
246  {
247  public:
249 
250  const std::vector<FEAT> & m_data;
251  CFeatureListKDTree(const std::vector<FEAT> & data) : m_data(data) { }
252 
253 
254  /** @name Methods that MUST be implemented by children classes of KDTreeCapable
255  @{ */
256 
257  /// Must return the number of data points
258  inline size_t kdtree_get_point_count() const { return m_data.size(); }
259 
260  /// Returns the dim'th component of the idx'th point in the class:
261  inline float kdtree_get_pt(const size_t idx, int dim) const {
262  ASSERTDEB_(dim==0 || dim==1)
263  if (dim==0) return m_data[idx].pt.x;
264  else return m_data[idx].pt.y;
265  }
266 
267  /// Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
268  inline float kdtree_distance(const float *p1, const size_t idx_p2,size_t size) const
269  {
270  ASSERTDEB_(size==2)
271 
272  const float d0 = p1[0] - m_data[idx_p2].pt.x;
273  const float d1 = p1[1] - m_data[idx_p2].pt.y;
274  return d0*d0+d1*d1;
275  }
276 
277  // Optional bounding-box computation: return false to default to a standard bbox computation loop.
278  // Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
279  // Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
280  template <typename BBOX>
281  bool kdtree_get_bbox(BBOX &bb) const { return false; }
282 
283  /** @} */
284 
285  }; // end CFeatureListKDTree
286 
287 
288  /** @} */ // End of add to module: mrptvision_features
289 
290  } // end of namespace
291 
292 } // end of namespace
293 
294 #endif
295 



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013