MRPT  2.0.2
CFeatureExtraction_SIFT.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "vision-precomp.h" // Precompiled headers
11 
12 #include <mrpt/system/os.h>
14 
15 // Universal include for all versions of OpenCV
16 #include <mrpt/3rdparty/do_opencv_includes.h>
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::system;
31 using namespace mrpt::math;
32 using namespace std;
33 
34 #if MRPT_HAS_OPENCV
35 using namespace cv;
36 #endif
37 
39  const CImage& img, CFeatureList& feats, unsigned int init_ID,
40  unsigned int nDesiredFeatures, const TImageROI& ROI)
41 {
42  mrpt::system::CTimeLoggerEntry tle(profiler, "extractFeaturesSIFT");
43 
44  bool usingROI = false;
45  if (ROI.xMin != 0 || ROI.xMax != 0 || ROI.yMin != 0 || ROI.yMax != 0)
46  usingROI = true; // A ROI has been defined
47 
48  // ROI can not be managed properly (yet) with these method, so we extract a
49  // subimage
50 
51  // use a smart pointer so we just copy the pointer if the image is
52  // grayscale, or we'll create a new one if it was RGB:
53  CImage img_grayscale(
54  img, FAST_REF_OR_CONVERT_TO_GRAY); // Was: auxImg::Ptr;
55  if (usingROI)
56  {
57  ASSERT_(
58  ROI.xMin < ROI.xMax && ROI.xMax < img.getWidth() &&
59  ROI.yMax < img.getHeight() && ROI.yMin < ROI.yMax);
60  CImage auximg;
61  img_grayscale.extract_patch(
62  auximg, ROI.xMin, ROI.yMin, ROI.xMax - ROI.xMin + 1,
63  ROI.yMax - ROI.yMin + 1); // Subimage in "auxImg"
64  img_grayscale.swap(auximg);
65  }
66 
67  switch (options.SIFTOptions.implementation)
68  {
69  case CSBinary:
70  {
72  "CSBinary SIFT not available since MRPT 1.9.9: "
73  "Use `OpenCV` version");
74  break;
75  } // end case Binary in C#
76  case VedaldiBinary:
77  {
79  "Vedaldi SIFT not available since MRPT 1.9.9: "
80  "Use `OpenCV` version");
81  break;
82  } // end case Binary by Vedaldi
83  case LoweBinary: // Binary by David Lowe
84  {
86  "LoweBinary not available since MRPT 1.9.9: "
87  "Use `OpenCV` version");
88  break;
89  } // end case Binary by Lowe
90  case Hess: // Implementation by Robert Hess
91  {
93  "Hess SIFT not available since MRPT 1.9.9: "
94  "Use `OpenCV` version");
95  break;
96  } // end case Hess
97  //***********************************************************************************************
98  // USING OPENCV
99  //***********************************************************************************************
100  case OpenCV:
101  {
102 #if defined(HAVE_OPENCV_NONFREE) || defined(HAVE_OPENCV_XFEATURES2D)
103 
104 #if MRPT_OPENCV_VERSION_NUM < 0x300
105  SiftFeatureDetector SIFTDetector(
106  options.SIFTOptions.threshold,
107  options.SIFTOptions.edgeThreshold);
108 
109  SiftDescriptorExtractor SIFTDescriptor;
110  vector<KeyPoint> cv_feats; // The OpenCV output feature list
111  const Mat& theImg = img_grayscale.asCvMatRef();
112  SIFTDetector.detect(theImg, cv_feats);
113  Mat desc;
114  SIFTDescriptor.compute(theImg, cv_feats, desc);
115 #else
116  // MRPT_OPENCV_VERSION_NUM >= 0x300
117  using namespace cv;
118  vector<KeyPoint> cv_feats;
119 
120  auto sift = cv::xfeatures2d::SIFT::create(
121  nDesiredFeatures, options.SIFTOptions.octaveLayers,
122  options.SIFTOptions.threshold,
123  options.SIFTOptions.edgeThreshold, 1.6);
124  const Mat& theImg = img_grayscale.asCvMatRef();
125  Mat desc;
126  sift->detectAndCompute(theImg, noArray() /*mask*/, cv_feats, desc);
127 #endif
128  const size_t N = cv_feats.size();
129  // std::cout << "N:" << N << "\n";
130  unsigned int nMax = nDesiredFeatures != 0 && N > nDesiredFeatures
131  ? nDesiredFeatures
132  : N;
133  const int offset = (int)this->options.patchSize / 2 + 1;
134  const size_t size_2 = options.patchSize / 2;
135  const size_t imgH = img.getHeight();
136  const size_t imgW = img.getWidth();
137  unsigned int i = 0;
138  unsigned int cont = 0;
139  TFeatureID nextID = init_ID;
140  feats.clear();
141 
142  while (cont != nMax && i != N)
143  {
144  const int xBorderInf = (int)floor(cv_feats[i].pt.x - size_2);
145  const int xBorderSup = (int)floor(cv_feats[i].pt.x + size_2);
146  const int yBorderInf = (int)floor(cv_feats[i].pt.y - size_2);
147  const int yBorderSup = (int)floor(cv_feats[i].pt.y + size_2);
148 
149  if (options.patchSize == 0 ||
150  ((xBorderSup < (int)imgW) && (xBorderInf > 0) &&
151  (yBorderSup < (int)imgH) && (yBorderInf > 0)))
152  {
153  CFeature ft;
154  ft.type = featSIFT;
155  ft.keypoint.ID = nextID++;
156  ft.keypoint.pt.x = cv_feats[i].pt.x;
157  ft.keypoint.pt.y = cv_feats[i].pt.y;
158  ft.keypoint.response = cv_feats[i].response;
159  ft.orientation = cv_feats[i].angle;
160  ft.keypoint.octave =
161  mrpt::round(std::log2(cv_feats[i].size));
162  ft.patchSize = options.patchSize;
163 
164  // The descriptor
165  ft.descriptors.SIFT.emplace();
166  auto& out_desc = ft.descriptors.SIFT.value();
167  out_desc.resize(128);
168  memcpy(
169  &out_desc[0], &desc.data[128 * i],
170  128 * sizeof(out_desc[0]));
171 
172  if (options.patchSize > 0)
173  {
175  img.extract_patch(
176  p, round(ft.keypoint.pt.x) - offset,
177  round(ft.keypoint.pt.y) - offset, options.patchSize,
178  options.patchSize);
179  ft.patch = std::move(p);
180  }
181  feats.push_back(ft);
182  ++cont;
183  }
184  ++i;
185  }
186  feats.resize(cont);
187 #else
189  "This method requires OpenCV >= 2.1.1 with nonfree module");
190 #endif
191  break;
192  } // end case OpenCV
193  return;
194  default:
195  {
196  break;
197  } // end default
198  } // end switch
199 } // end extractFeaturesSIFT
200 
201 // Compute SIFT descriptors on a set of already localized points
203  const CImage& in_img, CFeatureList& in_features)
204 {
206  profiler, "internal_computeSiftDescriptors");
207 
208  ASSERT_(in_features.size() > 0);
209  // switch (options.SIFTOptions.implementation)
211  "SIFT Extraction method not supported for features with already known "
212  "image coordinates");
213 
214 } // end computeSiftDescriptors
void internal_computeSiftDescriptors(const mrpt::img::CImage &in_img, CFeatureList &in_features)
Compute the SIFT descriptor of the provided features into the input image.
uint64_t TFeatureID
Definition of a feature ID.
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
A safe way to call enter() and leave() of a mrpt::system::CTimeLogger upon construction and destructi...
size_t size(const MATRIXLIKE &m, const int dim)
TKeyPointMethod type
Keypoint method used to detect this feature.
Definition: CFeature.h:73
size_t size() const
Definition: CFeature.h:352
cv::Mat & asCvMatRef()
Get a reference to the internal cv::Mat, which can be resized, etc.
Definition: CImage.cpp:227
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:849
Scale Invariant Feature Transform [LOWE&#39;04].
STL namespace.
TFeatureID ID
ID of the feature.
Definition: TKeyPoint.h:39
Definition: img/CImage.h:23
void swap(CImage &o)
Efficiently swap of two images.
Definition: CImage.cpp:171
A structure for defining a ROI within an image.
size_t yMin
Y coordinate limits [0,imageHeight)
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:120
void push_back(const CFeature &f)
Definition: CFeature.h:369
This base provides a set of functions for maths stuff.
size_t getWidth() const override
Returns the width of the image in pixels.
Definition: CImage.cpp:818
void resize(size_t N)
Definition: CFeature.h:358
TKeyPointf keypoint
Definition: CFeature.h:64
std::optional< mrpt::img::CImage > patch
A patch of the image surrounding the feature.
Definition: CFeature.h:67
Classes for computer vision, detectors, features, etc.
Definition: CDifodo.h:17
A generic 2D feature from an image, extracted with CFeatureExtraction Each feature may have one or mo...
Definition: CFeature.h:53
A list of visual features, to be used as output by detectors, as input/output by trackers, etc.
Definition: CFeature.h:275
size_t xMin
X coordinate limits [0,imageWidth)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::optional< std::vector< uint8_t > > SIFT
SIFT feature descriptor.
Definition: CFeature.h:110
TDescriptors descriptors
Definition: CFeature.h:157
uint8_t octave
The image octave the image was found in: 0=original image, 1=1/2 image, 2=1/4 image, etc.
Definition: TKeyPoint.h:49
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:1166
void extractFeaturesSIFT(const mrpt::img::CImage &img, CFeatureList &feats, unsigned int init_ID=0, unsigned int nDesiredFeatures=0, const TImageROI &ROI=TImageROI())
Extract features from the image based on the SIFT method.
float orientation
Main orientation of the feature.
Definition: CFeature.h:81
float response
A measure of the "goodness" of the feature (typically, the KLT_response value)
Definition: TKeyPoint.h:46
uint16_t patchSize
Size of the patch (patchSize x patchSize) (it must be an odd number)
Definition: CFeature.h:70
pixel_coords_t pt
Coordinates in the image.
Definition: TKeyPoint.h:36
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:148
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:24



Page generated by Doxygen 1.8.14 for MRPT 2.0.2 Git: 9b4fd2465 Mon May 4 16:59:08 2020 +0200 at lun may 4 17:26:07 CEST 2020