Main MRPT website > C++ reference for MRPT 1.9.9
CFeatureExtraction_SURF.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-2018, 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 
13 
14 // Universal include for all versions of OpenCV
15 #include <mrpt/otherlibs/do_opencv_includes.h>
16 
17 #ifdef HAVE_OPENCV_NONFREE // MRPT_HAS_OPENCV_NONFREE
18 #include <opencv2/nonfree/nonfree.hpp>
19 #endif
20 #ifdef HAVE_OPENCV_FEATURES2D
21 #include <opencv2/features2d/features2d.hpp>
22 #endif
23 #ifdef HAVE_OPENCV_XFEATURES2D
24 #include <opencv2/xfeatures2d.hpp>
25 #endif
26 
27 using namespace mrpt;
28 using namespace mrpt::vision;
29 using namespace mrpt::img;
30 using namespace mrpt::img;
31 using namespace mrpt::system;
32 using namespace std;
33 
34 // Was: MRPT_HAS_OPENCV_NONFREE
35 #if defined(HAVE_OPENCV_XFEATURES2D) || \
36  (MRPT_OPENCV_VERSION_NUM < 0x300 && MRPT_OPENCV_VERSION_NUM >= 0x240)
37 #define HAVE_OPENCV_WITH_SURF 1
38 #else
39 #define HAVE_OPENCV_WITH_SURF 0
40 #endif
41 
42 /************************************************************************************************
43 * extractFeaturesSURF *
44 ************************************************************************************************/
46  const mrpt::img::CImage& inImg, CFeatureList& feats, unsigned int init_ID,
47  unsigned int nDesiredFeatures, const TImageROI& ROI) const
48 {
49 #if HAVE_OPENCV_WITH_SURF
50  using namespace cv;
51 
52  const CImage img_grayscale(inImg, FAST_REF_OR_CONVERT_TO_GRAY);
53  const Mat img = cvarrToMat(img_grayscale.getAs<IplImage>());
54 
55  vector<KeyPoint> cv_feats; // OpenCV keypoint output vector
56  Mat cv_descs; // OpenCV descriptor output
57 
58 // gb redesign start -make sure that the Algorithm::create is used only for
59 // older openCV versions
60 #if MRPT_OPENCV_VERSION_NUM < 0x300 && MRPT_OPENCV_VERSION_NUM >= 0x240
61 
62  Ptr<Feature2D> surf = Algorithm::create<Feature2D>("Feature2D.SURF");
63  if (surf.empty())
64  CV_Error(
65  CV_StsNotImplemented,
66  "OpenCV <v3.0 was built without SURF support");
67 
68  surf->set("hessianThreshold", options.SURFOptions.hessianThreshold);
69  surf->set("nOctaves", options.SURFOptions.nOctaves);
70  surf->set("nOctaveLayers", options.SURFOptions.nLayersPerOctave);
71  // surf->set("upright", params.upright != 0);
72  surf->set("extended", options.SURFOptions.rotation_invariant);
73 
74  surf->operator()(img, Mat(), cv_feats, cv_descs);
75 
76 #else
77  Ptr<xfeatures2d::SURF> surf =
78  xfeatures2d::SURF::create(100.0, 4, 3, 0, 0); // gb
79 
80  if (surf.empty())
81  CV_Error(
82  CV_StsNotImplemented, "OpenCV 3.0 was built without SURF support");
83  surf->setHessianThreshold(options.SURFOptions.hessianThreshold);
84  surf->setNOctaves(options.SURFOptions.nOctaves);
85  surf->setNOctaveLayers(options.SURFOptions.nLayersPerOctave);
86  // surf->setUpright(params.upright != 0);
87  surf->setExtended(options.SURFOptions.rotation_invariant);
88  // gb redesign end
89  surf->detectAndCompute(img, Mat(), cv_feats, cv_descs);
90 #endif
91 
92  // -----------------------------------------------------------------
93  // MRPT Wrapping
94  // -----------------------------------------------------------------
95  feats.clear();
96  unsigned int nCFeats = init_ID;
97  int offset = (int)this->options.patchSize / 2 + 1;
98  unsigned int imgH = inImg.getHeight();
99  unsigned int imgW = inImg.getWidth();
100 
101  const size_t n_feats =
102  (nDesiredFeatures == 0)
103  ? cv_feats.size()
104  : std::min((size_t)nDesiredFeatures, cv_feats.size());
105 
106  for (size_t i = 0; i < n_feats; i++)
107  {
108  // Get the OpenCV SURF point
109  CFeature::Ptr ft = mrpt::make_aligned_shared<CFeature>();
110  const KeyPoint& point = cv_feats[i];
111 
112  const int xBorderInf = (int)floor(point.pt.x - options.patchSize / 2);
113  const int xBorderSup = (int)floor(point.pt.x + options.patchSize / 2);
114  const int yBorderInf = (int)floor(point.pt.y - options.patchSize / 2);
115  const int yBorderSup = (int)floor(point.pt.y + options.patchSize / 2);
116 
117  if (options.patchSize == 0 ||
118  ((xBorderSup < (int)imgW) && (xBorderInf > 0) &&
119  (yBorderSup < (int)imgH) && (yBorderInf > 0)))
120  {
121  ft->type = featSURF;
122  ft->x = point.pt.x; // X position
123  ft->y = point.pt.y; // Y position
124  ft->orientation = point.angle; // Orientation
125  ft->scale = point.size * 1.2 / 9; // Scale
126  ft->ID = nCFeats++; // Feature ID into extraction
127  ft->patchSize = options.patchSize; // The size of the feature patch
128 
129  if (options.patchSize > 0)
130  {
131  inImg.extract_patch(
132  ft->patch, round(ft->x) - offset, round(ft->y) - offset,
133  options.patchSize,
134  options.patchSize); // Image patch surronding the feature
135  }
136 
137  // Get the SURF descriptor
138  ft->descriptors.SURF.resize(cv_descs.cols);
139  for (int m = 0; m < cv_descs.cols; ++m)
140  ft->descriptors.SURF[m] = cv_descs.at<float>(i, m);
141 
142  feats.push_back(ft);
143 
144  } // end if
145  } // end for
146 
147 #else
149  "Method not available: MRPT compiled without OpenCV, or against a "
150  "version of OpenCV without SURF")
151 #endif // MRPT_HAS_OPENCV
152 } // end extractFeaturesSURF
153 
154 /************************************************************************************************
155 * internal_computeSurfDescriptors
156 ************************************************************************************************/
158  const mrpt::img::CImage& inImg, CFeatureList& in_features) const
159 {
160 #if HAVE_OPENCV_WITH_SURF
161  using namespace cv;
162 
163  if (in_features.empty()) return;
164 
165  const CImage img_grayscale(inImg, FAST_REF_OR_CONVERT_TO_GRAY);
166  const Mat img = cvarrToMat(img_grayscale.getAs<IplImage>());
167 
168  vector<KeyPoint> cv_feats; // OpenCV keypoint output vector
169  Mat cv_descs; // OpenCV descriptor output
170 
171  // Fill in the desired key-points:
172  cv_feats.resize(in_features.size());
173  for (size_t i = 0; i < in_features.size(); ++i)
174  {
175  cv_feats[i].pt.x = in_features[i]->x;
176  cv_feats[i].pt.y = in_features[i]->y;
177  cv_feats[i].size = 16; // sizes[layer];
178  }
179 
180 // Only computes the descriptors:
181 // gb redesign
182 #if MRPT_OPENCV_VERSION_NUM < 0x300 && MRPT_OPENCV_VERSION_NUM >= 0x240
183 
184  Ptr<Feature2D> surf = Algorithm::create<Feature2D>("Feature2D.SURF");
185  if (surf.empty())
186  CV_Error(CV_StsNotImplemented, "OpenCV was built without SURF support");
187  surf->set("hessianThreshold", options.SURFOptions.hessianThreshold);
188  surf->set("nOctaves", options.SURFOptions.nOctaves);
189  surf->set("nOctaveLayers", options.SURFOptions.nLayersPerOctave);
190  // surf->set("upright", params.upright != 0);
191  surf->set("extended", options.SURFOptions.rotation_invariant);
192 
193  surf->compute(
194  img, cv_feats,
195  cv_descs); // is that correct? the version from above is:
196 // surf->operator()(img, Mat(), cv_feats, cv_descs);
197 #else
198 
199  Ptr<xfeatures2d::SURF> surf =
200  xfeatures2d::SURF::create(100.0, 4, 3, 0, 0); // gb
201 
202  if (surf.empty())
203  CV_Error(CV_StsNotImplemented, "OpenCV was built without SURF support");
204  surf->setHessianThreshold(options.SURFOptions.hessianThreshold);
205  surf->setNOctaves(options.SURFOptions.nOctaves);
206  surf->setNOctaveLayers(options.SURFOptions.nLayersPerOctave);
207  // surf->setUpright(params.upright != 0);
208  surf->setExtended(options.SURFOptions.rotation_invariant);
209 
210  surf->detectAndCompute(img, Mat(), cv_feats, cv_descs);
211 #endif
212  // gb redesign end
213  // -----------------------------------------------------------------
214  // MRPT Wrapping
215  // -----------------------------------------------------------------
216  CFeatureList::iterator itList;
217  int i;
218  for (i = 0, itList = in_features.begin(); itList != in_features.end();
219  itList++, i++)
220  {
221  // Get the OpenCV SURF point
222  CFeature::Ptr ft = *itList;
223  const KeyPoint& point = cv_feats[i];
224 
225  ft->orientation = point.angle; // Orientation
226  ft->scale = point.size * 1.2 / 9; // Scale
227 
228  // Get the SURF descriptor
229  ft->descriptors.SURF.resize(cv_descs.cols);
230  for (int m = 0; m < cv_descs.cols; ++m)
231  ft->descriptors.SURF[m] =
232  cv_descs.at<float>(i, m); // Get the SURF descriptor
233  } // end for
234 
235 #else
237  "Method not available: MRPT compiled without OpenCV, or against a "
238  "version of OpenCV without SURF")
239 #endif // MRPT_HAS_OPENCV
240 } // end internal_computeSurfDescriptors
const T * getAs() const
Returns a pointer to a const T* containing the image - the idea is to call like "img.getAs<IplImage>()" so we can avoid here including OpenCV&#39;s headers.
Definition: img/CImage.h:599
#define min(a, b)
TInternalFeatList::iterator iterator
Definition: CFeature.h:365
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:25
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
size_t size() const
Definition: CFeature.h:386
GLintptr offset
Definition: glext.h:3925
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:892
STL namespace.
A structure for defining a ROI within an image.
size_t getWidth() const override
Returns the width of the image in pixels.
Definition: CImage.cpp:864
GLint GLvoid * img
Definition: glext.h:3763
Classes for computer vision, detectors, features, etc.
Definition: CCamModel.h:20
A list of visual features, to be used as output by detectors, as input/output by trackers, etc.
Definition: CFeature.h:304
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Speeded Up Robust Feature [BAY&#39;06].
void extractFeaturesSURF(const mrpt::img::CImage &img, CFeatureList &feats, unsigned int init_ID=0, unsigned int nDesiredFeatures=0, const TImageROI &ROI=TImageROI()) const
Extract features from the image based on the SURF method.
void extract_patch(CImage &patch, const unsigned int col=0, const unsigned int row=0, const unsigned int width=1, const unsigned int height=1) const
Extract a patch from this image, saveing it into "patch" (its previous contents will be overwritten)...
Definition: CImage.cpp:1359
void push_back(const CFeature::Ptr &f)
Definition: CFeature.h:398
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:130
void internal_computeSurfDescriptors(const mrpt::img::CImage &in_img, CFeatureList &in_features) const
Compute the SURF descriptor of the provided features into the input image.
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:23



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at lun oct 28 00:14:14 CET 2019