内存管理对于图像类至关重要 . 在opencv中,图像类是 cv::Mat
,它具有精细的内存管理方案 . 假设我已经拥有自己的图像类 SelfImage
:
class SelfImage
{
public:
int width_;
int height_;
unsigned char *pPixel_;
};
首先,我将把所有图像像素内容放到这个类中:
SelfImage myImage;
myImage.width_ = 300;
myImage.height_ = 200;
myImage.pPixel_ = new [300*200];
for(int i=0; i<300*200; i++)
myImage.pPixel_[i] = i%200;
然后我的问题是如何以非常有效的方式将这个类转换为 cv::Mat
,我有一个解决方案:
cv::Mat mat;
mat.create( myImage.height_, myImage.width_, CV_8UC1);
mat.data = myImage.pPixel_;
我不知道这是否是一个很好的解决方案 . 如果 cv::Mat::create
函数也会分配内存,那么上面的代码就有内存泄漏的危险 . 有任何想法吗?
EDIT 我必须说清楚,如果我可以使用 cv::Mat::create
方法但是与 SelfImage
类共享内存会很好 . 原因是定义了一个函数来执行图像类转换作业 void TransImageType(const SelfImage &geo_img, cv::Mat &mat)
;
4 回答
cv::Mat
has a constructor您可以在其中指定用户数据:文档说明了关于
data
参数的以下内容:这取决于您是否要复制数据 .
根据您的建议,您似乎想要共享数据 . 在这种情况下,这是最好的解决方案:
mat
在取消分配时不会释放内存,您必须这样做 .如果要复制数据,请创建正常的
cv::Mat
并稍后执行std::copy
(或建议使用memcpy
作为@KeillRandor) .Mat::create()
分配数据(total()*elemSize()
字节)并将分配数据的内部引用计数器初始化为1(除非Mat
已经存在且具有create()
方法中指定的相同大小/类型) .是的,你的代码 produces a memory leak ,因为移动
Mat::data
指针时Mat::create()
分配的数据会丢失 .正确的做法应该是(在我看来)使用
memcpy
从myImage.pPixel_
到mat.data
(在致电create()
之后) . 这似乎效率低下,但好的一面是Mat
析构函数将处理数据释放 .你可以简单地使用
这样,就不会复制任何数据 . 当然,作为价格,你应该注意释放记忆 .
来自doc: