c#-创建轮廓时谁应该关心MemStorage的重新分配?
作者:互联网
我想创建以某种方式生成轮廓并将其返回的函数.
要创建轮廓,请使用以下代码:
Contour<PointF> contour = new Contour<PointF>(new MemStorage());
谁应该关心MemStorage的重新分配?
我应该执行其他操作还是EmguCV在没有其他代码的情况下正确处理此情况?
还是以下代码正确:
MemStorage memStorage = new MemStorage();
Contour<PointF> contour = new Contour<PointF>(memStorage);
和memStorage应该显式释放?
解决方法:
因此,这是一个很好的问题,我希望存储器的使用(内存)与.Net中的任何其他变量相同.如果打算在调用时通过多种方法创建它,则创建全局内存存储分配会更有效.由于Memstorage是指向存储变量的物理地址的指针,因此最好重写其中的单个变量,然后创建一个新的Memstorage,在该位置必须重新池化和重新分配资源.
值得庆幸的是,垃圾收集器非常高效,当您退出收集Memstorage的方法时,在需要时或您的程序未执行任何操作时,所用资源将重新分配.您总是可以通过将Memstorage变量设置为null并调用GB.Collect()方法来告诉垃圾收集器手动执行此操作,当然,这依赖于Memstorage类是否可为空.
为了确保尽可能有效地处理内存分配,应使用using语句.这将释放Memstrage变量使用的资源.这是我从opencv转换为完成与Matlabs bwareopen相同的示例,其中较小的项目或被压抑.它确实需要工作,但这是在数据抑制方面.同样,using语句仅在不多次访问函数(例如在循环内)时才是好的.
在对问题的特定回答中,您应考虑使用using语句以确保MemStorage正确释放,但这仅应在调用方法有足够的中断的情况下进行.如果要在for循环中依次调用此方法,则应将MemStorage声明为类中的全局变量,然后在可能的情况下,在调用垃圾收集器之前,在类的IDisposable方法中将其设置为null.一旦循环完成,则可以调用该类的dispose方法以有效地重新分配资源.如果您也想要示例,请让我知道,我将相应地更新答案.
和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循环抑制数据应使用轮廓的边界约束而不是边界矩形.一旦我对此进行调整,我将相应地更新代码.
我希望这可以帮助您回答一些问题,
干杯,
克里斯
标签:emgucv,opencv,memory-management,c,net 来源: https://codeday.me/bug/20191202/2085335.html