Véase mi respuesta aquí por referencia Emgu Capture plays video super fast
pero esto debe hacer lo que le pide que he usado una lista para almacenar las imágenes que se pueden utilizar una gran variedad pero se necesita saber el tamaño de su archivo AVI es.
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();
{
}
Este fue diseñado para permitir la reproducción del archivo de vídeo a una velocidad responsable sino simplemente como su conversión se puede utilizar el método Application.Idle tan fácilmente como esto ...
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
}
}
Usted Tendrás que tener cuidado de que al final del error de archivo recibas un error. Siempre puedes usar una declaración try catch para detectar el error específico que dará en lugar de simplemente terminar la conversión.
Si usa una matriz de imágenes tendrá que recorrer el archivo incrementando una variable y contando los cuadros y luego crear la matriz de imágenes antes de convertir el archivo de video a una matriz.
[EDIT]
Como solicitó esta es una versión método de recuperación de todos los fotogramas de un archivo de vídeo no he probado esto en un archivo de vídeo de gran tamaño como espero que el programa se estrellaría desde requerirá mucha memoria.
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;
}
alternativa que se dan cuenta de que puede anotar por ejemplo, 10 segundos de vídeo desde una cámara web por lo que este método va a hacer eso, he usado un cronómetro como el bucle al mismo tiempo que prohíbe el uso de un contador de tiempo a menos que su multi-threading la aplicación
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;
}
y esto se llamaría así:
List<Image<Bgr, Byte>> Image_Array = GetVideoFrames(10000); //10 Secounds
esperanza esto ayuda,
Cheers,
Chris
Gracias, simplemente no quiero usarlo en 'Application.Idle'. Simplemente quiero tener una función a la que pueda llamar siempre que lo desee y me devuelve una lista de fotogramas de Image a partir de una entrada de video determinada. –
tom
Hola, he agregado el código en un método que podrías llamar, espero que esto sea lo que buscas si no me dejas saber Cheers – Chris
@Chris me puedes ayudar http://stackoverflow.com/questions/31259051/detect -hand-from-web-camera-emgu-cv – gihansalith