如何将像素数据的所有权传递给cv :: Mat

时间:2014-03-19 16:09:13

标签: c++ c opencv memory-management

我正在使用我在外部分配的像素数据创建一个cv :: Mat传递。

cv::Mat myMatrix(vImageResult.height,
                 vImageResult.width,
                 CV_8UC1,
                 vImageResult.data);

我希望cv :: Mat获取字节的所有权(即创建一个refCount并在它达到零时释放字节)。但是documentation

  

采用数据和步骤参数的矩阵构造函数不分配矩阵数据。相反,它们只是初始化指向指定数据的矩阵标头,这意味着不会复制任何数据。此操作非常有效,可用于使用OpenCV函数处理外部数据。 外部数据不会自动解除分配,因此您应该对其进行处理。

  • 如果我立即释放了基础vImageResult.data,那么我将在某个地方遇到一个糟糕的访问崩溃。
  • 如果我没有释放潜在的vImageResult.data,那么数据就会韭菜。

有没有办法通过所有权?

2 个答案:

答案 0 :(得分:4)

选项是使用Mat::clone()将数据复制到新矩阵,// create temporary matrix that holds the external/old data cv::Mat tmp(vImageResult.height, vImageResult.width, CV_8UC1, vImageResult.data); cv::Mat myMatrix = tmp.clone(); // myMatrix now has ownership of a clone of the data. 执行数据的深层复制。然后,新矩阵将拥有克隆数据的所有权。

例如:

{{1}}

答案 1 :(得分:4)

你不能。

cv :: Mat不知道你是如何分配内存的(malloc,new等),因此不知道如何释放它。

如果您自己分配数据,可以随时调用cv::Mat::create(...)来分配所需的内存,然后将指针myMatrix.data传递给您用来加载数据的任何函数。

如果您指的是通过视频捕获流或外部库提供给您的预先分配的内存,那么您就不走运了。

Andreas的解决方案可行,但如果频繁使用,可能会很慢。

妥协可能是将cv::Mat包裹在您自己的类型中:

struct MyMat
{
    cv::Mat mat;
    MyMat(int width, int height, int format, char *data)
        : mat(height, width, format, data){}
    ~MyMat() { delete [] mat.data; }
};

注意:故意不尝试子类cv :: Mat。它没有虚拟析构函数。