如何使用cv :: dnn :: Net执行深层复制?

时间:2019-10-17 14:12:11

标签: c++ opencv deep-copy

我想深复制cv :: dnn :: Net的实例:

cv::dnn::Net n1 = cv::dnn::readNetFromONNX("");
cv::dnn::Net n2 = n1;

但是据我所知,此类使用隐式共享。而且我在文档中找不到任何方法来执行此操作。是否有可能(例如,某些方法copy())允许完全复制实例?

1 个答案:

答案 0 :(得分:1)

要找到您问题的答案,我已参考OpenCV docs(用于dnn模块)和source

对于cv :: dnn :: Net没有明确定义的复制或移动构造函数(和复制运算符)。此类仅是接口,唯一的数据成员是: 在其私有部分中指向实现的指针。

class CV_EXPORTS_W_SIMPLE Net
{
public:
    CV_WRAP Net();  //!< Default constructor.
    CV_WRAP ~Net(); //!< Destructor frees the net only if there aren't references to the net anymore.

...

private:
    struct Impl;
    Ptr<Impl> impl;
};

因此您应该指出,以cv::dnn::Net n2 = n1;方式创建它的副本是没有意义的,因为它只是创建了指向同一实现的另一个指针。而且,在没有指向该实现的私有指针的任何接口的情况下,几乎不修改源代码就几乎无法访问它。

您都不可以使用cv::dnn::Model(继承自cv::dnn::Net并允许设置输入参数),因为它也只是实现的指针。

我无法想象用例需要使用同一网络的两个不同实例。看起来OpenCV开发人员也做了同样的事情。

要在多线程环境中转发网络,您可以调用cv::dnn::Net::forwardAsync(),但仅适用于intel推理引擎后端。尝试从并发线程中调用cv::dnn::Net::forward()会导致运行时错误。

您可以从相同的配置和模型文件中自由创建两个网络,但是我再也无法想象有这样的用例了(由于内部设计的优化,forwardAsync()可能会提供更好的性能)。