Für ein Projekt, ich dies tun musste. Was ich getan habe, erfüllt vielleicht nicht alle deine Anforderungen, aber es kann dir eine Idee geben. Zuerst speicherte ich jedes Farbrahmenbild in einem lokalen Laufwerk mit einer sequentiellen Namensgebung. Dann habe ich mit ffmpeg das sequentielle Bild in eine Videodatei umgewandelt, in meinem Fall war es ein mp4-Video, nicht avi.
Um Farbbildrahmen sequenziell zu speichern, können Sie wie unten kodieren,
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);
}
}
}
}
}
Obiges Beispiel speichert die Bilder im JPEG-Format. Wenn Sie es als PNG-Format speichern müssen, verwenden Sie PngBitmapEncoder
.
Jetzt haben wir sequentielle Bilder auf der Festplatte gespeichert. Um diese sequentiellen Bilder in eine Videodatei zu konvertieren, können Sie ffmpeg verwenden. Sie können auch Aforge.net verwenden. Aber ich habe es nie benutzt. In meinem Fall habe ich den ffmpeg.exe
Prozess von meinem C# Programm wie unten genannt.
Process.Start("ffmpeg.exe", "-framerate 10 -i ./img/%d.jpeg -c:v libx264 -r 30 -pix_fmt yuv420p kinect_video.mp4");
Hinweis:
- Machen Sie Ihre Build-Ziel x64. Dies erhöht das Speicherlimit des Programms.
- Ich habe eine grundlegende implementation in Bezug auf diese codiert. Sie können überprüfen, ob Sie möchten.
Hoffe, es hilft :)
wir VideoWriter classs und WriteFrame Funktion in emgucv speichern Video als AVI-Datei, aber diese Funktion nicht Streaming, –
i-Programm entwickeln wollen, die kontinuierlich kinect Farbdaten speichern können Quelle zu Datei auf hart nicht RAM, weil Speicher nicht genug –