Emgu CV从视频文件中获取所有帧
本文关键字:获取 文件 CV 视频 Emgu | 更新日期: 2023-09-27 18:17:28
我想请您帮助我使用Emgu CV从视频文件中获取所有帧。我知道我可以使用Capture
类和它的QueryFrame()
方法,但是这只返回一个帧。获得所有的帧最简单的方法是什么?(并保存它,例如Image<Bgr, Byte>[]
)我需要所有帧做一些更多的处理(更具体地说:关键帧提取视频摘要)。
非常感谢你的帮助
参考我的回答Emgu Capture播放视频超快
但是这应该可以满足你的要求,我已经使用列表来存储图像,你可以使用数组,但你需要知道你的avi文件有多大。
Timer My_Time = new Timer();
int FPS = 30;
List<Image<Bgr,Byte>> image_array = new List<Image<Bgr,Byte>>();
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<Bgr, Byte> frame = _capture.QueryFrame();
if (frame != null)
{
imageBox.Image = _capture.QueryFrame();
image_array.Add(_capture.QueryFrame().Copy());
}
else
{
My_Timer.Stop();
{
}
这是为了允许以负责任的速率播放视频文件,但作为您的简单转换,您可以使用应用程序。空闲方法就像这样简单…
List<Image<Bgr,Byte>> image_array = new List<Image<Bgr,Byte>>();
Capture _capture;
public Form1()
{
InitializeComponent();
//Frame Rate
_capture = new Capture("test.avi");
Application.Idle += ProcessFrame;
}
private void ProcessFrame(object sender, EventArgs arg)
{
Image<Bgr, Byte> frame = _capture.QueryFrame();
if (frame != null)
{
image_array.Add(frame.Copy());
}
else
{
Application.Idle -= ProcessFrame;// treat as end of file
}
}
你要小心文件的最后出错你会收到一个错误。您总是可以使用try catch语句来捕获它将给出的特定错误,而不是简单地终止转换。
如果你使用图像数组,你将不得不循环遍历文件,增加变量并计算帧数,然后在将视频文件转换为数组之前创建图像数组。
[编辑]
根据要求,这是一个从视频文件中检索所有帧的方法版本。我没有在大型视频文件上进行测试,因为我预计程序会崩溃,因为它将需要大量内存。
private List<Image<Bgr, Byte>> GetVideoFrames(String Filename)
{
List<Image<Bgr,Byte>> image_array = new List<Image<Bgr,Byte>>();
Capture _capture = new Capture(Filename);
bool Reading = true;
while (Reading)
{
Image<Bgr, Byte> frame = _capture.QueryFrame();
if (frame != null)
{
image_array.Add(frame.Copy());
}
else
{
Reading = false;
}
}
return image_array;
}
或者我意识到你可能希望从网络摄像头记录10秒的视频,所以这个方法可以做到这一点,我使用秒表作为while循环禁止使用计时器,除非你的多线程应用程序
private List<Image<Bgr, Byte>> GetVideoFrames(int Time_millisecounds)
{
List<Image<Bgr,Byte>> image_array = new List<Image<Bgr,Byte>>();
System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
bool Reading = true;
Capture _capture = new Capture();
SW.Start();
while (Reading)
{
Image<Bgr, Byte> 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<Bgr, Byte>> Image_Array = GetVideoFrames(10000); //10 Secounds
希望有帮助,
欢呼,克里斯
我也面临同样的问题。所以我初始化了另一个计时器,并在其中提供了视频保存代码。这个计时器只有在点击录制按钮(表单上用于点击录制视频的按钮)时才会启用。现在我可以捕获视频,但音频没有被记录。