This previous answer seems clear, except the following code doesn't change the number of features detected. How to extract more than 500 features (the default)? The parameter list / order was changed to match the protected variable list in orb.cpp.
File outputFile = new File("detectorParams.yml");
detector = FeatureDetector.create(FeatureDetector.ORB);
detector.read(outputFile.getAbsolutePath());
MatOfKeyPoint kp1 = new MatOfKeyPoint();
for (images in video) {
Mat img = ...
detector.detect(img, kp1);
}
YML Parameter file:
%YAML:1.0
nfeatures: 2000
scaleFactor: 1.2000000000000000e+000
nlevels: 8
edgeThreshold: 31
firstLevel: 0
wta_k: 2
scoreType: 0
patchSize: 31
fastThreshold: 0
Here is the xml file that was tried (generated based on this example
<?xml version="1.0"?>
<opencv_storage>
<nfeatures>2000</nfeatures>
<scaleFactor>1.2000000000000000e+000</scaleFactor>
<nlevels>8</nlevels>
<edgeThreshold>31</edgeThreshold>
<firstLevel>0</firstLevel>
<wta_k>2</wta_k>
<scoreType>0</scoreType>
<patchSize>31</patchSize>
<fastThreshold>0</fastThreshold>
</opencv_storage>
kp1 always has 500 rows which is the default value for nfeatures. So, the reading the yml file did not change the value of nfeatures to 2000. I have tried 1) the original list in the previous answer, 2) writing to xml and yml but I didn't change the format for xml, 3) writing only nfeatures.
Code to generate xml / yml files
#include "opencv2/opencv.hpp"
#include <time.h>
using namespace cv;
int main(int, char** argv)
{
int nfeatures=2000, nlevels=8, edgeThreshold=31, firstLevel=0, wta_k=2,
scoreType=ORB::HARRIS_SCORE, patchSize=31, fastThreshold=0;
double scaleFactor=1.2;
for (int ft=0; ft<2; ft++) {
FileStorage fs;
if (ft==0) {
fs = FileStorage("test_descrip.xml", FileStorage::WRITE);
} else {
fs = FileStorage("test_descrip.yml", FileStorage::WRITE);
}
fs << "nfeatures" << nfeatures;
fs << "scaleFactor" << scaleFactor;
fs << "nlevels" << nlevels;
fs << "edgeThreshold" << edgeThreshold;
fs << "firstLevel" << firstLevel;
fs << "wta_k" << wta_k;
fs << "scoreType" << scoreType;
fs << "patchSize" << patchSize;
fs << "fastThreshold" << fastThreshold;
fs.release();
}
return 0;
}
I tried writing a c++ to output the parameters, but nothing gets printed.
int main(int argc, char** argv) {
// CV_WRAP static Ptr<ORB> create(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31,
// int firstLevel=0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31, int fastThreshold=20);
Ptr<ORB> orb=ORB::create(2000,1.3f,9,32,0,2,ORB::HARRIS_SCORE,35,22);
FileStorage fs1("testorb.yml", FileStorage::WRITE);
FileStorage fs2("testorb.xml", FileStorage::WRITE);
orb->setMaxFeatures(2500);
orb->write(fs1);
orb->write(fs2);
return 0;
}
This creates the two files but they are both empty
testorb.xml
<?xml version="1.0"?>
<opencv_storage>
</opencv_storage>
testorb.yml
%YAML:1.0