【问题标题】:How to make OpenCV tracking classes derive from a base class?如何使 OpenCV 跟踪类派生自基类?
【发布时间】:2021-07-13 12:42:07
【问题描述】:

OpenCV 跟踪 API 在 3 个不同的地方实现。

  • video/tracking.hpp
  • tracking.hpp
  • tracking/tracking_legacy.hpp

我希望能够通过提供算法名称作为输入来使用任何实现。

cv::Ptr<cv::Tracker> get_tracker(std::string trackerType);

A similar approach with Python 似乎有效。

if tracker_type == 'CSRT':
    tracker = cv2.TrackerCSRT_create()
elif tracker_type == 'MOSSE':
    tracker = cv.legacy.TrackerMOSSE_create()
...
ok = tracker.init(frame, bbox)
ok, bbox = tracker.update(frame)

C++ 的问题是tracker 的类型应该在编译时就知道了。

拥有different implementations using templates是函数的解决方案,但我们返回的是一个对象,所以这不适用。

正确的解决方案是使用继承从具有纯虚函数initupdate 的基类派生cv::Trackercv::legacy::Tracker。这两个类都有这些方法,但它们分别从cv::Algorithm 派生而来,cv::Algorithm 没有任何这些功能。

到目前为止,我创建了单独的函数来获取跟踪器对象。

#include <opencv2/tracking.hpp>
#include <opencv2/tracking/tracking_legacy.hpp>
#include <string>
#include <stdexcept>

// https://docs.opencv.org/4.5.2/d0/d0a/classcv_1_1Tracker.html
cv::Ptr<cv::Tracker> get_tracker(std::string trackerType)
{
    if (trackerType == "MIL")
        return cv::TrackerMIL::create();
    if (trackerType == "GOTURN")
        return cv::TrackerGOTURN::create();
    if (trackerType == "CSRT")
        return cv::TrackerCSRT::create();
    if (trackerType == "KCF")
        return cv::TrackerKCF::create();
    throw std::runtime_error("Unknown tracker type.");
}

// https://docs.opencv.org/4.5.2/db/dfe/classcv_1_1legacy_1_1Tracker.html
cv::Ptr<cv::legacy::Tracker> get_legacy_tracker(std::string legacyTrackerType)
{
    if (legacyTrackerType == "MIL")
        return cv::legacy::TrackerMIL::create();
    if (legacyTrackerType == "BOOSTING")
        return cv::legacy::TrackerBoosting::create();
    if (legacyTrackerType == "MEDIANFLOW")
        return cv::legacy::TrackerMedianFlow::create();
    if (legacyTrackerType == "TLD")
        return cv::legacy::TrackerTLD::create();
    if (legacyTrackerType == "KCF")
        return cv::legacy::TrackerKCF::create();
    if (legacyTrackerType == "MOSSE")
        return cv::legacy::TrackerMOSSE::create();
    if (legacyTrackerType == "CSRT")
        return cv::legacy::TrackerCSRT::create();
    throw std::runtime_error("Unknown legacy tracker type.");
}

我将跟踪器类型作为命令行输入。任何使以下代码适用于所有跟踪器类型的解决方案都值得赞赏。 Tracker 在可用时优先于 legacy

tracker->init(frame, bbox);
bool ok = tracker->update(frame, bbox);

注意:我使用的是 OpenCV 4.5.2。 legacy 模块在this commit 中创建。

另外说明: 目前,opencv-python==4.5.2 的 pip 包不可用。提供的 Python 代码未经测试,而是根据文档编写的。

【问题讨论】:

    标签: c++ opencv4


    【解决方案1】:

    解决方案在于 OpenCV 的示例脚本。 (tracking/samples/samples_utility.hpp)

    我们需要将cv::legacy::Tracker 转换为首选类型cv::Tracker。就像函数的不同输入问题一样,我们需要分别实现这些成员函数。

    class LegacyTrackerWrapper : public cv::Tracker
    {
        const cv::Ptr<cv::legacy::Tracker> legacy_tracker_;
    
    public:
        LegacyTrackerWrapper(const cv::Ptr<legacy::Tracker>& legacy_tracker)
            : legacy_tracker_(legacy_tracker) {}
    
        ~LegacyTrackerWrapper() override {}
    
        void init(cv::InputArray image, const cv::Rect& boundingBox) override
        {
            legacy_tracker_->init(image, static_cast<cv::Rect2d>(boundingBox));
        }
    
        bool update(cv::InputArray image, cv::Rect& boundingBox) override
        {
            cv::Rect2d boundingBox2d;
            bool res = legacy_tracker_->update(image, boundingBox2d);
            boundingBox = static_cast<cv::Rect>(boundingBox2d);  // the cast is not defined by default
            return res;
        }
    };
    

    我们可以使用包装类来获得所需的行为。

    cv::Ptr<cv::Tracker> upgradeTrackingAPI(const cv::Ptr<legacy::Tracker>& legacy_tracker)
    {
        return cv::makePtr<LegacyTrackerWrapper>(legacy_tracker);
    }
    
    cv::Ptr<cv::Tracker> get_tracker(std::string trackerType)
    {
        if (trackerType == "CSRT")
            return cv::TrackerCSRT::create();
        if (trackerType == "MOSSE")
            return upgradeTrackingAPI(cv::legacy::TrackerMOSSE::create());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-05
      • 1970-01-01
      • 2017-07-04
      • 1970-01-01
      相关资源
      最近更新 更多