cv::KeyPointsFilter::retainBest
似乎没有像我想象的那样表现,我有兴趣在不同尺寸的图像上获得固定数量的点(用于分类),我使用的是OpenCV 2.4.10。
在我得到的几张图片上执行以下代码:110和122用于keypoints.size()
编辑:更多信息实际输出:
# keypoints: 478
new # keypoints: 122
filter not working properly?
和
# keypoints: 4575
new # keypoints: 110
filter not working properly?
一如既往,提前谢谢。
代码:
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
//#include <opencv2/nonfree/nonfree.hpp>
#define MAX_KEYPOINTS 100
int main(int argc, char *argv[])
{
//cv::initModule_nonfree();
cv::Mat image = cv::imread(argv[1]);
if (!image.empty())
{
cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create("FAST");
std::vector<cv::KeyPoint> keypoints;
detector->detect(image, keypoints);
std::cout << "# keypoints: " << keypoints.size() << std::endl;
cv::KeyPointsFilter::retainBest(keypoints, MAX_KEYPOINTS);
std::cout << "new # keypoints: " << keypoints.size() << std::endl;
if (keypoints.size() != MAX_KEYPOINTS)
{
std::cerr << "filter not working properly?" << std::endl;
return EXIT_FAILURE;
}
}
else
{
std::cerr << "failed to load image " << argv[1] << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
答案 0 :(得分:0)
这绝对不是一个错误。保留最佳将为您提供阵列中最好的第n个元素。所以你必须至少有n个元素。但它也会查找大于某个阈值的元素,因为Fast可能会给出模糊的结果。因此,您最终可以获得超过n个关键点。这是OpenCV代码:
struct KeypointResponseGreaterThanThreshold {
KeypointResponseGreaterThanThreshold(float _value) : value(_value) { }
inline bool operator()(const KeyPoint& kpt) const {
return kpt.response >= value;
}
float value;
};
void retainBest(std::vector<cv::KeyPoint>& keypoints, int n) {
std::nth_element(keypoints.begin(), keypoints.begin() + n, keypoints.end(),
[](cv::KeyPoint& a, cv::KeyPoint& b) { return a.response > b.response; });
float ambiguous_response = keypoints[n- 1].response;
std::vector<KeyPoint>::const_iterator new_end =
std::partition(keypoints.begin() + n, keypoints.end(),
KeypointResponseGreaterThanThreshold(ambiguous_response));
keypoints.resize(new_end - keypoints.begin());
}
但是如果你想要n个关键点,那么就自己动手吧,它更容易,更快。当然,您至少需要n个关键点:)
void retainBest(std::vector<cv::KeyPoint>& keypoints, int n) {
if (keypoints.size() > n) {
if (n == 0) {
keypoints.clear();
return;
}
std::nth_element(keypoints.begin(), keypoints.begin() + n, keypoints.end(),
[](cv::KeyPoint& a, cv::KeyPoint& b) { return a.response > b.response; });
keypoints.resize(n);
}
}