15 #include <mrpt/3rdparty/do_opencv_includes.h>    26     const unsigned int init_ID, 
const unsigned int nDesiredFeatures,
    36     vector<KeyPoint> cv_feats;  
    39     const bool use_precomputed_feats = feats.
size() > 0;
    41     if (use_precomputed_feats)
    43         cv_feats.resize(feats.
size());
    44         for (
size_t k = 0; k < cv_feats.size(); ++k)
    46             cv_feats[k].pt.x = feats[k].keypoint.pt.x;
    47             cv_feats[k].pt.y = feats[k].keypoint.pt.y;
    56     profiler.enter(
"extractFeaturesORB.openCV_detectAndCompute");
    58 #if MRPT_OPENCV_VERSION_NUM < 0x300    59     Ptr<Feature2D> orb = Algorithm::create<Feature2D>(
"Feature2D.ORB");
    60     orb->operator()(cvImg, Mat(), cv_feats, cv_descs, use_precomputed_feats);
    62     const size_t n_feats_2_extract =
    63         nDesiredFeatures == 0 ? 1000 : 3 * nDesiredFeatures;
    64     Ptr<cv::ORB> orb = cv::ORB::create(
    65         n_feats_2_extract, options.ORBOptions.scale_factor,
    66         options.ORBOptions.n_levels);
    67     orb->detectAndCompute(
    68         cvImg, Mat(), cv_feats, cv_descs, use_precomputed_feats);
    70     profiler.leave(
"extractFeaturesORB.openCV_detectAndCompute");
    74     const size_t n_feats = cv_feats.size();
    77     const unsigned int patch_size_2 = options.patchSize / 2;
    78     unsigned int f_id = init_ID;
    79     if (use_precomputed_feats)
    81         for (
size_t k = 0; k < n_feats; ++k)
    83             feats[k].descriptors.ORB->
resize(cv_descs.cols);
    84             for (
int m = 0; m < cv_descs.cols; ++m)
    85                 (*feats[k].descriptors.ORB)[m] = cv_descs.at<uchar>(k, m);
    95             if (options.ORBOptions.extract_patch && options.patchSize > 0)
    99                     round(feats[k].keypoint.pt.x) - patch_size_2,
   100                     round(feats[k].keypoint.pt.y) - patch_size_2,
   101                     options.patchSize, options.patchSize);
   111     std::vector<size_t> sorted_indices(n_feats);
   112     for (
size_t i = 0; i < n_feats; i++) sorted_indices[i] = i;
   114         sorted_indices.begin(), sorted_indices.end(),
   129     const bool do_filter_min_dist = options.ORBOptions.min_distance > 1;
   130     const unsigned int occupied_grid_cell_size =
   131         options.ORBOptions.min_distance / 2;
   132     const float occupied_grid_cell_size_inv = 1.0f / occupied_grid_cell_size;
   134     unsigned int grid_lx =
   137             : (
unsigned int)(1 + inImg.
getWidth() * occupied_grid_cell_size_inv);
   138     unsigned int grid_ly =
   141             : (
unsigned int)(1 + inImg.
getHeight() * occupied_grid_cell_size_inv);
   145     occupied_sections.
fill(
false);
   147     const size_t n_max_feats = nDesiredFeatures > 0
   148                                    ? std::min(
size_t(nDesiredFeatures), n_feats)
   151     if (!options.addNewFeatures) feats.
clear();
   155     const size_t imgW = inImg.
getWidth();
   158     while (c_feats < n_max_feats && k < n_feats)
   160         const size_t idx = sorted_indices[k++];
   161         const KeyPoint& kp = cv_feats[idx];
   162         if (options.ORBOptions.extract_patch && options.patchSize > 0)
   165             const int xBorderInf = (int)floor(kp.pt.x - patch_size_2);
   166             const int xBorderSup = (int)floor(kp.pt.x + patch_size_2);
   167             const int yBorderInf = (int)floor(kp.pt.y - patch_size_2);
   168             const int yBorderSup = (int)floor(kp.pt.y + patch_size_2);
   170             if (!(xBorderSup < (
int)imgW && xBorderInf > 0 &&
   171                   yBorderSup < (int)imgH && yBorderInf > 0))
   175         if (do_filter_min_dist)
   178             const auto sect_ix = size_t(kp.pt.x * occupied_grid_cell_size_inv);
   179             const auto sect_iy = size_t(kp.pt.y * occupied_grid_cell_size_inv);
   181             if (occupied_sections(sect_ix, sect_iy))
   185             occupied_sections(sect_ix, sect_iy) = 
