Giter Site home page Giter Site logo

kinectimagecapture's Introduction

kinectImageCapture

//------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //------------------------------------------------------------------------------

namespace Microsoft.Samples.Kinect.DepthBasics { using System; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Windows; using System.Windows.Media; using System.Windows.Media.Imaging; using Microsoft.Kinect;

/// <summary>
/// Interaction logic for MainWindow
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
    /// <summary>
    /// Map depth range to byte range
    /// </summary>
    private const int MapDepthToByte = 8000 / 256;
    
    /// <summary>
    /// Active Kinect sensor
    /// </summary>
    private KinectSensor kinectSensor = null;

    /// <summary>
    /// Reader for depth frames
    /// </summary>
    private DepthFrameReader depthFrameReader = null;
    private ColorFrameReader colorFrameReader = null;
    /// <summary>
    /// Description of the data contained in the depth frame
    /// </summary>
    private FrameDescription depthFrameDescription = null;
    private FrameDescription colorFrameDescription = null;

    /// <summary>
    /// Bitmap to display
    /// </summary>
    private WriteableBitmap depthBitmap = null;
    private WriteableBitmap colorBitmap = null;
    /// <summary>
    /// Intermediate storage for frame data converted to color
    /// </summary>
    private byte[] depthPixels = null;

    /// <summary>
    /// Current status text to display
    /// </summary>
    private string statusText = null;

    /// <summary>
    /// Initializes a new instance of the MainWindow class.
    /// </summary>
    public MainWindow()
    {
        // get the kinectSensor object
        this.kinectSensor = KinectSensor.GetDefault();

        // open the reader for the depth frames
        this.depthFrameReader = this.kinectSensor.DepthFrameSource.OpenReader();
        this.colorFrameReader = this.kinectSensor.ColorFrameSource.OpenReader();
        // wire handler for frame arrival
        this.depthFrameReader.FrameArrived += this.Reader_FrameArrived;
        this.colorFrameReader.FrameArrived += this.Reader_ColorFrameArrived;
        // get FrameDescription from DepthFrameSource
        this.depthFrameDescription = this.kinectSensor.DepthFrameSource.FrameDescription;
        FrameDescription colorFrameDescription = this.kinectSensor.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);

        // allocate space to put the pixels being received and converted
        this.depthPixels = new byte[this.depthFrameDescription.Width * this.depthFrameDescription.Height];

        // create the bitmap to display
        this.depthBitmap = new WriteableBitmap(this.depthFrameDescription.Width, this.depthFrameDescription.Height, 96.0, 96.0, PixelFormats.Gray8, null);
        this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
        // set IsAvailableChanged event notifier
        this.kinectSensor.IsAvailableChanged += this.Sensor_IsAvailableChanged;

        // open the sensor
        this.kinectSensor.Open();

        // set the status text
        this.StatusText = this.kinectSensor.IsAvailable ? Properties.Resources.RunningStatusText
                                                        : Properties.Resources.NoSensorStatusText;

        // use the window object as the view model in this simple example
        this.DataContext = this;

        // initialize the components (controls) of the window
        this.InitializeComponent();
    }

    /// <summary>
    /// INotifyPropertyChangedPropertyChanged event to allow window controls to bind to changeable data
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Gets the bitmap to display
    /// </summary>
    public ImageSource ImageSource
    {
        get
        {
            return this.depthBitmap;
        }
    }

    /// <summary>
    /// Gets or sets the current status text to display
    /// </summary>
    public string StatusText
    {
        get
        {
            return this.statusText;
        }

        set
        {
            if (this.statusText != value)
            {
                this.statusText = value;

                // notify any bound elements that the text has changed
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("StatusText"));
                }
            }
        }
    }

    /// <summary>
    /// Execute shutdown tasks
    /// </summary>
    /// <param name="sender">object sending the event</param>
    /// <param name="e">event arguments</param>
    private void MainWindow_Closing(object sender, CancelEventArgs e)
    {
        if (this.depthFrameReader != null)
        {
            // DepthFrameReader is IDisposable
            this.depthFrameReader.Dispose();
            this.depthFrameReader = null;
        }

        if (this.kinectSensor != null)
        {
            this.kinectSensor.Close();
            this.kinectSensor = null;
        }
    }

    /// <summary>
    /// Handles the user clicking on the screenshot button
    /// </summary>
    /// <param name="sender">object sending the event</param>
    /// <param name="e">event arguments</param>
    private void ScreenshotButton_Click(object sender, RoutedEventArgs e)
    {
        if (this.depthBitmap != null)
        {
            // create a png bitmap encoder which knows how to save a .png file
            BitmapEncoder encoder = new PngBitmapEncoder();
            BitmapEncoder encoder1 = new PngBitmapEncoder();
            // create frame from the writable bitmap and add to encoder
            encoder.Frames.Add(BitmapFrame.Create(this.depthBitmap));
            encoder1.Frames.Add(BitmapFrame.Create(this.colorBitmap));
            string time = System.DateTime.UtcNow.ToString("hh'-'mm'-'ss", CultureInfo.CurrentUICulture.DateTimeFormat);

            string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);

            string path = Path.Combine(myPhotos, "KinectScreenshot-Depth-" + time + ".png");
            string path1 = Path.Combine(myPhotos, "KinectScreenshot-Color-" + time + ".png");

            // write the new file to disk
            try
            {
                // FileStream is IDisposable
                using (FileStream fs = new FileStream(path, FileMode.Create))                        
                {
                    encoder.Save(fs);
                }
                 using (FileStream fs1 = new FileStream(path1, FileMode.Create))                        
                {
                    encoder1.Save(fs1);
                }


                this.StatusText = string.Format(CultureInfo.CurrentCulture, Properties.Resources.SavedScreenshotStatusTextFormat, path);
            }
            catch (IOException)
            {
                this.StatusText = string.Format(CultureInfo.CurrentCulture, Properties.Resources.FailedScreenshotStatusTextFormat, path);
            }
        }
    }

    /// <summary>
    /// Handles the depth frame data arriving from the sensor
    /// </summary>
    /// <param name="sender">object sending the event</param>
    /// <param name="e">event arguments</param>
    private void Reader_FrameArrived(object sender, DepthFrameArrivedEventArgs e)
    {
        bool depthFrameProcessed = false;

        using (DepthFrame depthFrame = e.FrameReference.AcquireFrame())
        {
            if (depthFrame != null)
            {
                // the fastest way to process the body index data is to directly access 
                // the underlying buffer
                using (Microsoft.Kinect.KinectBuffer depthBuffer = depthFrame.LockImageBuffer())
                {
                    // verify data and write the color data to the display bitmap
                    if (((this.depthFrameDescription.Width * this.depthFrameDescription.Height) == (depthBuffer.Size / this.depthFrameDescription.BytesPerPixel)) &&
                        (this.depthFrameDescription.Width == this.depthBitmap.PixelWidth) && (this.depthFrameDescription.Height == this.depthBitmap.PixelHeight))
                    {
                        // Note: In order to see the full range of depth (including the less reliable far field depth)
                        // we are setting maxDepth to the extreme potential depth threshold
                        ushort maxDepth = ushort.MaxValue;

                        // If you wish to filter by reliable depth distance, uncomment the following line:
                        //// maxDepth = depthFrame.DepthMaxReliableDistance
                        
                        this.ProcessDepthFrameData(depthBuffer.UnderlyingBuffer, depthBuffer.Size, depthFrame.DepthMinReliableDistance, maxDepth);
                        depthFrameProcessed = true;
                    }
                }
            }
        }

        if (depthFrameProcessed)
        {
            this.RenderDepthPixels();
        }
    }
    private void Reader_ColorFrameArrived(object sender, ColorFrameArrivedEventArgs e)
    {
        // ColorFrame is IDisposable
        using (ColorFrame colorFrame = e.FrameReference.AcquireFrame())
        {
            if (colorFrame != null)
            {
                FrameDescription colorFrameDescription = colorFrame.FrameDescription;

                using (KinectBuffer colorBuffer = colorFrame.LockRawImageBuffer())
                {
                    this.colorBitmap.Lock();

                    // verify data and write the new color frame data to the display bitmap
                    if ((colorFrameDescription.Width == this.colorBitmap.PixelWidth) && (colorFrameDescription.Height == this.colorBitmap.PixelHeight))
                    {
                        colorFrame.CopyConvertedFrameDataToIntPtr(
                            this.colorBitmap.BackBuffer,
                            (uint)(colorFrameDescription.Width * colorFrameDescription.Height * 4),
                            ColorImageFormat.Bgra);

                        this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));
                    }

                    this.colorBitmap.Unlock();
                }
            }
        }
    }
    /// <summary>
    /// Directly accesses the underlying image buffer of the DepthFrame to 
    /// create a displayable bitmap.
    /// This function requires the /unsafe compiler option as we make use of direct
    /// access to the native memory pointed to by the depthFrameData pointer.
    /// </summary>
    /// <param name="depthFrameData">Pointer to the DepthFrame image data</param>
    /// <param name="depthFrameDataSize">Size of the DepthFrame image data</param>
    /// <param name="minDepth">The minimum reliable depth value for the frame</param>
    /// <param name="maxDepth">The maximum reliable depth value for the frame</param>
    private unsafe void ProcessDepthFrameData(IntPtr depthFrameData, uint depthFrameDataSize, ushort minDepth, ushort maxDepth)
    {
        // depth frame data is a 16 bit value
        ushort* frameData = (ushort*)depthFrameData;

        // convert depth to a visual representation
        for (int i = 0; i < (int)(depthFrameDataSize / this.depthFrameDescription.BytesPerPixel); ++i)
        {
            // Get the depth for this pixel
            ushort depth = frameData[i];

            // To convert to a byte, we're mapping the depth value to the byte range.
            // Values outside the reliable depth range are mapped to 0 (black).
            this.depthPixels[i] = (byte)(depth >= minDepth && depth <= maxDepth ? (depth / MapDepthToByte) : 0);
        }
    }

    /// <summary>
    /// Renders color pixels into the writeableBitmap.
    /// </summary>
    private void RenderDepthPixels()
    {
        this.depthBitmap.WritePixels(
            new Int32Rect(0, 0, this.depthBitmap.PixelWidth, this.depthBitmap.PixelHeight),
            this.depthPixels,
            this.depthBitmap.PixelWidth,
            0);
    }

    /// <summary>
    /// Handles the event which the sensor becomes unavailable (E.g. paused, closed, unplugged).
    /// </summary>
    /// <param name="sender">object sending the event</param>
    /// <param name="e">event arguments</param>
    private void Sensor_IsAvailableChanged(object sender, IsAvailableChangedEventArgs e)
    {
        // on failure, set the status text
        this.StatusText = this.kinectSensor.IsAvailable ? Properties.Resources.RunningStatusText
                                                        : Properties.Resources.SensorNotAvailableStatusText;
    }
}

}

kinectimagecapture's People

Contributors

evilwarlock avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.