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
2.4.9 : Found 0 Keypoints
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.
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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With