cv :: KeyPointsFilter :: retainBest未按预期工作

时间:2015-03-16 19:42:53

标签: c++ opencv

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;
}

1 个答案:

答案 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);
    }
}