当轮廓被创建时,谁应该关心MemStorage的释放

本文关键字:关心 MemStorage 释放 轮廓 创建 | 更新日期: 2023-09-27 18:16:07

我使用Emgu CV wrapper for OpenCV。

我想创建一个函数,以某种方式生成轮廓并返回它。

要创建轮廓,我使用如下命令:

Contour<PointF> contour = new Contour<PointF>(new MemStorage());

谁来负责MemStorage的再分配?
我是否应该执行额外的操作,或者EmguCV是否可以在没有额外代码的情况下正确处理这种情况?

或者下面的代码是否正确:

MemStorage memStorage = new MemStorage();
Contour<PointF> contour = new Contour<PointF>(memStorage);

memStorage应该显式释放吗?

当轮廓被创建时,谁应该关心MemStorage的释放

好问题,因此upvote,我希望内存存储(Memstorage)的us与。net中的任何其他变量相同。如果您打算在调用时在多个方法中创建它,那么创建全局内存存储分配将更有效。由于Memstorage是一个指向存储变量的物理地址的指针,因此最好覆盖其中的单个变量,然后创建一个新的Memstorage,这样资源就必须重新池化和重新分配。

值得庆幸的是,垃圾收集器非常有效,当您退出收集Memstorage的方法时,它所占用的资源将在需要时或当您的程序不做任何事情时重新分配。您总是可以通过将Memstorage变量设置为空并调用GB.Collect()方法来告诉垃圾收集器手动执行此操作,当然这依赖于Memstorage类是可空的。

为了确保尽可能有效地处理内存分配,应该使用using语句。这将释放Memstrage变量使用的资源。这里是一个例子,我从opencv转换到完成与matlab相同的bwareopen,其中较小的项目或被压制。它确实需要工作,但那是在数据抑制方面。然而,using语句仅在不多次访问函数时才适用,例如在循环中。

在你的问题的具体答案中,你应该考虑使用using语句来确保MemStorage被正确释放,但这应该只有在方法被调用时有足够的中断时才会发生。如果要在for循环中依次调用此方法,则应将MemStorage声明为类中的全局变量,然后在可能的情况下,在调用垃圾收集器之前在类的IDisposable方法中将其设为空。一旦循环完成,就可以调用类的dispose方法来有效地重新分配资源。如果你也想要这样的例子,请让我知道,我会相应地更新我的答案。

using和MemStorage示例:

private Image<Bgr, byte> bwareaopen(Image<Bgr, byte> Input_Image, int threshold)
{
    Image<Bgr, byte> bwresults = Input_Image.Copy();
    using (MemStorage storage = new MemStorage())
    {
        for (Contour<Point> contours = Input_Image.Convert<Gray, byte>().FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE, Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_LIST, storage); contours != null; contours = contours.HNext)
        {
            Contour<Point> currentContour = contours.ApproxPoly(contours.Perimeter * 0.05, storage);
            if (currentContour.Area < threshold) 
            {
                for (int i = currentContour.BoundingRectangle.X; i < currentContour.BoundingRectangle.X + currentContour.BoundingRectangle.Width; i++)
                {
                    for (int j = currentContour.BoundingRectangle.Y; j < currentContour.BoundingRectangle.Y + currentContour.BoundingRectangle.Height; j++)
                    {
                        bwresults.Data[j, i, 0] = 0;
                        bwresults.Data[j, i, 1] = 0;
                        bwresults.Data[j, i, 2] = 0;
                    }
                }
            }
        }
    }
    return bwresults;
}

openCV代码可在这里获得http://tech.groups.yahoo.com/group/OpenCV/message/27345所有的功劳都归功于M.Klien在matlab中转换了该方法。

对于那些有兴趣让这个函数正确工作的人来说,For循环抑制数据应该使用轮廓的边界约束而不是边界矩形。一旦我调整了这一点,我将相应地更新代码。

我希望这对回答你的问题有所帮助,

欢呼,克里斯