Federico Nardi
Federico Nardi

Reputation: 510

OpenCV brief descriptors less than keypoints

I'm using OpenCV to detect features and compute descriptors.

For feature detection I'm using FAST:

cv::Ptr<cv::FeatureDetector> _detector = cv::FastFeatureDetector::create(_configuration.threshold,
                                            _configuration.nonmaxSuppression);

For descriptors I'm using BRIEF:

cv::Ptr<cv::DescriptorExtractor> _descriptor_extractor = cv::xfeatures2d::BriefDescriptorExtractor::create();

After that, I'd like to order keypoints based on their response and store just a certain number of them:

typedef std::map<float,cv::KeyPoint,std::greater<float> > ResponseKeypointMap;

// keypoint buffer
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;

// detect keypoints
_detector->detect(rgb_image_, keypoints);

const int keypoints_size = keypoints.size();
if(!keypoints_size){
    std::cerr << "warning: [PointDetector] found 0 keypoints!\n";
    return;
}

ResponseKeypointMap keypoints_map;
for(int i=0; i < keypoints_size; ++i){
  keypoints_map.insert(std::make_pair(keypoints[i].response,keypoints[i]));
}

int iterations = std::min(_configuration.max_keypoints_size,keypoints_size);
std::vector<cv::KeyPoint> filtered_keypoints;
filtered_keypoints.resize(iterations);
int k=0;

for(ResponseKeypointMap::iterator it = keypoints_map.begin();
    it != keypoints_map.end();
    ++it){
  filtered_keypoints[k] = it->second;
  k++;

  if(k>=iterations)
    break;
}

std::cerr << "filtered keypoints size: " << filtered_keypoints.size() << std::endl;

_descriptor_extractor->compute(rgb_image_, filtered_keypoints, descriptors);
std::cerr << "Computed " << descriptors.rows << "x" << descriptors.cols << " descriptors" << std::endl;

I don't know why I'm giving 100 keypoints to the DescriptorExtractor, but I'm recieving 55 descriptors.

I'd be very grateful if you could explain me what is happening.

Thanks.

Upvotes: 1

Views: 1239

Answers (2)

Haydon Berrow
Haydon Berrow

Reputation: 495

In, particular, FAST draws a diameter-7 ring around each test-point to determine if it is a keypoint, but BRIEF uses 256 points around the test-point. I don't know if BRIEF uses a square area or a circular area but, either way, it is bigger, and so FAST may find keypoints that are too close to the boundary of the image for BRIEF to be able to calculate the description.

Upvotes: 0

Aleksey Petrov
Aleksey Petrov

Reputation: 370

According to OpenCV documentation https://docs.opencv.org/2.4/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html

DescriptorExtractor::compute(const Mat& image, vector& keypoints, Mat& descriptors)
...
keypoints – Input collection of keypoints. Keypoints for which a descriptor cannot be computed are removed and the remaining ones may be reordered. Sometimes new keypoints can be added, for example: SIFT duplicates a keypoint with several dominant orientations (for each orientation).
...

So, after execution of compute method, your filtered_keypoints vector is altered and you have new pair of keypoints and descriptors, both of size 55.

Upvotes: 1

Related Questions