0

I am using the C++ implementation of OpenCV 2.4.6.1 for Ubuntu 12.10 on a x86_64 architecture. I am working on wrapping this code of the Agast Corner Detector inside a class inheriting from cv::FeatureDetector.

Inspecting the feature2d module header code and observing other implementations, I found I should mandatory implement the detectImpl method:

virtual void detectImpl( const Mat& image, std::vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const = 0;

Usually it is also implementented a method named operator having the following signature:

CV_WRAP_AS(detect) void operator()(const Mat& image, CV_OUT std::vector<KeyPoint>& keypoints) const;

Looking at other implementations I cannot say exactly what each of this methods should do. The second one operator I guess is somehow related to the detect method that is called for detecting keypoints:

cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create("...");
detector->detect(img, keypoints);

According to your experience what's the difference between this two methods and what should each of them implement?

Related to the detector's instantiation using the factory method cv::FeatureDetector::create I have some clues related to the attribute info of type AlgorithmInfo* usually put as a public attribute of the detector class implementation, and using the CV_INIT_ALGORITHM in the features2d_init source file.

What should I implement in order to be able to instantiate my custom FeatureDetector using the factory method?

Andres Felipe
  • 625
  • 7
  • 24

1 Answers1

1

Finally after a few days of work I succeeded on my commitment and learned a few lessons about implementing cv::FeatureDetector interface:

  • Include the wrapping class into the cv namespace.

  • The only method mandatory to implement is detectImpl using the signature of the method on the OpenCV version you are using.

  • Implementing the operator method is optional, in other implementations where it is used (e.g. MserFeatureDetector and StarDetector) this method is called from detectImpl through the class instance:

    void ...::detectImpl( const Mat& image, std::vector<KeyPoint>& keypoints, const Mat& mask ) const {
    ...
    (*this)(grayImage, keypoints);
    ...
    }
    
    void ...::operator()(const Mat& img, std::vector<KeyPoint>& keypoints) const{
    ...
    }
    
  • Be aware that detectImpl is a const method and hence it cannot modify instance parameters so It might turn useful defining the concrete behavior of the detector on a side function as done in other detector implementations (e.g. FastFeatureDetector or StarDetector)

  • To enable the wrapper to be instantiated using the factory method cv::FeatureDetector::create you should add to your class declaration the public method AlgorithmInfo* info() const; and initialize the class as an algorithm inside OpenCV using the CV_INIT_ALGORITHM as follows:

    namespace cv{
        CV_INIT_ALGORITHM(AgastFeatureDetector, "Feature2D.AGAST", obj.info()->addParam(obj, "threshold", obj.threshold); obj.info()->addParam(obj, "nonmaxsuppression", obj.nonmaxsuppression); obj.info()->addParam(obj, "type", obj.type));
    }
    

    If your class doesn't needs any parameter you can simply substitute all the params part by obj.info()

    Remind also to do this outside the source files where you are declaring (.h) or defining (.cpp) your wrapper and include the opencv2/core/internal.hpp library.

Andres Felipe
  • 625
  • 7
  • 24
  • You can take a look at my implementation on my github repository [AgastFeatureDetector.h](https://github.com/gantzer89/MediaEval-PlacingTask/blob/master/include/AgastFeatureDetector.h) and [AgastFeatureDetector.cpp](https://github.com/gantzer89/MediaEval-PlacingTask/blob/master/src/AgastFeatureDetector.cpp) – Andres Felipe Aug 23 '13 at 16:01
  • Have you tried submitting this to OpenCV? It looks like it would be a valuable contribution! – Aurelius Aug 23 '13 at 17:25
  • Thanks for the suggestion @Aurelius that would be nice, currently is just a wrapper of an external library and is rather far from optimal especially because of the unnecessary data structures transformation. I'll continue evolving it and I'll submit it if I achieve a reasonable performance, currently it takes around the double of the time to extract keypoints in comparison with FAST, its father, though theoretically it is faster. – Andres Felipe Aug 24 '13 at 19:10