Andres Felipe
Andres Felipe

Reputation: 684

OpenCV - How to implement FeatureDetector interface

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?

Upvotes: 0

Views: 1779

Answers (1)

Andres Felipe
Andres Felipe

Reputation: 684

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.

Upvotes: 1

Related Questions