繁体   English   中英

在stl容器中释放opencv映像?

[英]Release the opencv Image in a stl container?

我在释放存储在stl容器中的opencv映像时遇到问题。 我正在开发一种系统,可以从相机保存最后几帧。 我需要一个容器来存储图像。 但是,当我尝试使用迭代器来访问图像并释放它们时,事情就出错了。 像这样。

deque<IplImage> ImageQue;
IplImage * temp=cvCreateImage(cvSize(30, 30), 8, 3);
ImageQue.push_back(*temp);
deque<IplImage>::iterator it=ImageQue.begin();
//temp and temp2 pointing different mem 
IplImage * temp2=&*it;
//this goes wrong. execption at memory location.
cvReleaseImage(&temp2);

如果我尝试这个。

IplImage * try1=cvCreateImage(cvSize(30, 30), 8, 3);
//try1 and try2 are pointing the same mem.
IplImage * try2=&*try1;
//things alright here.
cvReleaseImage(&try2);

我认为问题就在这里。 deque :: iterator it = ImageQue.begin(); IplImage * temp2 =&* it;

有这个想法吗? 或建议是否要在stl容器中释放图像?

看起来您正在混合并匹配指针间接寻址。 不这样做可能是一个好主意:

deque<IplImage> ImageQue; 
IplImage * temp=cvCreateImage(cvSize(30, 30), 8, 3); 
ImageQue.push_back(*temp); 

您可能应该使用一个指针容器(而不要使用大写字母作为实例名称):

deque<IplImage*> imageQueue; 
imageQueue.push_backcvCreateImage(cvSize(30, 30), 8, 3));
// ...
auto itr = imageQueue.begin();
IplImage* temp = *itr;
cvReleaseImage(&temp);

那类的东西。 更重要的是,也许……如果您将要破坏像这样的图像,您可能应该首先将它们从容器中取出,因为您可能不希望有悬空的指针队列。

IplImage* temp  = imageQueue.front();
imageQueue.pop_front();
cvReleaseImage(&temp);

您还可以考虑使用某种智能指针(在其生命周期结束时会自动释放IplImage)... OpenCV的最新版本不包含用于此类操作的不错的C ++ API,还是我误会了? 给定合适的自定义删除器, std::shared_ptr可能也可以工作。

我不认为C界面的IplImage会像您尝试做的那样按值复制。 如果要使用以值语义操作的C ++容器,则应该使用IplImage*容器,或者更好的是,使用C ++接口的cv :: Mat ,该容器使用RAII来复制和释放资源(即您不必担心释放)。

您可以在C ++ 11中使用std :: shared_ptr或在C ++ 03中使用Boost等价物。

您可以将对象的shared_ptr存储在stl容器中,但是需要指定删除器(默认的删除器是操作员删除)。

您可以在shared_ptr的构造函数中分配指针的删除器。 在您的情况下,cvReleaseImage函数。

Boost文档

模板shared_ptr(Y * p,D d); 模板shared_ptr(Y * p,D d,A a);

 Requirements: p must be convertible to T *. D must be CopyConstructible. The copy constructor and destructor of D must not throw. The expression d(p) must be well-formed, must not invoke undefined behavior, and must not throw exceptions. A must be an allocator, as described in section 20.1.5 (Allocator requirements) of the C++ Standard. Effects: Constructs a shared_ptr that owns the pointer p and the deleter d. The second constructor allocates memory using a copy of a. Postconditions: use_count() == 1 && get() == p. Throws: std::bad_alloc, or an implementation-defined exception when a resource other than memory could not be obtained. Exception safety: If an exception is thrown, d(p) is called. Notes: When the the time comes to delete the object pointed to by p, the stored copy of d is invoked with the stored copy of p as an argument. 

[自定义解除分配器允许工厂函数返回shared_ptr,以使用户与其内存分配策略隔离。 由于取消分配器不是该类型的一部分,因此更改分配策略不会破坏源或二进制兼容性,并且不需要重新编译客户端。 例如,当将shared_ptr返回到静态分配的对象时,“ no-op”解除分配器很有用,其他变体允许将shared_ptr用作另一个智能指针的包装,从而简化了互操作性。

对自定义解除分配器的支持不会带来很大的开销。 其他shared_ptr功能仍然需要保留释放程序。

D的副本构造函数不抛出的要求来自于按值传递。 如果复制构造函数引发,则指针泄漏。 删除需求需要通过(const)引用。

通过引用传递的主要问题在于它与右值的交互。 const引用可能仍然会导致复制,并且将需要const operator()。 非常量引用根本不会绑定到右值。 一个很好的解决方案是N1377 / N1385中提出的右值参考。]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM