Zobacz moją odpowiedź tutaj odniesienie Emgu Capture plays video super fast
Ale to czynili, jak pytasz Użyłem listę do przechowywania obrazów można wykorzystać tablicę ale trzeba wiedzieć, jak duży plik avi jest.
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();
{
}
ten został zaprojektowany, aby umożliwić odtwarzanie pliku wideo w sposób odpowiedzialny za swoje stopy, ale po prostu konwersji można użyć metody Application.Idle równie łatwo, jak to ...
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
}
}
You będzie musiał uważać na koniec błędu pliku, pojawi się błąd. Zawsze możesz użyć instrukcji catch catch, aby uchwycić konkretny błąd, który da, zamiast po prostu przerwać konwersję.
Jeśli używasz macierzy obrazów, będziesz musiał przechodzić przez plik zwiększając liczbę zmiennych i licząc klatki, a następnie utworzyć tablicę obrazów przed konwersją pliku wideo do tablicy.
[EDIT]
Zgodnie z wnioskiem jest to wersja metody pobierania wszystkie klatki z pliku wideo nie testowałem to na duży plik wideo jako Spodziewam się, że program będzie katastrofy, ponieważ będzie wymagało dużo pamięci.
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;
}
Alternatywnie Zdaję sobie sprawę, może chcesz rekordu powiedzmy 10 sekund wideo z kamery internetowej, więc ta metoda będzie zrobić, użyłem Stoper jako pętli while zabrania używania czasomierz chyba, że wielu nawlekania aplikacja
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;
}
a to nazwać tak:
List<Image<Bgr, Byte>> Image_Array = GetVideoFrames(10000); //10 Secounds
Nadzieja to pomaga,
Cheers,
Chris
Dzięki, po prostu nie chcę go używać w 'Application.Idle'. Po prostu chcę mieć funkcję, którą mogę wywołać, kiedy tylko zechcę, i zwraca mi listę klatek Image z danego wejścia wideo. –
tom
Witam Dodałem do kodu w metodzie, że mógłbyś zadzwonić, mam nadzieję, że to jest to, co twoi po, jeśli nie dajcie mi znać Wiwaty – Chris
@Chris możecie pomóc mi http://stackoverflow.com/questions/31259051/detect -hand-from-web-camera-emgu-cv – gihansalith