How to save kinect color video as stream on hard d

2019-01-28 02:54发布

问题:

I have a question about save kinect color video as stream How to save Kinect's color video as stream to hard by Kinect SDK 2 in WPF???

i read this link: Save Kinect's color camera video stream in to .avi video

回答1:

For a project, I had to do this. What I've done may not fulfill all your requirements but it may give you an idea. At first I saved every color frame image in local drive with a sequencial naming. Then with ffmpeg I converted those sequential image to video file, in my case it was mp4 video, not avi.

To save color image frame sequentially, you may code like below,

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

Above example saves the images in jpeg format. if you need to save it as png format use PngBitmapEncoder.

Now we have saved sequential images in hard drive. To convert these sequential images to video file you can use ffmpeg. You can also use Aforge.net. But I've never used it. In my case I called the ffmpeg.exe process from my C# program like below.

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

Note:

  1. Make your Build target x64. This will increase the memory limit of the program.
  2. I've coded a basic implementation regarding this. You can check out if you want.

Hope it helps :)