如何在没有额外分配的情况下从 OpenCV 矩阵中获取图像数据?
Posted
技术标签:
【中文标题】如何在没有额外分配的情况下从 OpenCV 矩阵中获取图像数据?【英文标题】:How to get image data from OpenCV matrix without extra allocation? 【发布时间】:2013-07-26 12:40:39 【问题描述】:我想做以下事情:
-
复制一份我以某种方式检索到的 Cv::mat
转换它
将指向数据的指针连同元信息(大小、格式等)一起返回给调用者
完成后,释放数据
我使用的代码是:
cv::Mat m(...); //here is source image
cv::Mat *img = new cv::Mat(m.clone());// copy the data
//do transformations
(*result)->pdata = img->data; // pointer to data gois to out parameter
img->addref(); //to prevent freeing the image data after tempo
delete img; //dispose of temporary object
...
delete [] outparam->pdata; //result == &outparam; free data after use
但是,在执行时,此代码会在以下位置产生断言失败:
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
我应该如何实现我的目标?
【问题讨论】:
【参考方案1】:您可以为预分配内存创建Mat
对象。在这种情况下,引用计数将被禁用,并且对象不会在析构函数中释放此内存:
cv::Mat m(...);
Mat img(rows, cols, type, (*result)->pdata);
m.copyTo(img);
...
delete [] (*result)->pdata;
【讨论】:
我变换了 cv::mat 对象,改变了它的大小和颜色;我很确定这会改变分配数据的大小和数据本身 - 这就是为什么我想在转换后获取数据【参考方案2】:你想要做的是通过OpenCV的引用计数来实现的。依靠它而不是自己使用积分和分配是一个更好的主意。
cv::Mat m(...);
cv::Mat img = m; // this does not copy data, all the changes in img will be in m as well
// ... use img
// no delete necessary
请注意,如果您想在不删除原始内容的情况下转换数据,则需要复制数据。在这种情况下:
cv::Mat m(...)
cv::Mat img = m.clone(); // this copies data, m and img can be used as two different Mats
// ... use img
// no delete necessary, img will be automatically deallocated
如果释放的时间很重要,可以用范围控制:
cv::Mat m(...)
cv::Mat img = m.clone();
...
// img is automatically deleted here
// img is no longer available
【讨论】:
第一个示例与我想要的最接近,但有一个例外。我希望 img 中的图像数据在之后可用 - 并将它们返回给客户端。或者,underlting C 结构可能会这样做。现在我只使用 memcpy,但应该有办法没有它。 当你返回 img;你返回你的矩阵并且没有数据被复制,只是标题。使用 cv::Mat 复制和克隆功能比自己处理内存分配要安全得多。 我既不也不能返回 img,因为它是一个对象 - 我只需要返回数据以上是关于如何在没有额外分配的情况下从 OpenCV 矩阵中获取图像数据?的主要内容,如果未能解决你的问题,请参考以下文章