我使用Emgu CV包装器作为OpenCV

我想创建以某种方式生成轮廓并将其返回的函数。

要创建轮廓,请使用以下代码:

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

谁应该关心MemStorage的释放?
我应该执行其他操作,还是EmguCV在没有其他代码的情况下可以正确处理这种情况?

还是以下代码正确:
MemStorage memStorage = new MemStorage();
Contour<PointF> contour = new Contour<PointF>(memStorage);

memStorage应该被明确释放?

最佳答案

因此很好的问题是投票,我希望内存存储(Memstorage)的用途与.Net中的任何其他变量相同。如果打算在调用时以多种方法创建它,则创建全局内存存储分配会更有效。由于Memstorage是指向存储变量的物理地址的指针,因此最好重写其中的单个变量,然后创建一个新的Memstorage,在该位置必须重新池化和重新分配资源。

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

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

在对问题的具体回答中,您应考虑使用using语句来确保MemStorage正确释放,但这仅应在调用该方法且有足够的中断的情况下进行。如果要在for循环中依次调用此方法,则应将MemStorage声明为类中的全局变量,然后在可能的情况下,在调用垃圾收集器之前,在类的IDisposable方法中将其设置为null。一旦循环完成,则可以调用该类的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循环抑制数据应使用轮廓的边界约束,而不是边界矩形。一旦我对此进行调整,我将相应地更新代码。

我希望这可以帮助您回答一些问题,

干杯,

克里斯

关于c# - 创建轮廓时,谁应该关心MemStorage的重新分配?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8325390/

10-09 03:11