0
votes

I am trying to use SIFT descriptors that are directly used for image classification. The SIFT is defined by: Ptr<SIFT> sift = SIFT::create(100). Then I expect there would be 100 keypoints to be extracted. But the number of actually detected keypoints (sift->detect(img_resiz,keypoints)) is not always 100 (sometimes exceeding the preset value). How could that happen?

I want to have the fixed number of keypoints per image so as to produce the consistent length of descriptors (after being reshaped into a row vector) among different images (alternatively I may need more processing based on the bag-of-word to represent the sift descriptors into the same dimension).

1

1 Answers

1
votes

There was an error in the function KeyPointsFilter::retainBest(std::vector<KeyPoint>& keypoints, int n_points) as you can see here: https://github.com/opencv/opencv/commit/3f3c8823ac22e34a37d74bc824e00a807535b91b.
I could reproduce the error with an older version of OpenCV (3.4.5) and sometimes you had 1 more KeyPoint than expected e.g. 101 instead of 100 because of that marked line.

If you don't want to switch to a newer OpenCV version you could do something like:

// Detect SIFT keypoints
std::vector<cv::KeyPoint> keypoints_sift, keypoints_sift_100;
cv::Ptr<cv::xfeatures2d::SiftFeatureDetector> sift = cv::xfeatures2d::SiftFeatureDetector::create(100);
sift->detect(img, keypoints_sift);

std::cout << keypoints_sift.size() << std::endl;
for (size_t i = 0; i < 100; ++i) {
    keypoints_sift_100.push_back(keypoints_sift[i]);
}

So you would keep the 100 best keypoints after detection since they are ranked by their scores https://docs.opencv.org/4.1.0/d5/d3c/classcv_1_1xfeatures2d_1_1SIFT.html.