C# 创建轮廓时,谁应负责MemStorage解除分配?

C# 创建轮廓时,谁应负责MemStorage解除分配?,c#,.net,memory-management,opencv,emgucv,C#,.net,Memory Management,Opencv,Emgucv,我用包装纸包装 我想创建一个函数,它以某种方式生成轮廓并返回它 要创建等高线,我使用以下方法: Contour<PointF> contour = new Contour<PointF>(new MemStorage()); 而且memStorage应该被显式释放吗?这是一个好问题。因此,我希望内存存储(memStorage)的us与.Net中的任何其他变量相同。如果您打算在调用时在多个方法中创建它,那么创建全局内存存储分配将更有效。由于Memstorage是指向存储变

我用包装纸包装

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

要创建等高线,我使用以下方法:

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

而且
memStorage
应该被显式释放吗?

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

谢天谢地,垃圾收集器非常高效,当您退出收集Memstorage的方法时,它占用的资源将在需要时或当您的程序不执行任何操作时重新分配。您可以通过将Memstorage变量设置为null并调用
GB.Collect()
方法来告诉垃圾收集器手动执行此操作,当然这取决于Memstorage类是否可为null

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

在你的问题的具体答案中,你应该考虑使用<代码>使用语句,以确保MeMeStices被正确释放,但是只有当该方法被调用时有足够的中断。如果要在for循环中顺序调用此方法,则应将MemStorage声明为类中的全局变量,然后在调用垃圾收集器之前,尽可能在类的IDisposable方法中使其为null。循环完成后,可以调用类的dispose方法来有效地重新分配资源。如果你想知道这方面的例子,请让我知道,我会相应地更新我的答案

使用
和MemStorage的
示例:
private Image bwareaopen(图像输入\图像,int阈值)
{
Image bwresults=Input_Image.Copy();
使用(MemStorage=newmemstorage())
{
对于(等高线=输入\图像.Convert().FindContours(Emgu.CvEnum.CHAIN\ u近似\方法.CV\ u CHAIN\ u近似\简单,Emgu.CvEnum.RETR\ u TYPE.CV\ u RETR\ u列表,存储);等高线!=null;等高线=等高线.HNext)
{
轮廓电流轮廓=轮廓.近似多边形(轮廓.周长*0.05,存储);
if(当前轮廓面积<阈值)
{
对于(int i=currentContour.BoundingRectangle.X;i
openCV代码在这里可用 所有的功劳都归于M.Klien在matlab中转换方法

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

我希望这有助于回答您的问题

干杯

克里斯

MemStorage memStorage = new MemStorage();
Contour<PointF> contour = new Contour<PointF>(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;
}