C# 带EmguCV的QueryGrayFrame()上的SystemOutOfMemoryException
我正在使用此例程将视频的所有帧转换为一组帧: 点击:C# 带EmguCV的QueryGrayFrame()上的SystemOutOfMemoryException,c#,out-of-memory,emgucv,C#,Out Of Memory,Emgucv,我正在使用此例程将视频的所有帧转换为一组帧: 点击: private int CompareTwoVideos(string _firstVideoPath, string _secondVideoPath) { Capture _capture; List<Image<Gray, Byte>> FirstALLFrames = new List<Image<Gray, Byte>>(
private int CompareTwoVideos(string _firstVideoPath, string _secondVideoPath)
{
Capture _capture;
List<Image<Gray, Byte>> FirstALLFrames = new List<Image<Gray, Byte>>();
// ..
_capture = new Capture(FirstVideoLocation);
// get all frames
FirstALLFrames = GetAllFrames(_capture);
// do some image processing
// ..
_capture.Dispose();
return 0;
}
private int comparetovideos(string\u firstVideoPath,string\u secondVideoPath)
{
捕获(Capture);;
List FirstALLFrames=新列表();
// ..
_捕获=新捕获(FirstVideoLocation);
//获取所有帧
FirstALLFrames=GetAllFrames(_捕获);
//做一些图像处理
// ..
_capture.Dispose();
返回0;
}
效用函数:
List<Image<Gray, byte>> GetAllFrames(Capture _capture)
{
List<Image<Gray, byte>> AllFrames = new List<Image<Gray, byte>>();
int FramesCount = 0;
try
{
FramesCount = (int)_capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_COUNT);
for (int i = 0; i < FramesCount - 1; i++)
{
AllFrames.Add(_capture.QueryGrayFrame().Resize(ImageWidth, ImageHeight, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR));
}
}
catch (Exception ex)
{
// Error pops here
}
return AllFrames;
}
列出GetAllFrames(捕获)
{
List AllFrames=new List();
int frameScont=0;
尝试
{
FrameScont=(int)_capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP\u PROP.CV\u CAP\u PROP\u FRAME\u COUNT);
对于(int i=0;i
第一次单击时,一切正常
但是,第二次单击时会弹出错误
有什么想法吗?我不是100%确定“第二次单击”是什么意思,但我假设这意味着您可以再次直接运行代码来处理另一个视频 看起来你的列表变得太大了,占用了很多内存(这也是写出来的)。您确实处理了捕获对象,但没有处理列表。因此,列表上可能仍然存在引用,这会阻止系统正确地处理和收集该列表(因此,请确保您没有任何其他对该列表的引用) 此外,替换引用(使用
新列表()
实例)不会立即释放收集,垃圾收集器处理对象需要时间。很可能第二次点击只会导致你的程序占用太多内存,因为它现在在内存中包含了太多完整的视频。您是否监控了应用程序内存使用情况
因此,您可以尝试以下几种方法:
List.Clear()
方法可能会有所帮助,因为它会消除列表中的值。但它不会直接释放已分配的内存。这可能会有帮助,因为垃圾收集可以快速清理列表,尽管我不确定这对您的情况有多有效list=null
确保删除对列表的所有引用。然后通过调用GC.collect()
强制垃圾收集器直接收集垃圾。这将占用资源,因为此时调用收集器可能并不完全合适,但如果性能不是问题,则不应造成问题一旦我将我的行拆分为:
var frame=capture.QueryGrayFrame();var resized=frame.Resize(ImageWidth、ImageHeight、Emgu.CV.CvEnum.INTER.CV\u INTER\u LINEAR);AllFrames.Add(resized.Copy())
和处理
帧
和调整大小
在每次迭代中使用它们之后,该函数就像一个魔咒一样工作。谢谢