0

我在 x86_64 架构上为 Ubuntu 12.10 使用 OpenCV 2.4.6.1 的 C++ 实现。我正在将 Agast Corner Detector 的代码封装在一个继承自cv::FeatureDetector.

检查feature2d 模块头代码并观察其他实现,我发现我应该强制实现该detectImpl方法:

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

通常它还实现了一个名为operator具有以下签名的方法:

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

查看其他实现,我不能确切地说每种方法应该做什么。operator我猜第二个与检测关键点的检测方法有关:

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

根据您的经验,这两种方法有什么区别,它们各自应该实现什么?

与使用工厂方法的检测器实例化cv::FeatureDetector::create相关,我有一些与通常作为检测器类实现的公共属性并使用源文件中的 CV_INIT_ALGORITHMinfo的类型属性相关的线索。AlgorithmInfo*features2d_init

为了能够使用工厂方法实例化我的自定义 FeatureDetector,我应该实现什么?

4

1 回答 1

1

最后经过几天的工作,我成功地兑现了我的承诺,并学到了一些关于实现cv::FeatureDetector接口的经验:

  • 将包装类包含到 cv 命名空间中。

  • 唯一强制实施detectImpl的方法是在您使用的 OpenCV 版本上使用该方法的签名。

  • 实现 operator 方法是可选的,在使用它的其他实现中(例如MserFeatureDetectorand StarDetector),此方法是detectImpl通过类实例调用的:

    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{
    ...
    }
    
  • 请注意,这detectImpl是一个 const 方法,因此它不能修改实例参数,因此它可能会像在其他检测器实现中所做的那样,在辅助函数上定义检测器的具体行为(例如FastFeatureDetectorStarDetector)。

  • 要使包装器能够使用工厂方法进行实例化,cv::FeatureDetector::create您应该在类声明中添加公共方法AlgorithmInfo* info() const;,并使用以下方法将类初始化为 OpenCV 中的算法CV_INIT_ALGORITHM

    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));
    }
    

    如果您的课程不需要任何参数,您可以简单地将所有参数部分替换为obj.info()

    还要提醒在您声明 (.h) 或定义 (.cpp) 包装器并包含opencv2/core/internal.hpp库的源文件之外执行此操作。

于 2013-08-23T15:59:56.907 回答