true;
   186             if (sect_ix > 0) occupied_sections(sect_ix - 1, sect_iy) = 
true;
   187             if (sect_iy > 0) occupied_sections(sect_ix, sect_iy - 1) = 
true;
   188             if (sect_ix < grid_lx - 1)
   189                 occupied_sections(sect_ix + 1, sect_iy) = 
true;
   190             if (sect_iy < grid_ly - 1)
   191                 occupied_sections(sect_ix, sect_iy + 1) = 
true;
   208         for (
int m = 0; m < cv_descs.cols; ++m)
   211         if (options.ORBOptions.extract_patch && options.patchSize > 0)
   218                 round(kp.pt.y) - patch_size_2, options.patchSize,
   235         profiler, 
"internal_computeORBDescriptors");
   237     const size_t n_feats = in_features.
size();
   241     vector<KeyPoint> cv_feats(n_feats);
   242     for (
size_t k = 0; k < n_feats; ++k)
   244         KeyPoint& kp = cv_feats[k];
   245         kp.pt.x = in_features[k].keypoint.pt.x;
   246         kp.pt.y = in_features[k].keypoint.pt.y;
   247         kp.angle = in_features[k].orientation;
   248         kp.
size = in_features[k].keypoint.octave;
   254 #if MRPT_OPENCV_VERSION_NUM < 0x300   255     Ptr<Feature2D> orb = Algorithm::create<Feature2D>(
"Feature2D.ORB");
   257         cvImg, cv::noArray(), cv_feats, cv_descs,
   260     Ptr<cv::ORB> orb = cv::ORB::create(
   261         n_feats, options.ORBOptions.scale_factor, options.ORBOptions.n_levels);
   262     orb->detectAndCompute(
   263         cvImg, cv::noArray(), cv_feats, cv_descs,
   268     for (
size_t k = 0; k < n_feats; ++k)
   270         in_features[k].descriptors.ORB.emplace();
   271         auto& orb_desc = *in_features[k].descriptors.ORB;
   272         orb_desc.
resize(cv_descs.cols);
   273         for (
int i = 0; i < cv_descs.cols; ++i)
   274             orb_desc[i] = cv_descs.at<uchar>(k, i);
 
std::optional< std::vector< uint8_t > > ORB
ORB feature descriptor. 
 
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. 
 
void fill(const Scalar &val)
 
cv::Mat & asCvMatRef()
Get a reference to the internal cv::Mat, which can be resized, etc. 
 
size_t getHeight() const override
Returns the height of the image in pixels. 
 
TFeatureID ID
ID of the feature. 
 
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. 
 
size_t getWidth() const override
Returns the width of the image in pixels. 
 
std::optional< mrpt::img::CImage > patch
A patch of the image surrounding the feature. 
 
Classes for computer vision, detectors, features, etc. 
 
A generic 2D feature from an image, extracted with CFeatureExtraction Each feature may have one or mo...
 
A list of visual features, to be used as output by detectors, as input/output by trackers, etc. 
 
float response
A measure of the "goodness" of the feature. 
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
uint8_t octave
The image octave the image was found in: 0=original image, 1=1/2 image, 2=1/4 image, etc. 
 
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)...
 
float orientation
Main orientation of the feature. 
 
This template class provides the basic functionality for a general 2D any-size, resizable container o...
 
uint16_t patchSize
Size of the patch (patchSize x patchSize) (it must be an odd number) 
 
void emplace_back(CFeature &&f)
 
ORB detector and descriptor, OpenCV's implementation. 
 
pixel_coords_t pt
Coordinates in the image. 
 
A class for storing images as grayscale or RGB bitmaps. 
 
int round(const T value)
Returns the closer integer (int) to x.