ORB is not detecting keyPoints in opencv 2.4.9

rednaks picture rednaks · May 3, 2014 · Viewed 11.8k times · Source

I'm trying to detect keypoints with ORB everything is fine until I switched to Opencv 2.4.9.

Firts, it seems that the number of keys decresed, and for some images, no keypoints are detected :

This is my code compiled with two version : (2.3.1 and 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;
}

Result : 2.3.1 : Found 152 Keypoints

kp detected

2.4.9 : Found 0 Keypoints

zero kpts

I also tested with a different ORB Constructor, but I get the same result, no KPts. The same constuctor values as in 2.3.1 default's constructor : 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;
}

Do you have any idea what's happening ? And how can I fix it ?

Thank you.

Answer

nils picture nils · Mar 25, 2015

The implementation of ORB in OpenCV has changed quite significantly between version 2.3.1 and 2.4.9. It's hard to pin-point that one change that can explain the behavior you observed.

However, by changing the value of the edge threshold you can increase the number of detected features again.

Below is an adapted version of your code to show what I mean (careful, I could only test it with OpenCV 3.0.0, but I guess you get the point).

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