Emgu CV从video文件中获取所有帧

我想请你帮我用Emgu CV从video文件中获取所有帧。 我知道我可以使用Capture类及其QueryFrame()方法,但这只返回一帧。 获取所有帧的最简单方法是什么? (并将其保存为例如Image[] )我需要所有帧进行更多处理(更具体地说:video摘要的关键帧提取)。

非常感谢你的帮助。

请参阅我的答案以供参考Emgu Capture以超快速播放video

但这应该是你要求我已经使用一个列表来存储你可以使用数组的图像,但你需要知道你的avi文件有多大。

 Timer My_Time = new Timer(); int FPS = 30; List> image_array = new List>(); Capture _capture; public Form1() { InitializeComponent(); //Frame Rate My_Timer.Interval = 1000 / FPS; My_Timer.Tick += new EventHandler(My_Timer_Tick); My_Timer.Start() _capture = new Capture("test.avi"); } private void My_Timer_Tick(object sender, EventArgs e) { Image frame = _capture.QueryFrame(); if (frame != null) { imageBox.Image = _capture.QueryFrame(); image_array.Add(_capture.QueryFrame().Copy()); } else { My_Timer.Stop(); { } 

这是为了允许以负责任的速度播放video文件而设计,但是只需转换即可使用Application.Idle方法,就像这样容易…

 List> image_array = new List>(); Capture _capture; public Form1() { InitializeComponent(); //Frame Rate _capture = new Capture("test.avi"); Application.Idle += ProcessFrame; } private void ProcessFrame(object sender, EventArgs arg) { Image frame = _capture.QueryFrame(); if (frame != null) { image_array.Add(frame.Copy()); } else { Application.Idle -= ProcessFrame;// treat as end of file } } 

您将不得不小心文件错误的结束,您将收到错误。 您总是可以使用try catch语句来捕获它将提供的特定错误,而不是简单地终止转换。

如果您使用图像arrays,则必须循环文件递增变量并计算帧,然后在将video文件转换为数组之前创建图像arrays。


[编辑]

根据要求,这是从video文件中检索所有帧的方法版本我还没有在大型video文件上对此进行测试,因为我预计该程序会崩溃,因为它需要大量内存。

  private List> GetVideoFrames(String Filename) { List> image_array = new List>(); Capture _capture = new Capture(Filename); bool Reading = true; while (Reading) { Image frame = _capture.QueryFrame(); if (frame != null) { image_array.Add(frame.Copy()); } else { Reading = false; } } return image_array; } 

或者我意识到你可能希望从网络摄像头录制10秒的video,所以这种方法会这样做,我使用秒表作为while循环禁止使用计时器,除非你的multithreading应用程序

  private List> GetVideoFrames(int Time_millisecounds) { List> image_array = new List>(); System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch(); bool Reading = true; Capture _capture = new Capture(); SW.Start(); while (Reading) { Image frame = _capture.QueryFrame(); if (frame != null) { image_array.Add(frame.Copy()); if (SW.ElapsedMilliseconds >= Time_millisecounds) Reading = false; } else { Reading = false; } } return image_array; } 

这将被称为这样:

 List> Image_Array = GetVideoFrames(10000); //10 Secounds 

希望这可以帮助,

干杯,

克里斯

即使我面临同样的问题。所以我初始化了另一个计时器,并在那里提供了video保存代码。只有当点击记录按钮[点击记录video的表格上的按钮]时才启用此计时器。现在我可以捕获video但音频未被录制。