15 #include <mrpt/otherlibs/do_opencv_includes.h> 26 void CFeatureExtraction::extractFeaturesORB(
29 const unsigned int init_ID,
30 const unsigned int nDesiredFeatures,
37 # if MRPT_OPENCV_VERSION_NUM < 0x240 43 vector<KeyPoint> cv_feats;
46 const bool use_precomputed_feats = feats.
size() > 0;
48 if( use_precomputed_feats )
50 cv_feats.resize( feats.
size() );
51 for(
size_t k = 0; k < cv_feats.size(); ++k )
53 cv_feats[k].pt.x = feats[k]->x;
54 cv_feats[k].pt.y = feats[k]->y;
60 const Mat cvImg = cv::cvarrToMat( inImg_gray.
getAs<IplImage>() );
63 # if MRPT_OPENCV_VERSION_NUM < 0x300 64 Ptr<Feature2D> orb = Algorithm::create<Feature2D>(
"Feature2D.ORB");
65 orb->operator()( cvImg, Mat(), cv_feats, cv_descs, use_precomputed_feats );
67 const size_t n_feats_2_extract = nDesiredFeatures == 0 ? 1000 : 3*nDesiredFeatures;
68 Ptr<cv::ORB> orb = cv::ORB::create( n_feats_2_extract, options.ORBOptions.scale_factor, options.ORBOptions.n_levels );
69 orb->detectAndCompute(cvImg, Mat(), cv_feats, cv_descs, use_precomputed_feats );
72 const size_t n_feats = cv_feats.size();
75 const unsigned int patch_size_2 = options.patchSize/2;
76 unsigned int f_id = init_ID;
77 if( use_precomputed_feats )
79 for(
size_t k = 0; k < n_feats; ++k )
81 feats[k]->descriptors.ORB.
resize( cv_descs.cols );
82 for(
int m = 0; m < cv_descs.cols; ++m )
83 feats[k]->descriptors.ORB[m] = cv_descs.at<uchar>(k,m);
93 if( options.ORBOptions.extract_patch && options.patchSize > 0 )
97 round( feats[k]->
x ) - patch_size_2,
98 round( feats[k]->
y ) - patch_size_2,
108 std::vector<size_t> sorted_indices(n_feats);
109 for (
size_t i=0;i<n_feats;i++) sorted_indices[i]=i;
120 const bool do_filter_min_dist = options.ORBOptions.min_distance > 1;
121 const unsigned int occupied_grid_cell_size = options.ORBOptions.min_distance/2.0;
122 const float occupied_grid_cell_size_inv = 1.0f/occupied_grid_cell_size;
124 unsigned int grid_lx = !do_filter_min_dist ? 1 : (
unsigned int)(1 + inImg.
getWidth() * occupied_grid_cell_size_inv);
125 unsigned int grid_ly = !do_filter_min_dist ? 1 : (
unsigned int)(1 + inImg.
getHeight() * occupied_grid_cell_size_inv );
128 occupied_sections.
fillAll(
false);
130 const size_t n_max_feats = nDesiredFeatures > 0 ?
std::min(
size_t(nDesiredFeatures),n_feats) : n_feats;
132 if( !options.addNewFeatures )
137 const size_t imgW = inImg.
getWidth();
140 while( c_feats < n_max_feats && k < n_feats )
142 const size_t idx = sorted_indices[k++];
143 const KeyPoint & kp = cv_feats[ idx ];
144 if( options.ORBOptions.extract_patch && options.patchSize > 0 )
147 const int xBorderInf = (int)floor( kp.pt.x - patch_size_2 );
148 const int xBorderSup = (int)floor( kp.pt.x + patch_size_2 );
149 const int yBorderInf = (int)floor( kp.pt.y - patch_size_2 );
150 const int yBorderSup = (int)floor( kp.pt.y + patch_size_2 );
152 if (!( xBorderSup < (
int)imgW && xBorderInf > 0 && yBorderSup < (int)imgH && yBorderInf > 0 ))
156 if (do_filter_min_dist)
159 const size_t section_idx_x = size_t(kp.pt.x * occupied_grid_cell_size_inv);
160 const size_t section_idx_y = size_t(kp.pt.y * occupied_grid_cell_size_inv);
162 if (occupied_sections(section_idx_x,section_idx_y))
166 occupied_sections.
set_unsafe(section_idx_x,section_idx_y,
true);
167 if (section_idx_x>0) occupied_sections.
set_unsafe(section_idx_x-1,section_idx_y,
true);
168 if (section_idx_y>0) occupied_sections.
set_unsafe(section_idx_x,section_idx_y-1,
true);
169 if (section_idx_x<grid_lx-1) occupied_sections.
set_unsafe(section_idx_x+1,section_idx_y,
true);
170 if (section_idx_y<grid_ly-1) occupied_sections.
set_unsafe(section_idx_x,section_idx_y+1,
true);
174 CFeaturePtr ft = CFeature::Create();
179 ft->response = kp.response;
180 ft->orientation = kp.angle;
181 ft->scale = kp.octave;
185 ft->descriptors.ORB.resize( cv_descs.cols );
186 for(
int m = 0; m < cv_descs.cols; ++m )
187 ft->descriptors.ORB[m] = cv_descs.at<uchar>(idx,m);
189 if( options.ORBOptions.extract_patch && options.patchSize > 0 )
191 ft->patchSize = options.patchSize;
195 round( ft->x ) - patch_size_2,
196 round( ft->y ) - patch_size_2,
209 void CFeatureExtraction::internal_computeORBDescriptors(
214 # if MRPT_OPENCV_VERSION_NUM < 0x240 219 const size_t n_feats = in_features.
size();
223 vector<KeyPoint> cv_feats( n_feats );
224 for(
size_t k = 0; k < n_feats; ++k )
226 KeyPoint & kp = cv_feats[k];
227 kp.pt.x = in_features[k]->x;
228 kp.pt.y = in_features[k]->y;
229 kp.angle = in_features[k]->orientation;
230 kp.
size = in_features[k]->scale;
233 Mat cvImg(cv::cvarrToMat(inImg_gray.
getAs<IplImage>()));
236 # if MRPT_OPENCV_VERSION_NUM < 0x300 237 Ptr<Feature2D> orb = Algorithm::create<Feature2D>(
"Feature2D.ORB");
238 orb->operator()( cvImg, Mat(), cv_feats, cv_descs,
true );
240 Ptr<cv::ORB> orb = cv::ORB::create( n_feats, options.ORBOptions.scale_factor, options.ORBOptions.n_levels );
241 orb->detectAndCompute(cvImg, Mat(), cv_feats, cv_descs,
true );
245 for(
size_t k = 0; k < n_feats; ++k )
247 in_features[k]->descriptors.ORB.
resize( cv_descs.cols );
248 for(
int i = 0; i < cv_descs.cols; ++i )
249 in_features[k]->descriptors.ORB[i] = cv_descs.at<uchar>(k,i);
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Declares a matrix of booleans (non serializable).
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
A class for storing images as grayscale or RGB bitmaps.
#define THROW_EXCEPTION(msg)
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.
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 MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
Classes for computer vision, detectors, features, etc.
void push_back(const CFeaturePtr &f)
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.
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)...
int round(const T value)
Returns the closer integer (int) to x.
ORB detector and descriptor, OpenCV's implementation ("ORB: an efficient alternative to SIFT or SURF"...
size_t getWidth() const MRPT_OVERRIDE
Returns the width of the image in pixels.
size_t getHeight() const MRPT_OVERRIDE
Returns the height of the image in pixels.
void fillAll(const T &val)