如何在没有额外分配的情况下从 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 矩阵中获取图像数据?的主要内容,如果未能解决你的问题,请参考以下文章

opencv:矩阵分配混淆

OpenCV:在矩阵中,如何为一行中的所有元素分配相同的值

如何在不回显的情况下从 shell 脚本中获取密码

如何在没有 \n 的情况下从 txt 中获取特定行(Python)

如何在没有终端提示的情况下从 IPython 会话中复制

如何在没有动画的情况下从集合视图中删除项目?