Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ORB is not detecting keyPoints in opencv 2.4.9

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.

like image 557
rednaks Avatar asked May 03 '14 18:05

rednaks


2 Answers

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;
}
like image 68
nils Avatar answered Oct 11 '22 07:10

nils


In OpenCV 3.1, at least, the edgeThreshold parameter is actually the "size of the border where the features are not detected." One way to detect additional features is to decrease the fastThreshold parameter. It's a misleading name because this threshold impacts the number of corners detected even when using ORB::HARRIS_SCORE, that is Harris keypoints, not only FAST keypoints as you might think based on the argument name. It's also a bit misleading because edgeThreshold itself sounds like a threshold on Harris corner detection, not on the part of the image used for detecting points.

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

Additionally, increasing the number of pyramid levels nlevels could give you more keypoints, although if your image sizes are the same and the only difference is your OpenCV version, it's unlikely to help here.

I ran into the same issue and here's the code that worked:
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);

The last argument (20, above) is the fastThreshold to decrease to get new keypoints.

like image 23
chloelle Avatar answered Oct 11 '22 07:10

chloelle