我正在使用我在外部分配的像素数据创建一个cv :: Mat传递。
cv::Mat myMatrix(vImageResult.height,
vImageResult.width,
CV_8UC1,
vImageResult.data);
我希望cv :: Mat获取字节的所有权(即创建一个refCount并在它达到零时释放字节)。但是documentation说
采用数据和步骤参数的矩阵构造函数不分配矩阵数据。相反,它们只是初始化指向指定数据的矩阵标头,这意味着不会复制任何数据。此操作非常有效,可用于使用OpenCV函数处理外部数据。 外部数据不会自动解除分配,因此您应该对其进行处理。
vImageResult.data
,那么我将在某个地方遇到一个糟糕的访问崩溃。vImageResult.data
,那么数据就会韭菜。有没有办法通过所有权?
答案 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。它没有虚拟析构函数。