Click here to Skip to main content
15,880,427 members
Articles / Desktop Programming / Windows Forms

Hands Gesture Recognition

Rate me:
Please Sign up or sign in to vote.
4.95/5 (112 votes)
22 May 2008GPL314 min read 479K   37.8K   272  
Some ideas about Hands Gesture Recognition in still images and video feeds, using the AForge.NET framework (C#).
// Hands Gesture Recognition Application
//
// Copyright � Andrew Kirillov, 2008
// andrew.kirillov@gmail.com
//

namespace GesturesRecognition
{
	using System;
	using System.Drawing;
	using System.Threading;

    using AForge.Video;
    using AForge.GestureRecognition;

	/// <summary>
	/// Camera class.
	/// </summary>
    /// 
	public class Camera
	{
		private IVideoSource	videoSource = null;
		private Bitmap			lastFrame = null;
        private string          lastVideoSourceError = null;

        private GesturesRecognizerFromVideo gesturesRecognizer = new GesturesRecognizerFromVideo( );

		// image dimension
		private int width = -1;
        private int height = -1;

        private Gesture gesture = new Gesture( );
        private int gestureShowTime = 0;

		// public events
		public event EventHandler NewFrame;
        public event EventHandler VideoSourceError;

        // Last video frame
		public Bitmap LastFrame
		{
			get { return lastFrame; }
		}

        // Last video source error
        public string LastVideoSourceError
        {
            get { return lastVideoSourceError; }
        }

		// Video frame width
		public int Width
		{
			get { return width; }
		}

		// Vodeo frame height
		public int Height
		{
			get { return height; }
		}

		// Frames received from the last access to the property
		public int FramesReceived
		{
			get { return ( videoSource == null ) ? 0 : videoSource.FramesReceived; }
		}

        // Bytes received from the last access to the property
		public int BytesReceived
		{
			get { return ( videoSource == null ) ? 0 : videoSource.BytesReceived; }
		}

		// Running property
		public bool IsRunning
		{
			get { return ( videoSource == null ) ? false : videoSource.IsRunning; }
		}

		// Constructor
        public Camera( IVideoSource source )
		{
			this.videoSource = source;
			videoSource.NewFrame += new NewFrameEventHandler( video_NewFrame );
            videoSource.VideoSourceError += new VideoSourceErrorEventHandler( video_VideoSourceError );

            gesturesRecognizer.GestureDetected += new GestureDetectionEventHandler( recognizer_GestureDetected );
		}

		// Start video source
		public void Start( )
		{
			if ( videoSource != null )
			{
                gestureShowTime = 0;
				videoSource.Start( );
			}
		}

		// Siganl video source to stop
		public void SignalToStop( )
		{
			if ( videoSource != null )
			{
				videoSource.SignalToStop( );
            }
		}

		// Wait video source for stop
		public void WaitForStop( )
		{
			// lock
			Monitor.Enter( this );

			if ( videoSource != null )
			{
				videoSource.WaitForStop( );
			}
			// unlock
			Monitor.Exit( this );
		}

		// Abort camera
		public void Stop( )
		{
			// lock
			Monitor.Enter( this );

			if ( videoSource != null )
			{
				videoSource.Stop( );
			}

			// unlock
			Monitor.Exit( this );
		}

		// Lock it
		public void Lock( )
		{
			Monitor.Enter( this );
		}

		// Unlock it
		public void Unlock( )
		{
			Monitor.Exit( this );
		}

		// On new frame
		private void video_NewFrame( object sender, NewFrameEventArgs e )
		{
			try
			{
				// lock
				Monitor.Enter( this );

				// dispose old frame
				if ( lastFrame != null )
				{
					lastFrame.Dispose( );
				}

                // reset error
                lastVideoSourceError = null;
                // get new frame
				lastFrame = (Bitmap) e.Frame.Clone( );

				// apply gestures recognizer
                gesturesRecognizer.ProcessFrame( ref lastFrame );

                // check if we need to draw gesture information on top of image
                if ( gestureShowTime > 0 )
                {
                    if ( ( gesture.LeftHand != HandPosition.NotRaised ) || ( gesture.RightHand != HandPosition.NotRaised ) )
                    {
                        Graphics g = Graphics.FromImage( lastFrame );

                        string text = string.Format( "Left  = " + gesture.LeftHand + "\nRight = " + gesture.RightHand );
                        
                        Font drawFont = new Font( "Courier", 13, FontStyle.Bold );
                        SolidBrush drawBrush = new SolidBrush( Color.Blue );

                        g.DrawString( text, drawFont, drawBrush, new PointF( 0, 5 ) );

                        drawFont.Dispose( );
                        drawBrush.Dispose( );

                        g.Dispose( );
                    }
                    gestureShowTime--;
                }

                // image dimension
				width = lastFrame.Width;
				height = lastFrame.Height;
            }
			catch ( Exception )
			{
			}
			finally
			{
				// unlock
				Monitor.Exit( this );
			}

			// notify client
			if ( NewFrame != null )
				NewFrame( this, new EventArgs( ) );
		}

        // On video source error
        private void video_VideoSourceError( object sender, VideoSourceErrorEventArgs e )
        {
            // save video source error's description
            lastVideoSourceError = e.Description;

            // notify clients about the error
            if ( VideoSourceError != null )
            {
                VideoSourceError( this, new EventArgs( ) );
            }
        }

        // On gesture recognized
        private void recognizer_GestureDetected( object sender, Gesture gesture )
        {
            this.gesture = gesture;
            gestureShowTime = 15;
        }
	}
}

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 GNU General Public License (GPLv3)


Written By
Software Developer IBM
United Kingdom United Kingdom
Started software development at about 15 years old and it seems like now it lasts most part of my life. Fortunately did not spend too much time with Z80 and BK0010 and switched to 8086 and further. Similar with programming languages – luckily managed to get away from BASIC and Pascal to things like Assembler, C, C++ and then C#. Apart from daily programming for food, do it also for hobby, where mostly enjoy areas like Computer Vision, Robotics and AI. This led to some open source stuff like AForge.NET, Computer Vision Sandbox, cam2web, ANNT, etc.

Comments and Discussions