如何在WPF中通过Kinect SDK 2将kinect彩色视频保存为硬盘上的流

时间:2015-06-23 17:57:47

标签: wpf video stream kinect

我有一个关于将kinect彩色视频保存为流的问题 如何通过KF中的Kinect SDK 2将Kinect的彩色视频保存为硬盘

我读了这个链接:Save Kinect's color camera video stream in to .avi video

1 个答案:

答案 0 :(得分:4)

对于一个项目,我必须这样做。我所做的可能无法满足您的所有要求,但它可能会给您一个想法。起初,我使用顺序命名将每个彩色帧图像保存在本地驱动器中。然后使用ffmpeg我将这些连续图像转换为视频文件,在我的例子中它是mp4视频,而不是avi。

要按顺序保存彩色图像帧,您可以编写如下代码,

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

上面的示例以jpeg格式保存图像。如果您需要将其保存为png格式,请使用Picasso

现在我们已将顺序图像保存在硬盘中。要将这些连续图像转换为视频文件,您可以使用PngBitmapEncoder。您也可以使用ffmpeg。但我从来没有用过它。就我而言,我从我的C#程序中调用了ffmpeg.exe进程,如下所示。

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

注意:

  1. 使您的构建目标x64。这将增加程序的内存限制。
  2. 我已经为此编了一个基本的Aforge.net。您可以查看是否需要。
  3. 希望有所帮助:)