Click here to Skip to main content
15,891,136 members
Articles / Desktop Programming / WPF

Kinect Reception

Rate me:
Please Sign up or sign in to vote.
4.94/5 (34 votes)
12 Jan 2012Ms-PL5 min read 68.7K   2K   80  
TV Screen in the Reception, When nothing happens (no one is in the reception) we can display videos on the screen but when someone enters the frame show him the Kinect Image, and if the user is doing something funny, capture his image and save it.
// Written by Shai Raiten: http://blogs.microsoft.co.il/blogs/shair/

using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using KinectReception.Helpers;
using KinectReception.Managers;
using Microsoft.Research.Kinect.Nui;
using KinectReception.Enums;
using System.Windows.Threading;
using KinectReception.Controls;
using System.ComponentModel;

namespace KinectReception
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private readonly AuthenticManager _authenticManager;
        private DispatcherTimer _idleTimer;
        private DispatcherTimer _seriousTimer;
        private int _fpsCount = 0;
        private KinectSettings _settings;

        private bool _isPlaying = false;
        public bool IsPlaying
        {
            get { return _isPlaying; }
            set
            {
                _isPlaying = value;
                NotifyPropertyChanged("IsPlaying");
                NotifyPropertyChanged("ShowVideo");                
            }
        }

        public bool ShowVideo
        {
            get { return !_isPlaying; }
        }

        public bool ShowindicatorControl
        {
            get { return _seriousTimer.IsEnabled; }
        }

        public MainWindow()
        {
            this.InitializeComponent();

            _authenticManager = new AuthenticManager();
            _authenticManager.IsAuthentic += new AuthenticManager.IsAuthenticHandler(AuthenticManagerIsAuthentic);
            _authenticManager.PropertyChanged += new PropertyChangedEventHandler(AuthenticManagerPropertyChanged);
            
            this.DataContext = this;

            Initialize();
        }

        void AuthenticManagerIsAuthentic(int score, string result)
        {
            _authenticManager.Reset();
            cameraView.TakePicture(KinectImage.Source, score);
           // textBlock1.Text = result; - Debug
        }

        void AuthenticManagerPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if(e.PropertyName.Equals("Score"))
                ScoreProgressBar.Value = _authenticManager.Score;
        }

        #region Timers
        
        public void Initialize()
        {
            _idleTimer = new DispatcherTimer();
            _idleTimer.Interval = Properties.Settings.Default.IdleTimer;
            _idleTimer.Tick -= IdleTimerTick;
            _idleTimer.Tick += new EventHandler(IdleTimerTick);

            _seriousTimer = new DispatcherTimer();
            _seriousTimer.Interval = Properties.Settings.Default.SeriousTimer;
            _seriousTimer.Tick -= SeriousTimerTick;
            _seriousTimer.Tick += new EventHandler(SeriousTimerTick);
        }

        void SeriousTimerTick(object sender, EventArgs e)
        {
            _seriousTimer.Stop();
            NotifyPropertyChanged("ShowindicatorControl");

            if (_fpsCount <= Properties.Settings.Default.SeriousTimer.ToMinFps()) return;

            IsPlaying = true;
            _fpsCount = 0;
            VideoPreview.Source = VideoManager.GetVideo(VideoType.Out);
        }

        void InitializeIdleTimer()
        {
            _idleTimer.Stop();
            _idleTimer.Start();
        }

        void IdleTimerTick(object sender, EventArgs e)
        {
            _idleTimer.Stop();
            IsPlaying = false;
            _fpsCount = 0;
            VideoPreview.Source = VideoManager.GetVideo(VideoType.In);
        }

        #endregion

        private void BtnSettingsClick(object sender, RoutedEventArgs e)
        {
            _settings = new KinectSettings();
            _settings.ShowDialog();
        }

        private void WindowLoaded(object sender, RoutedEventArgs e)
        {
            if (KinectManager.GetInstance.IsInitialize)
            {
                KinectManager.GetInstance.ReInitialize += new KinectManager.InitializeHandler(InstanceReInitialize);
                KinectManager.GetInstance.KinectNui.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(SkeletonFrameReady);
                KinectManager.GetInstance.KinectNui.VideoFrameReady += new EventHandler<ImageFrameReadyEventArgs>(NuiVideoFrameReady);
            }

            VideoPreview.Source = VideoManager.GetVideo(VideoType.In);
            VideoPreview.MediaEnded += new RoutedEventHandler(VideoPreviewMediaEnded);
        }

        //If the user reset the Kinect runtime (from settings), we need to reregister to those events.
        void InstanceReInitialize(object sender)
        {
            KinectManager.GetInstance.KinectNui.SkeletonFrameReady -= SkeletonFrameReady;
            KinectManager.GetInstance.KinectNui.VideoFrameReady -= NuiVideoFrameReady;

            KinectManager.GetInstance.KinectNui.SkeletonFrameReady +=
                new EventHandler<SkeletonFrameReadyEventArgs>(SkeletonFrameReady);
            KinectManager.GetInstance.KinectNui.VideoFrameReady +=
                new EventHandler<ImageFrameReadyEventArgs>(NuiVideoFrameReady);
        }

        void VideoPreviewMediaEnded(object sender, RoutedEventArgs e)
        {
            if (!IsPlaying)
                VideoPreview.Source = VideoManager.GetVideo(VideoType.None);
        }

        void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            if (!IsPlaying && !_seriousTimer.IsEnabled)
            {
                _seriousTimer.Start();
                NotifyPropertyChanged("ShowindicatorControl");
            }
            else if (!IsPlaying)
            {
                _fpsCount++;
                txtCount.Text = _fpsCount.ToString();
            }
            else if (_isPlaying)
            {
                //reset the Idle Time user is still playing
                InitializeIdleTimer();
                //Reset the authentic calculator.
                _authenticManager.Reset();

                foreach (SkeletonData data in e.SkeletonFrame.Skeletons.
                  Where(data => !cameraView.IsWorking))
                {
                  _authenticManager.ChecksForAuthentic(data.Joints);
                }
            }
        }

        private Point GetDisplayPosition(Joint joint)
        {
            float depthX, depthY;
            KinectManager.GetInstance.KinectNui.SkeletonEngine.SkeletonToDepthImage(joint.Position, out depthX, out depthY);
            depthX = Math.Max(0, Math.Min(depthX * 320, 320));  //convert to 320, 240 space
            depthY = Math.Max(0, Math.Min(depthY * 240, 240));  //convert to 320, 240 space
            int colorX, colorY;
            var iv = new ImageViewArea();
            // only ImageResolution.Resolution640x480 is supported at this point
            KinectManager.GetInstance.KinectNui.NuiCamera.GetColorPixelCoordinatesFromDepthPixel(ImageResolution.Resolution640x480, iv, (int)depthX, (int)depthY, (short)0, out colorX, out colorY);

            // map back to skeleton.Width & skeleton.Height
            return new Point((int)(KinectImage.Width * colorX / 640.0 - 30), (int)(KinectImage.Height * colorY / 480 - 30));
        }

        void NuiVideoFrameReady(object sender, ImageFrameReadyEventArgs e)
        {
            if (!IsPlaying) return;

            var planarImage = e.ImageFrame.Image;

            KinectImage.Source = BitmapSource.Create(
                planarImage.Width, planarImage.Height, 96, 96, PixelFormats.Bgr32, null,
                planarImage.Bits, planarImage.Width * planarImage.BytesPerPixel);

        }

        private void WindowClosed(object sender, EventArgs e)
        {
            KinectManager.GetInstance.Close();
        }

        private void WindowKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
                if (MessageBox.Show(Properties.Resources.CloseWindowMessage,
                    Properties.Resources.CloseWindowTitle,
                    MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
                    this.Close();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Architect Sela
Israel Israel
Shai Raiten is VS ALM MVP, currently working for Sela Group as a ALM senior consultant and trainer specializes in Microsoft technologies especially Team System and .NET technology. He is currently consulting in various enterprises in Israel, planning and analysis Load and performance problems using Team System, building Team System customizations and adjusts ALM processes for enterprises. Shai is known as one of the top Team System experts in Israel. He conducts lectures and workshops for developers\QA and enterprises who want to specialize in Team System.

My Blog: http://blogs.microsoft.co.il/blogs/shair/

Comments and Discussions