ORB 未检测 opencv 2.4.9 中的关键点

Posted

技术标签:

【中文标题】ORB 未检测 opencv 2.4.9 中的关键点【英文标题】:ORB is not detecting keyPoints in opencv 2.4.9 【发布时间】:2014-06-20 08:02:30 【问题描述】:

我正在尝试使用 ORB 检测关键点,一切都很好,直到我切换到 Opencv 2.4.9。

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

这是我用两个版本编译的代码:(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 个关键点

2.4.9: 找到 0 个关键点

我还使用不同的 ORB 构造函数进行了测试,但我得到了相同的结果,没有 KPts。 与 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;

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

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

谢谢。

【问题讨论】:

你有解决办法吗? 在其他图像上你也发现了 0 个关键点?还是与 openCV 2.3.1 相比,关键点更少? 【参考方案1】:

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;

【讨论】:

【参考方案2】:

至少在 OpenCV 3.1 中,edgeThreshold 参数实际上是“未检测到特征的边界的大小”。检测附加特征的一种方法是减小fastThreshold 参数。这是一个具有误导性的名称,因为即使在使用 ORB::HARRIS_SCORE(即 Harris 关键点)时,此阈值也会影响检测到的角点数量,而不仅仅是您根据参数名称可能认为的 FAST 关键点。这也有点误导,因为edgeThreshold 本身听起来像是 Harris 角点检测的阈值,而不是用于检测点的图像部分。 请参阅: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 减少以获得新的关键点.

【讨论】:

以上是关于ORB 未检测 opencv 2.4.9 中的关键点的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV ORB 检测器发现的关键点很少

使用 OpenCV Cuda ORB 特征检测器

OpenCV中的特征匹配(Feature Matching)

OpenCV ORB 特征检测器如何工作?

OpenCV+Python特征提取算法与图像描述符之SIFT / SURF / ORB

OpenCV 例程 300篇246. 特征检测之ORB算法