Feature Detectors: getAlgorithm("detector") works for GridGFTT, but does not for GridSIFT

asked 2014-07-23 17:12:44 -0500

JK gravatar image

updated 2014-07-24 05:03:09 -0500

Hi all,

I want to use grid-adapted feature detectors, be able to choose whether or not to perform gridding in an INI and, set all the parameters in an INI (parameters of the feature detector as well as the GridAdapter).

All works fine for "GridGFTT" and "GFFT" feature detectors, respectively. Here is a code snippet of what I do:

// OpenCV
#include "opencv2/features2d/features2d.hpp"

// ----------------------------------------------------------------------------

int main(int argc, char** argv)
{
    // smart ptr of detector ----------------------------------------------------
    cv::Ptr<cv::FeatureDetector> _detector; // gridded or non-gridded (depending on case)
    cv::Ptr<cv::FeatureDetector> detector_obj; // always non-gridded
    bool gridded = true;
    //bool gridded = false;

    // construct detector -------------------------------------------------------
    if(!_detector) {
        if(gridded) {
            // gridded
            _detector = cv::FeatureDetector::create(
                "GridGFTT");
            detector_obj = _detector->getAlgorithm("detector");
        } else {
            // non-gridded
            _detector = cv::FeatureDetector::create(
                "GFTT");
            detector_obj = _detector; // copy of _detector -> so I do not need to distinguish cases when parameterizing
        }
        // check construction
        if(_detector.empty() || detector_obj.empty()) {
            printf("nope\n");
            return 1;
        }
    }

    // perform custom init -------------------------------------------------------
    if(gridded)  {
        std::vector<std::string> test;
        _detector->getParams(test);
        _detector->set("gridCols", 2);
        _detector->set("gridRows", 2);
        _detector->set("maxTotalKeypoints", 100);
    }
    std::vector<std::string> test;
    detector_obj->getParams(test);
    detector_obj->set("nfeatures", 100);
    detector_obj->set("qualityLevel", 1);
    detector_obj->set("minDistance", 2);
    //detector_obj->set("blockSize", 3);
    detector_obj->set("useHarrisDetector", 4);
    detector_obj->set("k", 5);

    // run detector -------------------------------------------------------------
    //_detector->detect()

    // destruct detector --------------------------------------------------------
    _detector.release();

    printf("yeah\n");
    return 0;
};

Gridding is selected on line 10/11, grid adapter parameters (if needed) are set on lines 36-40 and, feature descriptor parameters are set on lines 42-49. I use a "detector_obj" on line 20, so I do not have to distinguish cases when parameterizing. As already mentioned, both cases work out just fine -> prints "yeah" on exit.

Bug-report: "blockSize" on line 47 can not be set this way (not returned by getParams()). I guess this can be fixed on initialization of the GFTTDetector algorithm in ./modules/features2d/src/features2d_init.cpp:

CV_INIT_ALGORITHM(GFTTDetector, "Feature2D.GFTT",
                  obj.info()->addParam(obj, "nfeatures", obj.nfeatures);
                  obj.info()->addParam(obj, "qualityLevel", obj.qualityLevel);
                  obj.info()->addParam(obj, "minDistance", obj.minDistance);
                  obj.info()->addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
                  obj.info()->addParam(obj, "k", obj.k));

Ok. So far so good. BUT when I try this with "GridSIFT" and "SIFT" instead I can not access the detector_obj in the gridded case. Again, a code snippet for illustration:

// OpenCV
#include "opencv2/nonfree/features2d.hpp"
#include "opencv2/nonfree/nonfree.hpp"

// ----------------------------------------------------------------------------
// statics
// ----------------------------------------------------------------------------

static bool makeUseOfNonfree = cv::initModule_nonfree();

// ----------------------------------------------------------------------------

int main(int argc, char** argv)
{
    // smart ptr of detector ----------------------------------------------------
    cv::Ptr<cv::FeatureDetector> _detector; // gridded or non-gridded (depending on case)
    cv::Ptr<cv::FeatureDetector> detector_obj; // always non-gridded
    bool gridded = true;
    //bool gridded = false;

    // construct detector -------------------------------------------------------
    if(!_detector) {
        if(gridded) {
            // gridded
            _detector = cv::FeatureDetector::create(
                "GridSIFT");
            detector_obj = _detector->getAlgorithm("detector");
        } else {
            // non-gridded
            _detector = cv::FeatureDetector::create(
                "SIFT");
            detector_obj = _detector; // copy of _detector -> so I do not need to distinguish cases when parameterizing
        }
        // check construction
        if(_detector.empty() || detector_obj.empty()) {
            printf("nope\n");
            return 1;
        }
    }

    // perform custom init -------------------------------------------------------
    if(gridded)  {
        std::vector<std::string> test;
        _detector->getParams(test);
        _detector->set("gridCols", 2);
        _detector->set("gridRows", 2 ...
(more)
edit retag flag offensive close merge delete