How to save kinect color video as stream on hard disk by Kinect SDK 2 in WPF

后端 未结 1 932
感情败类
感情败类 2020-12-21 05:02

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

相关标签:
1条回答
  • 2020-12-21 05:20

    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 :)

    0 讨论(0)
提交回复
热议问题