I'm getting poor results using a variety of Feature Detection Algos on Android. I cannot use SURF, SIFT, or BRISK because they are too slow (I'm using a Samsung Galaxy S5). So I've worked with ORB Detector/Orb Extractor, as well as with Orb Detector/FREAK extractor, both of which perform in real-time. However they aren't very good at finding my original training object in any scene with even small amounts of clutter.
I filter by Hamming distance. I apply cross-check and ratio test. I apply KNN. I use various combinations of these. I can't get a clear signal out of the noise. This photo below probably indicates the highest quality feature matching I can get, and there are many points that are not correct. The high number of errors would prevent an algo from confidentally identifying the object.

Is it possible to get a higher quality result?
Possibly my code is wrong, so here are the key lines of code, extracted from a larger class. In this example I'm using ORB Feature Detector and Descriptor Extractor with BF HAMMINGLUT matcher, and a simple distance filter.
DescriptorExtractor descriptorExtractor;
DescriptorMatcher _matcher;
FeatureDetector _detector;
Mat _descriptors;
MatOfKeyPoint _keypoints;
Mat _descriptors2;
MatOfKeyPoint _keypoints2;
private Mat trainFeatureDetector(CvCameraViewFrame inputFrame) {
Mat gray1 = inputFrame.gray();
_descriptors = new Mat();
_keypoints = new MatOfKeyPoint();
_detector = FeatureDetector.create(FeatureDetector.ORB);
_matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);
_detector.detect(gray1, _keypoints, _descriptors);
descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB);
descriptorExtractor.compute(gray1, _keypoints, _descriptors);
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Mat gray2 = inputFrame.gray();
_descriptors2 = new Mat();
_keypoints2 = new MatOfKeyPoint();
_detector.detect(gray2, _keypoints2);
descriptorExtractor.compute(gray2, _keypoints2, _descriptors2);
MatOfDMatch matches12 = new MatOfDMatch();
_matcher.match(_descriptors, _descriptors2, matches12);
List matches12_list = matches12.toList();
// .... filter based on distance...
//-- Quick calculation of min distances between keypoints
double min_dist = 0;
for (int i = 0; i < matches12_list.size(); i++) {
double dist = matches12_list.get(i).distance;
if (dist < min_dist) min_dist = dist;
}
//-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )
List good_matches_list = new ArrayList<>();
for (int i = 0; i < matches12_list.size(); i++) {
if (matches12_list.get(i).distance < 3 * min_dist) {
good_matches_list.add(matches12_list.get(i));
}
}
drawMatches(gray2, _keypoints2, good_matches_list, (double) gray2.height(), (double) gray2.width());
}
↧