2015-06-23 24 views
5

Mam pytanie dotyczące zapisu kolorowego wideo koloru jako strumienia Jak zapisać kolorowe wideo Kinect jako strumień na twardy przez Kinect SDK 2 w WPF? ?Jak zapisać kinect kolor wideo jako strumień na dysku twardym przez Kinect SDK 2 w WPF

czytałem ten link: Save Kinect's color camera video stream in to .avi video

+0

możemy użyć VideoWriter classs i funkcji WriteFrame w emgucv zapisać jako plik wideo AVI, ale ta funkcja nie strumieniowe, –

+0

chcę rozwijać program, który może uratować ciągle Kinect danych kolorów źródło do pliku na twardym RAM-ie, bo pamięć za mało –

Odpowiedz

4

Dla projektu, musiałem to zrobić. To, co zrobiłem, może nie spełnić wszystkich twoich wymagań, ale może dać ci pomysł. Najpierw zapisałem każdy obraz klatki koloru na dysku lokalnym z sekwencyjnym nazwaniem. Następnie za pomocą ffmpeg przekonwertowałem sekwencyjny obraz na plik wideo, w moim przypadku było to wideo MP4, a nie AVI.

Aby zapisać kolor ramki obrazu sekwencyjnie, można kodować jak poniżej,

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using Microsoft.Kinect; 
using System.IO; 
using System.Drawing; 
using System.Drawing.Imaging; 

namespace Kinect_Video_Recorder 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     KinectSensor ks; 
     ColorFrameReader cfr; 
     byte[] colorData; 
     ColorImageFormat format; 
     WriteableBitmap wbmp; 
     BitmapSource bmpSource; 
     int imageSerial; 

     public MainWindow() 
     { 
      InitializeComponent(); 
      ks = KinectSensor.GetDefault(); 
      ks.Open(); 
      var fd = ks.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra); 
      uint frameSize = fd.BytesPerPixel * fd.LengthInPixels; 
      colorData = new byte[frameSize]; 
      format = ColorImageFormat.Bgra; 
      imageSerial = 0; 

      cfr = ks.ColorFrameSource.OpenReader(); 
      cfr.FrameArrived += cfr_FrameArrived; 
     } 

     void cfr_FrameArrived(object sender, ColorFrameArrivedEventArgs e) 
     { 
      if (e.FrameReference == null) return; 

      using (ColorFrame cf = e.FrameReference.AcquireFrame()) 
      { 
       if(cf == null) return; 
       cf.CopyConvertedFrameDataToArray(colorData, format); 
       var fd = cf.FrameDescription; 

       // Creating BitmapSource 
       var bytesPerPixel = (PixelFormats.Bgr32.BitsPerPixel)/8; 
       var stride = bytesPerPixel * cf.FrameDescription.Width; 

       bmpSource = BitmapSource.Create(fd.Width, fd.Height, 96.0, 96.0, PixelFormats.Bgr32, null, colorData, stride); 

       // WritableBitmap to show on UI 
       wbmp = new WriteableBitmap(bmpSource); 
       kinectImage.Source = wbmp; 

       // JpegBitmapEncoder to save BitmapSource to file 
       // imageSerial is the serial of the sequential image 
       JpegBitmapEncoder encoder = new JpegBitmapEncoder(); 
       encoder.Frames.Add(BitmapFrame.Create(bmpSource)); 
       using (var fs = new FileStream("./img/" + (imageSerial++) + ".jpeg", FileMode.Create, FileAccess.Write)) 
       { 
        encoder.Save(fs); 
       }  
      } 
     } 
    } 
} 

powyższym przykładzie zapisuje obrazy w formacie JPEG. jeśli chcesz zapisać go jako format png, użyj PngBitmapEncoder.

Teraz zapisaliśmy kolejne obrazy na dysku twardym. Aby przekonwertować te sekwencyjne obrazy do pliku wideo, możesz użyć ffmpeg. Możesz także użyć Aforge.net. Ale nigdy tego nie używałem. W moim przypadku wywołałem proces ffmpeg.exe z mojego programu C#, jak poniżej.

Process.Start("ffmpeg.exe", "-framerate 10 -i ./img/%d.jpeg -c:v libx264 -r 30 -pix_fmt yuv420p kinect_video.mp4");

Uwaga:

  1. Dokonaj docelową Budowa x64. Spowoduje to zwiększenie limitu pamięci programu.
  2. Mam kodowany podstawowy implementation w tej sprawie. Możesz sprawdzić, czy chcesz.

Nadzieja to pomaga :)

+1

Użyłem twojego pomysłu kochany Rafaf Tahsin, twój kod jest powoli, ponieważ ten kod: 'wbmp = new WriteableBitmap (bmpSource);' jeśli usuniesz ten kod i użyjesz 'kinectImage. Source = bmpSource; 'zamiast tego, jest dobry –

+0

jest duży problem i to jest głos, zmieniam moje pytanie: jak nagrywać i zapisywać głosowe i kolorowe wideo jako strumień, w którym są one dopasowane? –

+0

Nie mam pojęcia, jak synchronicznie zapisywać zarówno dźwięk, jak i wideo z poziomu Kinect v2. Chciałbym zasugerować, abyś zadał nowe pytanie w tej sprawie, mam nadzieję, że ktoś ci pomoże. Dzięki –