【发布时间】:2017-04-23 01:07:10
【问题描述】:
我已经研究了一段时间,但我仍然找不到问题的根源。
首先,请注意所有视频均为 15 秒,总共 450 帧。框架稍后会调整为 50x50。
使用 EmguCv,我正在使用以下例程来获取视频的所有帧:
public void PopulateAllFrames()
{
int FramesCount = 0;
try
{
FramesCount = (int)capture.GetCaptureProperty(Emgu.CV.CvEnum.CAP_PROP.CV_CAP_PROP_FRAME_COUNT);
for (int i = 0; i < FramesCount; i++)
{
var frame = capture.QueryGrayFrame(); // Error here
var resized = frame.Resize(ImageWidth, ImageHeight, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR);
AllFrames.Add(resized.Copy());
}
capture.Dispose();
GC.Collect();
}
catch (Exception ex)
{ }
}
当我在按钮点击上加载任何视频时,上述工作正常:
private void SelectAVideo_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog OpenFile = new OpenFileDialog();
if (OpenFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
OriginalVideo = new MyVideo(OpenFile.FileName, true);
OriginalVideo.PopulateAllFrames();
}
catch (Exception ex)
{}
}
但当我加载包含 25 个视频的目录时,它对某些视频不起作用。通过的视频每次都是相同的视频,“错误”的视频也每次都是相同的:
private void LoadDirectory_Click(object sender, EventArgs e)
{
try
{
using (var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && fbd.SelectedPath != null)
{
AllVideos = new List<MyVideo>();
AllVideosFileNames = Directory.GetFiles(fbd.SelectedPath).ToList();
for (int i = 0; i < AllVideosFileNames.Count(); i++) // loop the rest of the videos, start from the 5th video and till the end
{
MyVideo CurrentVideo = new MyVideo(AllVideosFileNames[i], false);
CurrentVideo.PopulateAllFrames();
AllVideos.Add(CurrentVideo);
}
}
catch (Exception ex)
{ }
}
每当我点击QueryGrayFrame() 时,我都会收到OutOfMemoryException,每次我执行时都在同一组视频上,即使我只加载了 10 个视频。并且没有模式(意味着错误不会仅在最后 10 个索引上弹出......等)。知道视频真的很小,如果我单独加载这些视频中的任何一个,它都可以正常工作。
我该如何解决这个问题?
【问题讨论】:
-
如果您在处理之前随机化视频列表,是否仍然会发生在相同的视频上?
-
您的
frame变量实现了 IDisposable 但您不处置它。与resized相同。 -
@Evk 我不知道该告诉你什么 :) 一旦我添加了
frame.Dispose()和resized.Dispose()一切都按预期工作! -
由于视频格式使用的压缩算法,视频文件很小。当您拉出所有帧时,您将撤消该压缩并以最原始的格式处理视频。例如,一个 15 秒长、30 fps 的 720p 视频作为一个文件可能只有几兆字节,但将所有图像拉出来,突然间你正在处理 1,244,160,000 字节(1.24 GB)的数据。因此,如果您在使用它们后不
Dispose帧,那么您会将所有这些数据存储在内存中。 -
参考数学:1280 像素宽度 * 720 像素高度 * 每像素 3 个通道 * 15 秒 * 30 帧每秒 = 1,244,160,000 字节(假设每个通道 8 位)。
标签: c# video out-of-memory video-capture emgucv