MRPT  2.0.1
CFeatureExtraction_LSD_BLD.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 /*---------------------------------------------------------------
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 
18 #include <mrpt/3rdparty/do_opencv_includes.h>
19 #include <mrpt/io/CMemoryStream.h>
20 #include <mrpt/system/os.h>
21 #include <mrpt/vision/CFeatureExtraction.h> // important import
22 
23 #ifdef HAVE_OPENCV_XFEATURES2D
24 #include <opencv2/xfeatures2d.hpp>
25 #endif
26 #ifdef HAVE_OPENCV_LINE_DESCRIPTOR
27 #include <opencv2/line_descriptor.hpp>
28 using namespace cv::line_descriptor;
29 #endif
30 
31 using namespace mrpt::vision;
32 using namespace mrpt::img;
33 using namespace mrpt::math;
34 using namespace mrpt::img;
35 using namespace mrpt;
36 using namespace std;
37 
38 #if defined(HAVE_OPENCV_XFEATURES2D) && defined(HAVE_OPENCV_LINE_DESCRIPTOR)
39 #define HAVE_OPENCV_WITH_LSD 1
40 #else
41 #define HAVE_OPENCV_WITH_LSD 0
42 #endif
43 
44 void CFeatureExtraction::extractFeaturesLSD(
45  const mrpt::img::CImage& inImg, CFeatureList& feats, unsigned int init_ID,
46  unsigned int nDesiredFeatures, const TImageROI& ROI)
47 {
49 
50  mrpt::system::CTimeLoggerEntry tle(profiler, "extractFeaturesLSD");
51 
52 #if (!HAVE_OPENCV_WITH_LSD)
54  "This function requires OpenCV modules: xfeatures2d, line_descriptor");
55 #else
56  using namespace cv;
57 
58  vector<KeyPoint> cv_feats; // The opencv keypoint output vector
59  vector<KeyLine> cv_line;
60 
61  // Make sure we operate on a gray-scale version of the image:
62  const CImage inImg_gray(inImg, FAST_REF_OR_CONVERT_TO_GRAY);
63  const Mat& theImg = inImg_gray.asCvMatRef();
64  /* create a binary mask */
65  cv::Mat mask = Mat::ones(theImg.size(), CV_8UC1);
66 
67  Ptr<LSDDetector> bd = LSDDetector::createLSDDetector();
68 
69  /* extract lines */
70  cv::Mat output = theImg.clone();
71  bd->detect(
72  theImg, cv_line, options.LSDOptions.scale, options.LSDOptions.nOctaves,
73  mask);
74 
75  // *All* the features have been extracted.
76  const size_t N = cv_line.size();
77 
78  // Now:
79  // 1) Sort them by "response":
80  // sort the LSD features by line length
81  for (size_t i = 0; i < N; i++)
82  {
83  for (size_t j = i + 1; j < N; j++)
84  {
85  if (cv_line.at(j).lineLength > cv_line.at(i).lineLength)
86  {
87  KeyLine temp_line = cv_line.at(i);
88  cv_line.at(i) = cv_line.at(j);
89  cv_line.at(j) = temp_line;
90  }
91  }
92  }
93 
94  // 2) Filter by "min-distance" (in options.FASTOptions.min_distance) //
95  // NOT REQUIRED FOR LSD Features
96  // 3) Convert to MRPT CFeatureList format.
97  // Steps 2 & 3 are done together in the while() below.
98  // The "min-distance" filter is done by means of a 2D binary matrix where
99  // each cell is marked when one
100  // feature falls within it. This is not exactly the same than a pure
101  // "min-distance" but is pretty close
102  // and for large numbers of features is much faster than brute force search
103  // of kd-trees.
104  // (An intermediate approach would be the creation of a mask image updated
105  // for each accepted feature, etc.)
106 
107  unsigned int nMax =
108  (nDesiredFeatures != 0 && N > nDesiredFeatures) ? nDesiredFeatures : N;
109  const int offset = (int)this->options.patchSize / 2 + 1;
110  const size_t size_2 = options.patchSize / 2;
111  const size_t imgH = inImg.getHeight();
112  const size_t imgW = inImg.getWidth();
113  unsigned int i = 0;
114  unsigned int cont = 0;
115  TFeatureID nextID = init_ID;
116 
117  if (!options.addNewFeatures) feats.clear();
118 
119  /* draw lines extracted from octave 0 */
120  if (output.channels() == 1) cvtColor(output, output, COLOR_GRAY2BGR);
121 
122  while (cont != nMax && i != N)
123  {
124  KeyLine kl = cv_line[i];
125  KeyPoint kp;
126 
127  if (kl.octave == 0)
128  {
129  Point pt1 = Point2f(kl.startPointX, kl.startPointY);
130  Point pt2 = Point2f(kl.endPointX, kl.endPointY);
131 
132  kp.pt.x = (pt1.x + pt2.x) / 2;
133  kp.pt.y = (pt1.y + pt2.y) / 2;
134  i++;
135  // Patch out of the image??
136  const int xBorderInf = (int)floor(kp.pt.x - size_2);
137  const int xBorderSup = (int)floor(kp.pt.x + size_2);
138  const int yBorderInf = (int)floor(kp.pt.y - size_2);
139  const int yBorderSup = (int)floor(kp.pt.y + size_2);
140 
141  if (!(xBorderSup < (int)imgW && xBorderInf > 0 &&
142  yBorderSup < (int)imgH && yBorderInf > 0))
143  continue; // nope, skip.
144 
145  // All tests passed: add new feature:
146  CFeature ft;
147  ft.type = featLSD;
148  ft.keypoint.ID = nextID++;
149  ft.keypoint.pt.x = kp.pt.x;
150  ft.keypoint.pt.y = kp.pt.y;
151  ft.x2[0] = pt1.x;
152  ft.x2[1] = pt2.x;
153  ft.y2[0] = pt1.y;
154  ft.y2[1] = pt2.y;
155  ft.keypoint.response = kl.response;
156  ft.keypoint.octave = kl.octave;
157 
158  if (options.patchSize > 0)
159  {
161  inImg.extract_patch(
162  p, round(kp.pt.x) - offset, round(kp.pt.y) - offset,
163  options.patchSize,
164  options.patchSize); // Image patch surronding the feature
165  ft.patch = std::move(p);
166  }
167  feats.emplace_back(std::move(ft));
168  }
169  ++cont;
170  // cout << ft->x << " " << ft->y << endl;
171  }
172 
173 #endif
174  MRPT_END
175 }
176 
177 void CFeatureExtraction::internal_computeBLDLineDescriptors(
178  const mrpt::img::CImage& in_img, CFeatureList& in_features)
179 {
180 #if (!HAVE_OPENCV_WITH_LSD)
182  "This function requires OpenCV modules: xfeatures2d, line_descriptor");
183 #else
184 
186  profiler, "internal_computeBLDLineDescriptors");
187 
188  using namespace cv;
189 
190  if (in_features.empty()) return;
191 
192  const CImage img_grayscale(in_img, FAST_REF_OR_CONVERT_TO_GRAY);
193  const Mat& img = img_grayscale.asCvMatRef();
194 
195  vector<KeyPoint> cv_feats; // OpenCV keypoint output vector
196  Mat cv_descs; // OpenCV descriptor output
197 
198  cv::Mat mask = Mat::ones(img.size(), CV_8UC1);
199 
200  BinaryDescriptor::Params params;
201  params.ksize_ = options.BLDOptions.ksize_;
202  params.reductionRatio = options.BLDOptions.reductionRatio;
203  params.numOfOctave_ = options.BLDOptions.numOfOctave;
204  params.widthOfBand_ = options.BLDOptions.widthOfBand;
205 
206  Ptr<BinaryDescriptor> bd2 =
207  BinaryDescriptor::createBinaryDescriptor(params);
208  /* compute lines */
209  std::vector<KeyLine> keylines;
210 
211  bd2->detect(img, keylines, mask);
212 
213  /* compute descriptors */
214  bd2->compute(img, keylines, cv_descs);
215  keylines.resize(in_features.size());
216 
217  // -----------------------------------------------------------------
218  // MRPT Wrapping
219  // -----------------------------------------------------------------
220  int i = 0;
221  for (auto& ft : in_features)
222  {
223  // Get the BLD descriptor
224  ft.descriptors.BLD.emplace();
225  auto& desc = ft.descriptors.BLD.value();
226  desc.resize(cv_descs.cols);
227  for (int m = 0; m < cv_descs.cols; ++m)
228  desc[m] = cv_descs.at<int>(i, m);
229  }
230 
231 #endif // end of opencv3 version check
232 } // end internal_computeBLDDescriptors
#define MRPT_START
Definition: exceptions.h:241
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...
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
mrpt::vision::TStereoCalibParams params
STL namespace.
TFeatureID ID
ID of the feature.
Definition: TKeyPoint.h:39
LSD detector, OpenCV&#39;s implementation.
Definition: img/CImage.h:23
A structure for defining a ROI within an image.
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
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
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define MRPT_END
Definition: exceptions.h:245
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
float y2[2]
Coordinates for a LSD Detector to represent a line.
Definition: CFeature.h:89
float response
A measure of the "goodness" of the feature (typically, the KLT_response value)
Definition: TKeyPoint.h:46
void emplace_back(CFeature &&f)
Definition: CFeature.h:364
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
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.1 Git: 0fef1a6d7 Fri Apr 3 23:00:21 2020 +0200 at vie abr 3 23:20:28 CEST 2020