Adding new Features

Jan 28, 2013 at 9:23 AM
Edited Jan 28, 2013 at 10:00 AM

Thank your Josh for sharing this Solution with us! I used it for my presentations and added two features: lowering the framerate for saving computitional power (thus less heat and less noise while presenting) and added a delay/timeout for how long you have to hold a gestrue to let it be triggered.

The lower framerate was easy to achieve by adding a delay to the kinect FrameReady CallbackHandlers:

//declare variables
DateTime FPSLowering = DateTime.Now;
double Delay = 0.1;

//frame callback handlers
void runtime_VideoFrameReady(object sender, Microsoft.Research.Kinect.Nui.ImageFrameReadyEventArgs e)
{
     if (FPSLowering.AddSeconds(Delay) < DateTime.Now)
     {
          FPSLowering = DateTime.Now;

          //original Code goes here...
      }
}

 

 Of course you will have to do the same with the SkeletonFrameReady handler. Be careful with too huge delays (like 0.5). The detection becomes faulty when using too low FPS. Somehow it didn't track the joint right. :(

 

For implementing a "hold gestrue timeout" I added two bool properties and a timer to the code:

 

 System.Timers.Timer GestureHangInTime = new System.Timers.Timer(1500);
        public bool rightGestrueRecognized
        {
            get { return _righteGesture; }
            set
            {
                if (!_righteGesture & value) { GestureHangInTime.Start(); _righteGesture = value; }
                else if (_righteGesture & !value) 
{
GestureHangInTime.Stop();
//get another full second
GestureHangInTime.Interval = HangInTime;
_righteGesture = value;
}
} } public bool leftGestrueRecognized { get { return _leftGestrue; } set { if (!_leftGestrue & value) { GestureHangInTime.Start(); _leftGestrue = value; } else if (_leftGestrue & !value)
{
GestureHangInTime.Stop();
GestureHangInTime.Interval = HangInTime;
_leftGestrue = value;
} } } bool _righteGesture, _leftGestrue = false;
       static double HangInTime = 1000;

 

As you can see the timer gets started/stopped if the value of a bool was changed. To trigger the state change of the bool properties modify the "ProcessForwardBackGesture" method code as follows:

 

        private void ProcessForwardBackGesture(Joint head, Joint rightHand, Joint leftHand)
        {
            if (rightHand.Position.X > head.Position.X + 0.45)
            {
                if (!isBackGestureActive && !isForwardGestureActive)
                {
                    isForwardGestureActive = true;
                }
                rightGestrueRecognized = true;
            }
            else
            {
                isForwardGestureActive = false;
                rightGestrueRecognized = false;
            }

            if (leftHand.Position.X < head.Position.X - 0.45)
            {
                if (!isBackGestureActive && !isForwardGestureActive)
                {
                    isBackGestureActive = true;
                }
                leftGestrueRecognized = true;
            }
            else
            {
                isBackGestureActive = false;
                leftGestrueRecognized = false;
            }
        }

 

Finally subscribe you application to the timer.Elapsed event and trigger the SendKey.SendWait events:

 

//subscribe for event in class constructor
GestureHangInTime.Elapsed += new System.Timers.ElapsedEventHandler(GestureHangInTime_Elapsed);

//send key in timer.Elapsed event
        void GestureHangInTime_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (rightGestrueRecognized)
            {
                //send key
                System.Windows.Forms.SendKeys.SendWait("{Right}");
                //stop timer
                rightGestrueRecognized = false;
            }
            else if (leftGestrueRecognized)
            {
                System.Windows.Forms.SendKeys.SendWait("{Left}");
                leftGestrueRecognized = false;
            }
        }

 This prevents accidentally switching the slide with a handwipe. If you want another delay for triggering keys, simply change the HangInTime value. I found 1000 ms useful, but thats a matter of taste i think.