ORB未在opencv 2.4.9中检测keyPoints

时间:2014-05-03 18:36:59

标签: c++ opencv feature-detection orb

我试图用ORB检测关键点一切正常,直到我切换到Opencv 2.4.9。

Firts,似乎键的数量减少了,对于某些图像,没有检测到关键点:

这是我用两个版本编译的代码:(2.3.1和2.4.9)

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/features2d/features2d.hpp>


using namespace cv;


int main(int argc, char **argv){

  Mat img = imread(argv[1]);

  std::vector<KeyPoint> kp;

  OrbFeatureDetector detector;
  detector.detect(img, kp);
  std::cout << "Found " << kp.size() << " Keypoints " << std::endl;

  Mat out;
  drawKeypoints(img, kp, out, Scalar::all(255));

  imshow("Kpts", out);

  waitKey(0);
  return 0;
}

结果: 2.3.1: 找到152个关键点

kp detected

2.4.9: 找到0个关键点

zero kpts

我还使用不同的ORB构造函数进行了测试,但是得到了相同的结果,没有KPts。 与2.3.1默认构造函数中相同的构造函数值: 2.4.9 custom constr:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/features2d/features2d.hpp>


using namespace cv;


int main(int argc, char **argv){

  Mat img = imread(argv[1]);

  std::vector<KeyPoint> kp;

  // default in 2.4.9 is : ORB(700, 1.2f, 3, 31, 0);
  OrbFeatureDetector detector(500, 1.2f, 8, 31, 0); // default values of 2.3.1
  detector.detect(img, kp);
  std::cout << "Found " << kp.size() << " Keypoints " << std::endl;
  Mat out;
  drawKeypoints(img, kp, out, Scalar::all(255));

  imshow("Kpts", out);

  waitKey(0);
  return 0;
}

你知道发生了什么吗?我该如何解决?

谢谢。

2 个答案:

答案 0 :(得分:9)

OpenCV中ORB的实现在版本2.3.1和2.4.9之间发生了很大变化。很难确定一个可以解释你观察到的行为的变化。

但是,通过更改边缘阈值,可以再次增加检测到的要素数。

下面是你的代码的改编版本,以显示我的意思(小心,我只能用OpenCV 3.0.0测试它,但我想你明白了。)

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>

using namespace cv;

int main(int argc, char **argv){

    Mat img = imread(argv[1]);

    std::vector<KeyPoint> kp;

    // Default parameters of ORB
    int nfeatures=500;
    float scaleFactor=1.2f;
    int nlevels=8;
    int edgeThreshold=15; // Changed default (31);
    int firstLevel=0;
    int WTA_K=2;
    int scoreType=ORB::HARRIS_SCORE;
    int patchSize=31;
    int fastThreshold=20;

    Ptr<ORB> detector = ORB::create(
    nfeatures,
    scaleFactor,
    nlevels,
    edgeThreshold,
    firstLevel,
    WTA_K,
    scoreType,
    patchSize,
    fastThreshold );

    detector->detect(img, kp);
    std::cout << "Found " << kp.size() << " Keypoints " << std::endl;

    Mat out;
    drawKeypoints(img, kp, out, Scalar::all(255));

    imshow("Kpts", out);

    waitKey(0);
    return 0;
}

答案 1 :(得分:2)

至少在OpenCV 3.1中,edgeThreshold参数实际上是未检测到要素的边框的大小。&#34;检测其他功能的一种方法是减少fastThreshold参数。它具有误导性的名称,因为即使使用ORB::HARRIS_SCORE,这个阈值也会影响检测到的角点数,即Harris关键点,而不仅仅是基于参数名称的FAST关键点。它也有点误导,因为edgeThreshold本身听起来像哈里斯角点检测的阈值,而不是用于检测点的图像。

见:http://docs.opencv.org/trunk/db/d95/classcv_1_1ORB.html#gsc.tab=0

另外,增加金字塔等级nlevels的数量可以为您提供更多关键点,但如果您的图像大小相同且唯一的区别是您的OpenCV版本,则不太可能在这里帮忙。

我遇到了同样的问题,这里的代码有效:
std::vector<KeyPoint> kpts1; Mat desc1; Ptr<ORB> orb = ORB::create(100, 2, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, 20); orb->detectAndCompute(input_image, Mat(), kpts1, desc1);

最后一个论点(上面20)是fastThreshold减少以获得新的关键点。