Emgu CV得到的视频文件的所有帧 [英] Emgu CV get all frames from video file

查看:603
本文介绍了Emgu CV得到的视频文件的所有帧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想请你帮我正从视频文件中使用Emgu CV所有的帧。我知道我可以使用捕获类和 QueryFrame()方法,但这只返回一帧。什么是让所有的帧的最简单的方法? (并保存,例如以图片< BGR,字节> [] )我需要所有的帧做一些更多的处理(更具体:对视频关键帧提取摘要)。

I would like to ask you to help me with getting all the frames from video file using Emgu CV. I know I can use Capture class and its QueryFrame() method, but this only returns one frame. What is the easiest way to get all the frames? (and save it for example to Image<Bgr, Byte>[]) I need all the frames to do some more processing (to be more specific: key frame extraction for video summarization).

非常感谢你的帮助。

推荐答案

见我的答案在这里,以供参考 Emgu捕捉播放视频超快速

See my answer here for reference Emgu Capture plays video super fast

但是,正如你问我用一个列表来存储你可以使用数组的图片,但你需要知道你的AVI文件有多大这是应该做的。

But this should do as you ask I've used a list to store the images you can use an array but you will need to know how big your avi file is.

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();
    {
}

这被设计为允许视频文件的回放一个负责任的速度,但作为简单的转换,你可以很容易地使用Application.Idle方法像这样...

This was designed to allow playback of the video file at a responsible rate but as your simply converting you could use the Application.Idle method just as easily like this...

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语句捕捉特定的错误,它会直接给出简单地终止转换。

You will have to be careful of the end of the file error you will receive an error. You could always use a try catch statement to catch the specific error it will give instead of simply terminating conversion.

如果您使用使用一个图像阵列,你将不得不循环通过文件递增一个变量,计算帧,然后将视频文件转换为一个数组之前创建的图像阵列。

If you use to use an image array you will have to loop through the file incrementing a variable and counting the frames and then create the image array before converting the video file to an array.

按照要求,这是从视频文件中提取的所有帧的方法的版本我没有在一个大的视频测试这文件作为我预计,该计划将崩溃,因为这将需要大量的内存。

As requested this is a method version of retrieving all frames from a video file I have not tested this on a large video file as I expect that the program would crash since it will require a lot of memory.

    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循环禁止使用定时器,除非你的多线程应用程序

Alternatively I realise you may wish to record say 10 seconds of video from a webcam so this method will do that, I used a Stopwatch as the the while loop prohibits the use of a timer unless your multi threading the application

    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;
    }

和本会被称为是这样的:

and this would be called like this:

List<Image<Bgr, Byte>> Image_Array = GetVideoFrames(10000); //10 Secounds






希望这有助于


Hope this helps,

干杯,

克里斯

这篇关于Emgu CV得到的视频文件的所有帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