我正在使用cvBlobs来跟踪视频中的某些对象。 cvBlobs使用旧的C接口和IplImage,cvMat等类型。我使用的是使用cv :: Mat的C ++接口。
所以我必须在两种类型之间进行转换才能使用该库。这有效,但我无法释放内存。我的程序使用的内存不断增长。
这是我的代码,在底部你可以看到我尝试释放内存(编译器错误)。
void Tracker::LabelConnectedComponents(Mat& Frame, Mat& Foreground)
{
// Convert to old format, this is the method used in the opencv cheatsheet
IplImage IplFrame = Frame;
IplImage IplForeground = Foreground;
IplImage *LabelImg = cvCreateImage(cvGetSize(&IplFrame), IPL_DEPTH_LABEL, 1);
// Make blobs (IplForeground is the segmented frame, 1 is foreground, 0 background)
unsigned int result = cvLabel(&IplForeground, LabelImg, Blobs);
// Remove small blobs
cvFilterByArea(Blobs, 500, 1000000);
// Draw bounding box
cvRenderBlobs(LabelImg, Blobs, &IplFrame, &IplFrame, CV_BLOB_RENDER_BOUNDING_BOX | CV_BLOB_RENDER_CENTROID);
// Convert back to c++ format
Frame = cvarrToMat(&IplFrame);
// Here are the problems
cvReleaseImage(&IplFrame); // error
cvReleaseImage(&IplForeground); // error
cvReleaseImage(&LabelImg); // ok
}
cvReleaseImage具有IplImage **类型的参数,这是编译器错误:
tracker.cpp|35 col 33 error| cannot convert ‘IplImage* {aka _IplImage*}’ to ‘IplImage** {aka _IplImage**}’ for argument ‘1’ to ‘void cvReleaseImage(IplImage**)’
我知道& IplFrame不是正确的参数,但&& IplFrame不起作用。我该如何发布那些2 IplImages?
答案 0 :(得分:1)
问题是你在这里创建了对象的副本:
IplImage IplFrame = Frame;
IplImage IplForeground = Foreground;
因此,这些电话:
cvReleaseImage(IplFrame);
cvReleaseImage(IplForeground);
即使可以编译,也不会发布原始图像。如果您已经删除了对象(即更改它们),为什么要将它们作为引用而不是指针发送到方法?我有点困惑,因为你似乎正在做这样的事情:
Mat frame = ...
Mat fg = ...
LabelConnectedComponents(frame, fg); // function releases the frame/fg memory
// at this point you are left with invalid frame/fg
我查看了文档,并说Mat::operator IplImage() doesn't copy data
,这意味着IplFrame没有内存,因此发布它是不正确的。
我认为这取决于Mat
实例的创建方式 - 如果它是从IplImage*
创建的,copyData
设置为false
,那么您需要发布原始版本IplImage
个实例。如果创建时copyData
设置为true
,那么Mat
实例会自动处理它(除非您使用Mat::release
明确地执行此操作)
答案 1 :(得分:1)
您无需取消分配从Mat对象构造的IplImages。这些是薄包装器,不会复制数据,因此您不需要释放任何内容。
由于cv :: Mat具有自动内存管理功能,因此您无需任何内容。
并且,作为完成,要调用cvReleaseImage,您需要发送指向指针的指针:
IplImage* pimg= cvLoadImage();
...
cvReleaseImage(pimg);
构造
IplImage img;
...
cvReleaseImage(&&img);
不起作用,因为& img是一个地址(内存地址),但不表示变量。因此,下一个评估&(& img)将给出编译器错误,因为& img是一个值。该值不能有地址,但它是一个简单的数字。