2011-12-12 30 views
8

Tôi muốn yêu cầu bạn giúp tôi nhận tất cả các khung hình từ tệp video bằng Emgu CV. Tôi biết tôi có thể sử dụng Capture lớp học và phương pháp QueryFrame() của nó, nhưng điều này chỉ trả về một khung. Cách dễ nhất để có được tất cả các khung là gì? (và lưu nó vào ví dụ để Image<Bgr, Byte>[]) Tôi cần tất cả các khung để làm một số chế biến nhiều hơn (cụ thể hơn: khai thác khung chính để tổng kết video).Emgu CV nhận tất cả các khung hình từ tệp video

Cảm ơn rất nhiều sự giúp đỡ của bạn.

Trả lời

13

Xem câu trả lời của tôi ở đây để tham khảo Emgu Capture plays video super fast

Nhưng điều này nên làm như bạn hỏi tôi đã sử dụng một danh sách để lưu trữ các hình ảnh mà bạn có thể sử dụng một mảng nhưng bạn sẽ cần phải biết làm thế nào lớn file avi của bạn.

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

này được thiết kế để cho phép phát lại các tập tin video ở tốc độ trách nhiệm nhưng khi bạn chỉ đơn giản là chuyển đổi bạn có thể sử dụng phương pháp Application.Idle cũng giống như dễ dàng như thế này ...

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 
    } 

} 

Bạn sẽ phải cẩn thận khi kết thúc lỗi tệp, bạn sẽ nhận được lỗi. Bạn luôn có thể sử dụng câu lệnh try catch để nắm bắt lỗi cụ thể mà nó sẽ cung cấp thay vì chỉ đơn giản là chấm dứt chuyển đổi.

Nếu bạn sử dụng để sử dụng mảng hình ảnh, bạn sẽ phải lặp qua tệp tăng biến và đếm khung và sau đó tạo mảng hình ảnh trước khi chuyển đổi tệp video thành mảng.


[EDIT]

Theo yêu cầu này là một phiên bản phương pháp thu hồi tất cả các khung từ một tập tin video tôi đã không kiểm tra này trên một tập tin video lớn như tôi hy vọng rằng chương trình sẽ sụp đổ kể từ nó sẽ đòi hỏi nhiều bộ nhớ.

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

Ngoài ra tôi nhận ra bạn có thể muốn ghi lại nói 10 giây của video từ webcam vì vậy phương pháp này sẽ làm điều đó, tôi đã sử dụng một Stopwatch như vòng lặp trong khi cấm việc sử dụng một bộ đếm thời gian trừ khi đa bạn luồng sự ứng dụng

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

và điều này sẽ được gọi là như thế này:

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

Hope điều này giúp,

Chúc mừng,

Chris

+0

Cảm ơn, tôi chỉ không muốn sử dụng nó trong 'Application.Idle'. Tôi chỉ đơn giản muốn có một chức năng mà tôi có thể gọi bất cứ khi nào tôi muốn và nó trả về cho tôi danh sách các hình ảnh khung hình từ đầu vào video nhất định. – tom

+0

Xin chào Tôi đã thêm vào mã trong một phương pháp mà bạn có thể gọi, tôi hy vọng đây là những gì sau của bạn nếu không cho tôi biết Cheers – Chris

+0

@Chris bạn có thể giúp tôi http://stackoverflow.com/questions/31259051/detect -hand-from-web-camera-emgu-cv – gihansalith

0

Ngay cả khi tôi phải đối mặt với cùng một issue.So i được khởi tạo timer khác và cung cấp video lưu mã trong there.And timer này được kích hoạt chỉ khi nút ghi [ Các nút trên biểu mẫu mà trên nhấp vào ghi lại video] được nhấp. Bây giờ tôi có thể quay video nhưng âm thanh không được ghi lại.

Các vấn đề liên quan