我正在使用 cvBlobs 来跟踪视频中的一些对象。 cvBlobs 使用较旧的 C 接口(interface),其中包括 IplImage、cvMat 等类型,而我使用的是使用 cv::Mat 的 C++ 接口(interface)。
所以我必须在两种类型之间进行转换才能使用该库。这可行,但我在释放内存时遇到问题。我的程序使用的内存不断增长。
这是我的代码,在底部您可以看到我尝试释放内存(编译器错误)。
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 个 IplImage?
最佳答案
问题是您在此处创建了对象的拷贝:
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() does not copy data
,这意味着IplFrame不拥有内存,所以释放是不正确的它。
我认为这取决于 Mat
实例的创建方式 - 如果它是从 IplImage*
创建的,且 copyData
设置为 false
,那么您需要释放原始的IplImage
实例。如果它是在将 copyData
设置为 true
的情况下创建的,则 Mat
实例会自动处理它(除非您使用 Mat 显式执行此操作)::发布
)
关于c++ - 从 cv::Mat 初始化的 IplImage 的内存释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12635978/