Main MRPT website > C++ reference for MRPT 1.9.9
CFeatureExtraction_LSD_BLD.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 /*---------------------------------------------------------------
11  CLASS: CFeatureExtraction
12  FILE: CFeatureExtraction_LSD_BLD.cpp
13  AUTHOR: Raghavender Sahdev <raghavendersahdev@gmail.com>
14  ---------------------------------------------------------------*/
15 
16 #include "vision-precomp.h" // Precompiled headers
17 #include <mrpt/system/os.h>
18 #include <mrpt/vision/CFeatureExtraction.h> // important import
20 #include <mrpt/otherlibs/do_opencv_includes.h>
21 
22 #ifdef HAVE_OPENCV_XFEATURES2D
23 #include <opencv2/xfeatures2d.hpp>
24 #endif
25 #ifdef HAVE_OPENCV_LINE_DESCRIPTOR
26 #include <opencv2/line_descriptor.hpp>
27 using namespace cv::line_descriptor;
28 #endif
29 
30 using namespace mrpt::vision;
31 using namespace mrpt::utils;
32 using namespace mrpt::math;
33 using namespace mrpt;
34 using namespace std;
35 
36 #if defined(HAVE_OPENCV_XFEATURES2D) && defined(HAVE_OPENCV_LINE_DESCRIPTOR)
37 #define HAVE_OPENCV_WITH_LSD 1
38 #else
39 #define HAVE_OPENCV_WITH_LSD 0
40 #endif
41 
42 void CFeatureExtraction::extractFeaturesLSD(
43  const mrpt::utils::CImage& inImg, CFeatureList& feats, unsigned int init_ID,
44  unsigned int nDesiredFeatures, const TImageROI& ROI) const
45 {
47 #if (!HAVE_OPENCV_WITH_LSD)
49  "This function requires OpenCV modules: xfeatures2d, line_descriptor");
50 #else
51  using namespace cv;
52 
53  vector<KeyPoint> cv_feats; // The opencv keypoint output vector
54  vector<KeyLine> cv_line;
55 
56  // Make sure we operate on a gray-scale version of the image:
57  const CImage inImg_gray(inImg, FAST_REF_OR_CONVERT_TO_GRAY);
58 
59  const Mat theImg = cvarrToMat(inImg_gray.getAs<IplImage>());
60  /* create a random binary mask */
61  cv::Mat mask = Mat::ones(theImg.size(), CV_8UC1);
62 
63  Ptr<LSDDetector> bd = LSDDetector::createLSDDetector();
64 
65  /* extract lines */
66  cv::Mat output = theImg.clone();
67  bd->detect(
68  theImg, cv_line, options.LSDOptions.scale, options.LSDOptions.nOctaves,
69  mask);
70 
71  // *All* the features have been extracted.
72  const size_t N = cv_line.size();
73 
74  // Now:
75  // 1) Sort them by "response":
76  // sort the LSD features by line length
77  for (size_t i = 0; i < N; i++)
78  {
79  for (size_t j = i + 1; j < N; j++)
80  {
81  if (cv_line.at(j).lineLength > cv_line.at(i).lineLength)
82  {
83  KeyLine temp_line = cv_line.at(i);
84  cv_line.at(i) = cv_line.at(j);
85  cv_line.at(j) = temp_line;
86  }
87  }
88  }
89 
90  // 2) Filter by "min-distance" (in options.FASTOptions.min_distance) //
91  // NOT REQUIRED FOR LSD Features
92  // 3) Convert to MRPT CFeatureList format.
93  // Steps 2 & 3 are done together in the while() below.
94  // The "min-distance" filter is done by means of a 2D binary matrix where
95  // each cell is marked when one
96  // feature falls within it. This is not exactly the same than a pure
97  // "min-distance" but is pretty close
98  // and for large numbers of features is much faster than brute force search
99  // of kd-trees.
100  // (An intermediate approach would be the creation of a mask image updated
101  // for each accepted feature, etc.)
102 
103  unsigned int nMax =
104  (nDesiredFeatures != 0 && N > nDesiredFeatures) ? nDesiredFeatures : N;
105  const int offset = (int)this->options.patchSize / 2 + 1;
106  const size_t size_2 = options.patchSize / 2;
107  const size_t imgH = inImg.getHeight();
108  const size_t imgW = inImg.getWidth();
109  unsigned int i = 0;
110  unsigned int cont = 0;
111  TFeatureID nextID = init_ID;
112 
113  if (!options.addNewFeatures) feats.clear();
114 
115  /* draw lines extracted from octave 0 */
116  if (output.channels() == 1) cvtColor(output, output, COLOR_GRAY2BGR);
117 
118  while (cont != nMax && i != N)
119  {
120  KeyLine kl = cv_line[i];
121  KeyPoint kp;
122 
123  if (kl.octave == 0)
124  {
125  Point pt1 = Point2f(kl.startPointX, kl.startPointY);
126  Point pt2 = Point2f(kl.endPointX, kl.endPointY);
127 
128  kp.pt.x = (pt1.x + pt2.x) / 2;
129  kp.pt.y = (pt1.y + pt2.y) / 2;
130  i++;
131  // Patch out of the image??
132  const int xBorderInf = (int)floor(kp.pt.x - size_2);
133  const int xBorderSup = (int)floor(kp.pt.x + size_2);
134  const int yBorderInf = (int)floor(kp.pt.y - size_2);
135  const int yBorderSup = (int)floor(kp.pt.y + size_2);
136 
137  if (!(xBorderSup < (int)imgW && xBorderInf > 0 &&
138  yBorderSup < (int)imgH && yBorderInf > 0))
139  continue; // nope, skip.
140 
141  // All tests passed: add new feature:
142  CFeature::Ptr ft = std::make_shared<CFeature>();
143  ft->type = featLSD;
144  ft->ID = nextID++;
145  ft->x = kp.pt.x;
146  ft->y = kp.pt.y;
147  ft->x2[0] = pt1.x;
148  ft->x2[1] = pt2.x;
149  ft->y2[0] = pt1.y;
150  ft->y2[1] = pt2.y;
151  ft->response = kl.response;
152  // ft->orientation = kp.angle;
153  ft->scale = kl.octave;
154  // ft->patchSize = options.patchSize; // The size of
155  // the
156  // feature
157  // patch
158 
159  if (options.patchSize > 0)
160  {
161  inImg.extract_patch(
162  ft->patch, round(ft->x) - offset, round(ft->y) - offset,
163  options.patchSize,
164  options.patchSize); // Image patch surronding the feature
165  }
166  feats.push_back(ft);
167  }
168  ++cont;
169  // cout << ft->x << " " << ft->y << endl;
170  }
171 
172 #endif
173  MRPT_END
174 }
175 
176 /************************************************************************************************
177 * internal_computeBLDDescriptors
178 ************************************************************************************************/
179 void CFeatureExtraction::internal_computeBLDLineDescriptors(
180  const mrpt::utils::CImage& in_img, CFeatureList& in_features) const
181 {
182 #if (!HAVE_OPENCV_WITH_LSD)
184  "This function requires OpenCV modules: xfeatures2d, line_descriptor");
185 #else
186  using namespace cv;
187 
188  if (in_features.empty()) return;
189 
190  const CImage img_grayscale(in_img, FAST_REF_OR_CONVERT_TO_GRAY);
191  const Mat img = cvarrToMat(img_grayscale.getAs<IplImage>());
192 
193  vector<KeyPoint> cv_feats; // OpenCV keypoint output vector
194  Mat cv_descs; // OpenCV descriptor output
195 
196  cv::Mat mask = Mat::ones(img.size(), CV_8UC1);
197 
198  BinaryDescriptor::Params params;
199  params.ksize_ = options.BLDOptions.ksize_;
200  params.reductionRatio = options.BLDOptions.reductionRatio;
201  params.numOfOctave_ = options.BLDOptions.numOfOctave;
202  params.widthOfBand_ = options.BLDOptions.widthOfBand;
203 
204  Ptr<BinaryDescriptor> bd2 =
205  BinaryDescriptor::createBinaryDescriptor(params);
206  /* compute lines */
207  std::vector<KeyLine> keylines;
208 
209  bd2->detect(img, keylines, mask);
210 
211  /* compute descriptors */
212  bd2->compute(img, keylines, cv_descs);
213  keylines.resize(in_features.size());
214 
215  // -----------------------------------------------------------------
216  // MRPT Wrapping
217  // -----------------------------------------------------------------
218  CFeatureList::iterator itList;
219  int i;
220  for (i = 0, itList = in_features.begin(); itList != in_features.end();
221  itList++, i++)
222  {
223  CFeature::Ptr ft = *itList;
224 
225  // Get the BLD descriptor
226  ft->descriptors.BLD.resize(cv_descs.cols);
227  for (int m = 0; m < cv_descs.cols; ++m)
228  ft->descriptors.BLD[m] =
229  cv_descs.at<int>(i, m); // Get the SURF descriptor
230  } // end for
231 
232 #endif // end of opencv3 version check
233 } // end internal_computeBLDDescriptors
std::shared_ptr< CFeature > Ptr
Definition: CFeature.h:58
GLenum GLint GLuint mask
Definition: glext.h:4050
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
LSD detector, OpenCV&#39;s implementation.
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:118
size_t size() const
Definition: CFeature.h:387
#define THROW_EXCEPTION(msg)
GLintptr offset
Definition: glext.h:3925
STL namespace.
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: CImage.h:587
A structure for defining a ROI within an image.
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
size_t getWidth() const override
Returns the width of the image in pixels.
Definition: CImage.cpp:869
#define MRPT_END
GLint GLvoid * img
Definition: glext.h:3763
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:897
Classes for computer vision, detectors, features, etc.
uint64_t TFeatureID
Definition of a feature ID.
A list of visual features, to be used as output by detectors, as input/output by trackers, etc.
Definition: CFeature.h:305
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
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:1367
int round(const T value)
Returns the closer integer (int) to x.
Definition: round.h:25
TInternalFeatList::iterator iterator
Definition: CFeature.h:366
EIGEN_STRONG_INLINE void ones(const size_t row, const size_t col)
Resize matrix and set all elements to one.
Definition: eigen_plugins.h:86
GLenum const GLfloat * params
Definition: glext.h:3534
void push_back(const CFeature::Ptr &f)
Definition: CFeature.h:399



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019