如何将像素数据的所有权传递给 cv::Mat
Posted
技术标签:
【中文标题】如何将像素数据的所有权传递给 cv::Mat【英文标题】:How do I pass ownership of pixel data to cv::Mat 【发布时间】:2014-03-19 16:09:12 【问题描述】:我正在创建一个 cv::Mat 传递我在外部分配的像素数据。
cv::Mat myMatrix(vImageResult.height,
vImageResult.width,
CV_8UC1,
vImageResult.data);
我希望 cv::Mat 获得字节的所有权(即创建一个 refCount 并在它达到零时释放字节)。但是documentation 说
如果我立即释放底层的采用数据和步骤参数的矩阵构造函数不分配矩阵数据。相反,它们只是初始化指向指定数据的矩阵头,这意味着没有数据被复制。此操作非常高效,可用于使用 OpenCV 函数处理外部数据。 外部数据不会被自动释放,所以你应该注意它。
vImageResult.data
,我将在某个地方遇到糟糕的访问崩溃。
如果我不释放底层的vImageResult.data
,那么数据就会泄漏。
有没有办法传递所有权?
【问题讨论】:
只做myMatrix=vImageResult
有什么问题?
@AldurDisciple vImageResult 可能不是 cv::Mat。这应该是“外部分配”的意思,也是我写答案时的假设。
我认为你不能这样做,因为 Mat 不知道你如何分配内存(malloc、new 等),因此也不知道如何释放它。
IIRC - 解决方案是创建 cv::Mat,获取底层字节并将它们传递给外部程序进行操作。这样 cv::Mat 保留所有权,因为它首先创建了它们。
【参考方案1】:
一个选项是使用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.
【讨论】:
复制后可以立即释放原始数据。这也是我的建议,尽管严格来说这不是问题的答案:D 右(两点)。据我在文档中看到的,没有办法传递所有权,所以这个选项最接近 OP 想要的。 @anderas 你假设vImageResult
不是cv::Mat
一定是对的,但是也许你应该添加一些关于如何使用clone()
来传递所有权的细节。【参考方案2】:
你不能。
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。它没有虚拟析构函数。
【讨论】:
以上是关于如何将像素数据的所有权传递给 cv::Mat的主要内容,如果未能解决你的问题,请参考以下文章
如何将 cv::mat 对象从 python 模块传递给 c++ 函数并返回返回的 cv::mat 类型的对象?
如何将 opencv Mat 类型传递给 Python 并返回一个数组?