Main MRPT website > C++ reference
MRPT logo
TSimpleFeature.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef _mrpt_vision_TSimpleFeature_H
00029 #define _mrpt_vision_TSimpleFeature_H
00030 
00031 #include <mrpt/utils/TPixelCoord.h>
00032 #include <mrpt/math/KDTreeCapable.h>
00033 #include <mrpt/math/CMatrixTemplateNumeric.h>
00034 #include <mrpt/vision/types.h>
00035 
00036 #include <mrpt/vision/link_pragmas.h>
00037 
00038 namespace mrpt
00039 {
00040         namespace vision
00041         {
00042                 /** \addtogroup  mrptvision_features 
00043                     @{ */
00044 
00045                 /** A simple structure for representing one image feature (without descriptor nor patch) - This is
00046                   *  the template which allows you to select if pixels are represented as integers or floats.
00047                   *  \sa TSimpleFeature, TSimpleFeaturef
00048                   */
00049                 template <typename PIXEL_COORD_TYPE>
00050                 struct TSimpleFeature_templ
00051                 {
00052                         PIXEL_COORD_TYPE    pt;             //!< Coordinates in the image
00053                         TFeatureID          ID;             //!< ID of the feature
00054                         TFeatureTrackStatus     track_status;   //!< Status of the feature tracking process
00055                         float                           response;               //!< A measure of the "goodness" of the feature (typically, the KLT_response value)
00056                         uint8_t                         octave;                 //!< The image octave the image was found in: 0=original image, 1=1/2 image, 2=1/4 image, etc.
00057                         uint8_t                         user_flags;             //!< A field for any other flags needed by the user (this has not a predefined meaning)
00058 
00059                         /** Constructor that only sets the pt.{x,y} values, leaving all other values to *undefined values*. */
00060                         template <typename COORD_TYPE>
00061                         inline TSimpleFeature_templ(const COORD_TYPE x, const COORD_TYPE y) : pt(x,y) { }
00062 
00063                         /** Default constructor, leaves all fields uninitialized */
00064                         inline TSimpleFeature_templ() {}
00065                 };
00066 
00067                 /** A simple structure for representing one image feature (without descriptor nor patch).
00068                   *  \sa TSimpleFeaturef, CFeature, TSimpleFeatureList
00069                   */
00070                 typedef TSimpleFeature_templ<mrpt::utils::TPixelCoord>   TSimpleFeature;
00071 
00072                 /** A version of  TSimpleFeature with subpixel precision */
00073                 typedef TSimpleFeature_templ<mrpt::utils::TPixelCoordf>  TSimpleFeaturef;
00074 
00075 
00076                 template <typename FEATURE> struct TSimpleFeatureTraits;
00077 
00078                 template <> struct TSimpleFeatureTraits<TSimpleFeature>  {
00079                         typedef int   coord_t;
00080 
00081                         static inline coord_t f2coord(float f) { return mrpt::utils::round(f); }
00082                 };
00083 
00084                 template <> struct TSimpleFeatureTraits<TSimpleFeaturef> {
00085                         typedef float coord_t;
00086 
00087                         static inline coord_t f2coord(float f) { return f; }
00088                 };
00089 
00090 
00091 
00092                 /** A list of image features using the structure TSimpleFeature for each feature - capable of KD-tree computations
00093                   *  Users normally use directly the typedef's: TSimpleFeatureList & TSimpleFeaturefList
00094                   */
00095                 template <typename FEATURE>
00096                 struct TSimpleFeatureList_templ
00097                 {
00098                 public:
00099                         typedef std::vector<FEATURE> TFeatureVector;
00100 
00101                         /** @name Utilities
00102                             @{ */
00103 
00104                         /** Returns a const ref to the actual std::vector<> container */
00105                         const TFeatureVector& getVector() const { return m_feats; }
00106 
00107                         /** Returns the maximum ID of all features in the list, or 0 if it's empty */
00108                         TFeatureID getMaxID() const {
00109                                 if (this->empty()) return 0;
00110                                 TFeatureID maxID = m_feats[0].ID;
00111                                 size_t N = m_feats.size()-1;
00112                                 for ( ; N ; --N) mrpt::utils::keep_max(maxID, m_feats[N].ID);
00113                                 return maxID;
00114                         }
00115 
00116                         /** Returns a vector with a LUT of the first feature index per row, to efficiently look for neighbors, etc.
00117                           *  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.
00118                           *  \note FASTER detectors do fill this out. In general, a feature list that dynamically changes will not use this LUT.
00119                           */
00120                         const std::vector<size_t> & getFirstIndexPerRowLUT() const { return m_first_index_per_row; }
00121                         /// \overload
00122                         std::vector<size_t> & getFirstIndexPerRowLUT() { return m_first_index_per_row; }
00123 
00124                         /** Get a ref to the occupation matrix: this is a user-defined matrix, which is not updated automatically by this class. */
00125                         inline mrpt::math::CMatrixBool & getOccupiedSectionsMatrix() { return m_occupied_sections; }
00126                         inline const mrpt::math::CMatrixBool & getOccupiedSectionsMatrix() const { return m_occupied_sections; }
00127 
00128                         /** @} */
00129 
00130                         /** @name Method and datatypes to emulate a STL container
00131                             @{ */
00132                         typedef typename TFeatureVector::iterator iterator;
00133                         typedef typename TFeatureVector::const_iterator const_iterator;
00134 
00135                         typedef typename TFeatureVector::reverse_iterator reverse_iterator;
00136                         typedef typename TFeatureVector::const_reverse_iterator const_reverse_iterator;
00137 
00138                         inline iterator begin() { return m_feats.begin(); }
00139                         inline iterator end() { return m_feats.end(); }
00140                         inline const_iterator begin() const { return m_feats.begin(); }
00141                         inline const_iterator end() const { return m_feats.end(); }
00142 
00143                         inline reverse_iterator rbegin() { return m_feats.rbegin(); }
00144                         inline reverse_iterator rend() { return m_feats.rend(); }
00145                         inline const_reverse_iterator rbegin() const { return m_feats.rbegin(); }
00146                         inline const_reverse_iterator rend() const { return m_feats.rend(); }
00147 
00148                         inline iterator erase(const iterator it)  {  return m_feats.erase(it); }
00149 
00150                         inline bool empty() const  { return m_feats.empty(); }
00151                         inline size_t size() const { return m_feats.size(); }
00152 
00153                         inline void clear() { m_feats.clear(); m_first_index_per_row.clear(); }
00154                         inline void resize(size_t N) { m_feats.resize(N);  }
00155                         inline void reserve(size_t N) { m_feats.reserve(N); }
00156 
00157                         inline void push_back(const FEATURE &f) {   m_feats.push_back(f); }
00158                         inline void push_back_fast (const FEATURE &f) { m_feats.push_back(f); }
00159                         inline void push_back_fast (const int x, const int y) { m_feats.push_back (FEATURE(x,y)); }
00160 
00161                         inline       FEATURE & operator [](const unsigned int index)        { return m_feats[index]; }
00162                         inline const FEATURE & operator [](const unsigned int index) const  { return m_feats[index]; }
00163 
00164                         inline       FEATURE & back()        { return m_feats.back(); }
00165                         inline const FEATURE & back() const  { return m_feats.back(); }
00166 
00167                         inline       FEATURE & front()        { return m_feats.front(); }
00168                         inline const FEATURE & front() const  { return m_feats.front(); }
00169 
00170                         /** @} */
00171 
00172                         /** @name getFeature*() methods for template-based access to feature list
00173                             @{ */
00174                         inline typename TSimpleFeatureTraits<FEATURE>::coord_t getFeatureX(size_t i) const { return m_feats[i].pt.x; }
00175                         inline typename TSimpleFeatureTraits<FEATURE>::coord_t getFeatureY(size_t i) const { return m_feats[i].pt.y; }
00176                         inline TFeatureID getFeatureID(size_t i) const { return m_feats[i].ID; }
00177                         inline float getFeatureResponse(size_t i) const { return m_feats[i].response; }
00178                         inline bool isPointFeature(size_t i) const { return true; }
00179                         inline float getScale(size_t i) const { return static_cast<float>(1<<m_feats[i].octave); }
00180                         inline TFeatureTrackStatus getTrackStatus(size_t i) { return m_feats[i].track_status; }
00181 
00182                         inline void setFeatureX(size_t i,typename TSimpleFeatureTraits<FEATURE>::coord_t x) { m_feats[i].pt.x=x; }
00183                         inline void setFeatureY(size_t i,typename TSimpleFeatureTraits<FEATURE>::coord_t y) { m_feats[i].pt.y=y; }
00184 
00185                         inline void setFeatureXf(size_t i,float x) { m_feats[i].pt.x=TSimpleFeatureTraits<FEATURE>::f2coord(x); }
00186                         inline void setFeatureYf(size_t i,float y) { m_feats[i].pt.y=TSimpleFeatureTraits<FEATURE>::f2coord(y); }
00187 
00188                         inline void setFeatureID(size_t i,TFeatureID id) { m_feats[i]->ID=id; }
00189                         inline void setFeatureResponse(size_t i,float r) { m_feats[i]->response=r; }
00190                         inline void setScale(size_t i,float s) { m_feats[i]->octave=mrpt::utils::round(std::log(s)/std::log(2)); }
00191                         inline void setTrackStatus(size_t i,TFeatureTrackStatus s) { m_feats[i].track_status=s; }
00192 
00193                         inline void mark_as_outdated() const {  }
00194                         /** @} */
00195 
00196                 private:
00197                         TFeatureVector                  m_feats; //!< The actual container with the list of features
00198                         std::vector<size_t>             m_first_index_per_row; //!< A LUT of the first feature index per row, to efficiently look for neighbors, etc.
00199                         mrpt::math::CMatrixBool m_occupied_sections;
00200 
00201                 }; // end of class
00202 
00203                 /** A list of image features using the structure TSimpleFeature for each feature - capable of KD-tree computations */
00204                 typedef TSimpleFeatureList_templ<TSimpleFeature>  TSimpleFeatureList;
00205 
00206                 /** A list of image features using the structure TSimpleFeaturef for each feature - capable of KD-tree computations */
00207                 typedef TSimpleFeatureList_templ<TSimpleFeaturef> TSimpleFeaturefList;
00208 
00209 
00210                 /** A helper struct to sort keypoints by their response: It can be used with these types:
00211                   *       - std::vector<cv::KeyPoint>
00212                   *       - mrpt::vision::TSimpleFeatureList
00213                   */
00214                 template <typename FEATURE_LIST>
00215                 struct KeypointResponseSorter : public std::binary_function<size_t,size_t,bool>
00216                 {
00217                         const FEATURE_LIST &m_data;
00218                         KeypointResponseSorter( const FEATURE_LIST &data ) : m_data(data) { }
00219                         bool operator() (size_t k1, size_t k2 ) const {
00220                                 return (m_data[k1].response > m_data[k2].response);
00221                         }
00222                 };
00223 
00224 
00225                 /** Helper class: KD-tree search class for vector<KeyPoint>:
00226                   *  Call mark_as_outdated() to force rebuilding the kd-tree after modifying the linked feature list.
00227                   *  \tparam FEAT Can be cv::KeyPoint or mrpt::vision::TSimpleFeature
00228                   */
00229                 template <typename FEAT>
00230                 class CFeatureListKDTree : public mrpt::math::KDTreeCapable<CFeatureListKDTree<FEAT> >
00231                 {
00232                 public:
00233                         inline void mark_as_outdated() { mrpt::math::KDTreeCapable<CFeatureListKDTree<FEAT> >::kdtree_mark_as_outdated(); }
00234 
00235                         const std::vector<FEAT> & m_data;
00236                         CFeatureListKDTree(const std::vector<FEAT> & data) : m_data(data) {  }
00237 
00238 
00239                                 /** @name Methods that MUST be implemented by children classes of KDTreeCapable
00240                                         @{ */
00241 
00242                                 /// Must return the number of data points
00243                                 inline size_t kdtree_get_point_count() const {  return m_data.size(); }
00244 
00245                                 /// Returns the dim'th component of the idx'th point in the class:
00246                                 inline float kdtree_get_pt(const size_t idx, int dim) const {
00247                                         ASSERTDEB_(dim==0 || dim==1)
00248                                         if (dim==0) return m_data[idx].pt.x;
00249                                         else return m_data[idx].pt.y;
00250                                 }
00251 
00252                                 /// Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
00253                                 inline float kdtree_distance(const float *p1, const size_t idx_p2,size_t size) const
00254                                 {
00255                                         ASSERTDEB_(size==2)
00256 
00257                                         const float d0 = p1[0] - m_data[idx_p2].pt.x;
00258                                         const float d1 = p1[1] - m_data[idx_p2].pt.y;
00259                                         return d0*d0+d1*d1;
00260                                 }
00261 
00262                                 // Optional bounding-box computation: return false to default to a standard bbox computation loop.
00263                                 //   Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
00264                                 //   Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
00265                                 template <typename BBOX>
00266                                 bool kdtree_get_bbox(BBOX &bb) const  { return false; }
00267 
00268                                 /** @} */
00269 
00270                 }; // end CFeatureListKDTree
00271 
00272 
00273                 /** @} */ // End of add to module: mrptvision_features
00274 
00275         } // end of namespace
00276 
00277 } // end of namespace
00278 
00279 #endif
00280 



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011