См. мой ответ здесь для справки 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();
{
}
Это было разработано, чтобы позволить воспроизведение видеофайла с ответственной скоростью, но поскольку вы просто конвертируете, вы можете использовать метод Application.Idle так же легко, как это...
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
Надеюсь это поможет,
Ваше здоровье,
Крис
person
Chris
schedule
12.12.2011