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

Iva*_*nko 7 c++ opencv deep-copy

我想深拷贝 cv::dnn::Net 的实例:

cv::dnn::Net n1 = cv::dnn::readNetFromONNX("");
cv::dnn::Net n2 = n1;
Run Code Online (Sandbox Code Playgroud)

但是这个类使用隐式共享,据我所知。我没有在文档中找到任何方法来做到这一点。是否有可能(例如某些方法 copy())允许完全复制实例?

f4f*_*f4f 3

为了找到您问题的答案,我参考了 OpenCV文档(对于 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;
};
Run Code Online (Sandbox Code Playgroud)

因此,您指出以某种方式创建它的副本是没有意义的cv::dnn::Net n2 = n1;,因为它只是创建另一个指向相同实现的指针,这是正确的。如果没有任何指向该实现的私有指针的接口,您很难在不修改源代码的情况下访问它。

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

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

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

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