我正在使用此例程将视频的所有帧都放入一个帧数组中:
点击:
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;
}
效用函数:
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;
}
第一次点击一切正常。
但是,第二次点击时会弹出错误。
有什么想法吗?
答案 0 :(得分:1)
我不是100%肯定你的意思&#34;第二次点击&#34;但我假设这意味着你再次直接运行代码来处理另一个视频。
似乎你的列表变得很大并占用了大量内存(也写成under Exceptions in the List(T) MSDN documentation)。您确实处置了_capture
对象,但是您没有处置您的列表。因此,列表中仍可能存在引用,以防止它被系统正确处理和收集(因此请确保您没有对列表进行任何其他引用)。
此外,替换引用(使用new List()
实例)不会立即释放集合,并且在垃圾收集器处置对象之前需要一些时间。很可能第二次点击只会导致您的程序使用太多内存,因为它现在在内存中包含太多完整的视频。您是否监控过应用程序内存使用情况?
你可以尝试一些事情:
使用可能有帮助的List.Clear()
方法,因为它消除了列表中的值。但它并没有直接释放分配的内存。这可能会有所帮助,因为垃圾收集可以快速清理列表,虽然我不确定这对你的情况有多大。
通过调用List = null
确保消除对列表的所有引用。然后通过调用GC.Collect()
强制垃圾收集器直接收集垃圾。这将占用资源,因为您可能在某个时刻调用收集器可能不太合适,但特别是如果性能不是问题,这不应该造成问题。
最后,尝试处理每个帧并在处理下一帧之前直接丢弃它。或者尝试批量处理视频(无论什么可能)。这会减轻你的记忆负担。