15 #include <mrpt/otherlibs/do_opencv_includes.h> 31 unsigned int nDesiredFeatures,
const TImageROI& ROI,
38 #if MRPT_OPENCV_VERSION_NUM < 0x210 44 vector<KeyPoint> cv_feats;
54 #if MRPT_OPENCV_VERSION_NUM >= 0x211 60 const Mat theImg = cvarrToMat(inImg_gray.
getAs<IplImage>());
65 cout <<
"using mask" << endl;
66 size_t maskW =
mask->cols(), maskH =
mask->rows();
72 for (
int ii = 0; ii < int(maskW); ++ii)
73 for (
int jj = 0; jj < int(maskH); ++jj)
75 if (!
mask->get_unsafe(jj, ii))
77 cvMask.at<
char>(ii, jj) = (
char)0;
82 #if MRPT_OPENCV_VERSION_NUM < 0x300 83 FastFeatureDetector fastDetector(
84 options.FASTOptions.threshold, options.FASTOptions.nonmax_suppression);
85 fastDetector.detect(theImg, cv_feats);
87 Ptr<cv::FastFeatureDetector> fastDetector = cv::FastFeatureDetector::create(
88 options.FASTOptions.threshold, options.FASTOptions.nonmax_suppression);
89 fastDetector->detect(theImg, cv_feats);
92 #elif MRPT_OPENCV_VERSION_NUM >= 0x210 94 inImg_gray.
getAs<IplImage>(), cv_feats, options.FASTOptions.threshold,
95 options.FASTOptions.nonmax_suppression);
99 const size_t N = cv_feats.size();
102 if (options.FASTOptions.use_KLT_response)
104 const unsigned int KLT_half_win = 4;
105 const unsigned int max_x = inImg_gray.
getWidth() - 1 - KLT_half_win;
106 const unsigned int max_y = inImg_gray.
getHeight() - 1 - KLT_half_win;
107 for (
size_t i = 0; i < N; i++)
109 const unsigned int x = cv_feats[i].pt.x;
110 const unsigned int y = cv_feats[i].pt.y;
111 if (
x > KLT_half_win &&
y > KLT_half_win &&
x <= max_x &&
113 cv_feats[i].response =
116 cv_feats[i].response = -100;
124 std::vector<size_t> sorted_indices(N);
125 for (
size_t i = 0; i < N; i++) sorted_indices[i] = i;
127 sorted_indices.begin(), sorted_indices.end(),
142 const bool do_filter_min_dist = options.FASTOptions.min_distance > 1;
146 const unsigned int occupied_grid_cell_size =
147 options.FASTOptions.min_distance / 2.0;
148 const float occupied_grid_cell_size_inv = 1.0f / occupied_grid_cell_size;
150 unsigned int grid_lx =
153 : (
unsigned int)(1 + inImg.
getWidth() * occupied_grid_cell_size_inv);
154 unsigned int grid_ly =
157 : (
unsigned int)(1 + inImg.
getHeight() * occupied_grid_cell_size_inv);
161 occupied_sections.
fillAll(
false);
164 (nDesiredFeatures != 0 && N > nDesiredFeatures) ? nDesiredFeatures : N;
165 const int offset = (int)this->options.patchSize / 2 + 1;
166 const size_t size_2 = options.patchSize / 2;
168 const size_t imgW = inImg.
getWidth();
170 unsigned int cont = 0;
173 if (!options.addNewFeatures) feats.
clear();
175 while (cont != nMax && i != N)
178 const KeyPoint& kp = cv_feats[sorted_indices[i]];
182 const int xBorderInf = (int)floor(kp.pt.x - size_2);
183 const int xBorderSup = (int)floor(kp.pt.x + size_2);
184 const int yBorderInf = (int)floor(kp.pt.y - size_2);
185 const int yBorderSup = (int)floor(kp.pt.y + size_2);
187 if (!(xBorderSup < (
int)imgW && xBorderInf > 0 &&
188 yBorderSup < (int)imgH && yBorderInf > 0))
191 if (do_filter_min_dist)
194 const size_t section_idx_x =
195 size_t(kp.pt.x * occupied_grid_cell_size_inv);
196 const size_t section_idx_y =
197 size_t(kp.pt.y * occupied_grid_cell_size_inv);
199 if (occupied_sections(section_idx_x, section_idx_y))
203 occupied_sections.
set_unsafe(section_idx_x, section_idx_y,
true);
204 if (section_idx_x > 0)
206 section_idx_x - 1, section_idx_y,
true);
207 if (section_idx_y > 0)
209 section_idx_x, section_idx_y - 1,
true);
210 if (section_idx_x < grid_lx - 1)
212 section_idx_x + 1, section_idx_y,
true);
213 if (section_idx_y < grid_ly - 1)
215 section_idx_x, section_idx_y + 1,
true);
224 ft->response = kp.response;
225 ft->orientation = kp.angle;
226 ft->scale = kp.octave;
227 ft->patchSize = options.patchSize;
229 if (options.patchSize > 0)
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's headers.
uint64_t TFeatureID
Definition of a feature ID.
Declares a matrix of booleans (non serializable).
#define THROW_EXCEPTION(msg)
size_t getHeight() const override
Returns the height of the image in pixels.
FAST feature detector, OpenCV's implementation ("Faster and better: A machine learning approach to...
A helper struct to sort keypoints by their response: It can be used with these types: ...
A structure for defining a ROI within an image.
#define ASSERT_(f)
Defines an assertion mechanism.
This base provides a set of functions for maths stuff.
size_t getWidth() const override
Returns the width of the image in pixels.
Classes for computer vision, detectors, features, etc.
void set_unsafe(size_t row, size_t col, const T &v)
Fast but unsafe method to write a value in the matrix.
A list of visual features, to be used as output by detectors, as input/output by trackers, etc.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
float KLT_response(const unsigned int x, const unsigned int y, const unsigned int half_window_size) const
Compute the KLT response at a given pixel (x,y) - Only for grayscale images (for efficiency it avoids...
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)...
EIGEN_STRONG_INLINE void ones(const size_t row, const size_t col)
Resize matrix and set all elements to one.
void push_back(const CFeature::Ptr &f)
A class for storing images as grayscale or RGB bitmaps.
void fillAll(const T &val)
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
int round(const T value)
Returns the closer integer (int) to x.