Ask Your Question

Revision history [back]

Is Feature Detection Feasible on Android?

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.

image description

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<DMatch> 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<DMatch> good_matches_list = new ArrayList<>();
    for (int i = 0; i < matches12_list.size(); i++) {
        if (matches12_list.get(i).distance < 3 * min_dist) {

    drawMatches(gray2, _keypoints2, good_matches_list, (double) gray2.height(), (double) gray2.width());