Click here to Skip to main content
15,896,606 members
Articles / Programming Languages / C#

Laser Gesture Recognition

Rate me:
Please Sign up or sign in to vote.
4.93/5 (84 votes)
9 Jan 20073 min read 323.2K   7.2K   177  
A quick article on setting up a simple, real-time laser gesture recognition application and using it to control Windows Media Player.
// Motion Detector
//
// Copyright � Andrew Kirillov, 2005
// andrew.kirillov@gmail.com
//

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

using videosource;

namespace motion
{
	/// <summary>
	/// Summary description for MainForm
	/// </summary>
	public class MainForm : System.Windows.Forms.Form
	{
		// statistics
		private const int	statLength = 15;
		private int			statIndex = 0, statReady = 0;
		private int[]		statCount = new int[statLength];

        private MotionDetector1 detector = new MotionDetector1();        

		private System.Windows.Forms.MenuItem fileItem;
		private System.Windows.Forms.MenuItem openFileItem;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem exitFileItem;
		private System.Windows.Forms.OpenFileDialog ofd;
		private System.Windows.Forms.MainMenu mainMenu;
		private System.Timers.Timer timer;
		private System.Windows.Forms.StatusBar statusBar;
		private System.Windows.Forms.StatusBarPanel fpsPanel;
		private System.Windows.Forms.Panel panel;
        private motion.CameraWindow cameraWindow;
		private System.Windows.Forms.MenuItem openURLFileItem;
		private System.Windows.Forms.MenuItem openMMSFileItem;
		private System.Windows.Forms.MenuItem openLocalFileItem;
        private System.Windows.Forms.MenuItem openMJEPGFileItem;
		private System.Windows.Forms.MenuItem helpItem;
        private System.Windows.Forms.MenuItem aboutHelpItem;
        private TrackBar thresholdTrackBar;
        private Label label1;
        private Label thresholdLabel;
        private IContainer components;
        private MenuItem wmpMenuItem;
        private MenuItem controlMPlayerWmpItem;

        public int threshold = 220;
        public bool controlWMP = false;

		public MainForm()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
            this.mainMenu = new System.Windows.Forms.MainMenu(this.components);
            this.fileItem = new System.Windows.Forms.MenuItem();
            this.openFileItem = new System.Windows.Forms.MenuItem();
            this.openURLFileItem = new System.Windows.Forms.MenuItem();
            this.openMJEPGFileItem = new System.Windows.Forms.MenuItem();
            this.openMMSFileItem = new System.Windows.Forms.MenuItem();
            this.openLocalFileItem = new System.Windows.Forms.MenuItem();
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.exitFileItem = new System.Windows.Forms.MenuItem();
            this.helpItem = new System.Windows.Forms.MenuItem();
            this.aboutHelpItem = new System.Windows.Forms.MenuItem();
            this.ofd = new System.Windows.Forms.OpenFileDialog();
            this.timer = new System.Timers.Timer();
            this.statusBar = new System.Windows.Forms.StatusBar();
            this.fpsPanel = new System.Windows.Forms.StatusBarPanel();
            this.panel = new System.Windows.Forms.Panel();
            this.thresholdLabel = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
            this.thresholdTrackBar = new System.Windows.Forms.TrackBar();
            this.cameraWindow = new motion.CameraWindow();
            this.wmpMenuItem = new System.Windows.Forms.MenuItem();
            this.controlMPlayerWmpItem = new System.Windows.Forms.MenuItem();
            ((System.ComponentModel.ISupportInitialize)(this.timer)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.fpsPanel)).BeginInit();
            this.panel.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.thresholdTrackBar)).BeginInit();
            this.SuspendLayout();
            // 
            // mainMenu
            // 
            this.mainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.fileItem,
            this.wmpMenuItem,
            this.helpItem});
            // 
            // fileItem
            // 
            this.fileItem.Index = 0;
            this.fileItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.openFileItem,
            this.openURLFileItem,
            this.openMJEPGFileItem,
            this.openMMSFileItem,
            this.openLocalFileItem,
            this.menuItem1,
            this.exitFileItem});
            this.fileItem.Text = "&File";
            // 
            // openFileItem
            // 
            this.openFileItem.Index = 0;
            this.openFileItem.Shortcut = System.Windows.Forms.Shortcut.CtrlO;
            this.openFileItem.Text = "&Open";
            this.openFileItem.Click += new System.EventHandler(this.openFileItem_Click);
            // 
            // openURLFileItem
            // 
            this.openURLFileItem.Index = 1;
            this.openURLFileItem.Text = "Open JPEG &URL";
            this.openURLFileItem.Click += new System.EventHandler(this.openURLFileItem_Click);
            // 
            // openMJEPGFileItem
            // 
            this.openMJEPGFileItem.Index = 2;
            this.openMJEPGFileItem.Text = "Open M&JPEG URL";
            this.openMJEPGFileItem.Click += new System.EventHandler(this.openMJEPGFileItem_Click);
            // 
            // openMMSFileItem
            // 
            this.openMMSFileItem.Index = 3;
            this.openMMSFileItem.Text = "Open &MMS Stream";
            this.openMMSFileItem.Click += new System.EventHandler(this.openMMSFileItem_Click);
            // 
            // openLocalFileItem
            // 
            this.openLocalFileItem.Index = 4;
            this.openLocalFileItem.Text = "Open &Local Device";
            this.openLocalFileItem.Click += new System.EventHandler(this.openLocalFileItem_Click);
            // 
            // menuItem1
            // 
            this.menuItem1.Index = 5;
            this.menuItem1.Text = "-";
            // 
            // exitFileItem
            // 
            this.exitFileItem.Index = 6;
            this.exitFileItem.Text = "E&xit";
            this.exitFileItem.Click += new System.EventHandler(this.exitFileItem_Click);
            // 
            // helpItem
            // 
            this.helpItem.Index = 2;
            this.helpItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.aboutHelpItem});
            this.helpItem.Text = "&Help";
            // 
            // aboutHelpItem
            // 
            this.aboutHelpItem.Index = 0;
            this.aboutHelpItem.Text = "&About";
            this.aboutHelpItem.Click += new System.EventHandler(this.aboutHelpItem_Click);
            // 
            // ofd
            // 
            this.ofd.Filter = "AVI files (*.avi)|*.avi";
            this.ofd.Title = "Open movie";
            // 
            // timer
            // 
            this.timer.Interval = 1000;
            this.timer.SynchronizingObject = this;
            this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
            // 
            // statusBar
            // 
            this.statusBar.Location = new System.Drawing.Point(0, 305);
            this.statusBar.Name = "statusBar";
            this.statusBar.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
            this.fpsPanel});
            this.statusBar.ShowPanels = true;
            this.statusBar.Size = new System.Drawing.Size(325, 22);
            this.statusBar.TabIndex = 1;
            // 
            // fpsPanel
            // 
            this.fpsPanel.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
            this.fpsPanel.Name = "fpsPanel";
            this.fpsPanel.Width = 309;
            // 
            // panel
            // 
            this.panel.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
            this.panel.Controls.Add(this.thresholdLabel);
            this.panel.Controls.Add(this.label1);
            this.panel.Controls.Add(this.thresholdTrackBar);
            this.panel.Controls.Add(this.cameraWindow);
            this.panel.Dock = System.Windows.Forms.DockStyle.Fill;
            this.panel.Location = new System.Drawing.Point(0, 0);
            this.panel.Name = "panel";
            this.panel.Size = new System.Drawing.Size(325, 305);
            this.panel.TabIndex = 2;
            // 
            // thresholdLabel
            // 
            this.thresholdLabel.AutoSize = true;
            this.thresholdLabel.Location = new System.Drawing.Point(199, 243);
            this.thresholdLabel.Name = "thresholdLabel";
            this.thresholdLabel.Size = new System.Drawing.Size(111, 13);
            this.thresholdLabel.TabIndex = 4;
            this.thresholdLabel.Text = "Current threshold: 220";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.BackColor = System.Drawing.Color.Transparent;
            this.label1.Location = new System.Drawing.Point(10, 245);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(105, 13);
            this.label1.TabIndex = 3;
            this.label1.Text = "Brightness threshold:";
            // 
            // thresholdTrackBar
            // 
            this.thresholdTrackBar.Location = new System.Drawing.Point(13, 261);
            this.thresholdTrackBar.Maximum = 255;
            this.thresholdTrackBar.Minimum = 100;
            this.thresholdTrackBar.Name = "thresholdTrackBar";
            this.thresholdTrackBar.Size = new System.Drawing.Size(297, 42);
            this.thresholdTrackBar.SmallChange = 5;
            this.thresholdTrackBar.TabIndex = 2;
            this.thresholdTrackBar.TickFrequency = 5;
            this.thresholdTrackBar.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
            this.thresholdTrackBar.Value = 220;
            this.thresholdTrackBar.Scroll += new System.EventHandler(this.thresholdTrackBar_Scroll);
            // 
            // cameraWindow
            // 
            this.cameraWindow.BackColor = System.Drawing.SystemColors.AppWorkspace;
            this.cameraWindow.Camera = null;
            this.cameraWindow.Location = new System.Drawing.Point(0, 0);
            this.cameraWindow.Name = "cameraWindow";
            this.cameraWindow.Size = new System.Drawing.Size(320, 240);
            this.cameraWindow.TabIndex = 1;
            // 
            // wmpMenuItem
            // 
            this.wmpMenuItem.Index = 1;
            this.wmpMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.controlMPlayerWmpItem});
            this.wmpMenuItem.Text = "&WMP";
            // 
            // controlMPlayerWmpItem
            // 
            this.controlMPlayerWmpItem.Index = 0;
            this.controlMPlayerWmpItem.Text = "Control Media Player";
            this.controlMPlayerWmpItem.Click += new System.EventHandler(this.controlMPlayerWmpItem_Click);
            // 
            // MainForm
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(325, 327);
            this.Controls.Add(this.panel);
            this.Controls.Add(this.statusBar);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.Menu = this.mainMenu;
            this.Name = "MainForm";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Laser Gesture Recognizer";
            this.Closing += new System.ComponentModel.CancelEventHandler(this.MainForm_Closing);
            this.Load += new System.EventHandler(this.MainForm_Load);
            ((System.ComponentModel.ISupportInitialize)(this.timer)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.fpsPanel)).EndInit();
            this.panel.ResumeLayout(false);
            this.panel.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.thresholdTrackBar)).EndInit();
            this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new MainForm());
		}

		// On form closing
		private void MainForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			CloseFile();		
		}

		// Close the main form
		private void exitFileItem_Click(object sender, System.EventArgs e)
		{
			this.Close();
		}

		// On "Help->About"
		private void aboutHelpItem_Click(object sender, System.EventArgs e)
		{
			AboutForm form = new AboutForm();

			form.ShowDialog();
		}

		// Open file
		private void openFileItem_Click(object sender, System.EventArgs e)
		{
			if (ofd.ShowDialog() == DialogResult.OK)
			{
				// create video source
				VideoFileSource fileSource = new VideoFileSource();
				fileSource.VideoSource = ofd.FileName;

				// open it
				OpenVideoSource(fileSource);
			}		
		}

		// Open URL
		private void openURLFileItem_Click(object sender, System.EventArgs e)
		{
			URLForm	form = new URLForm();

			form.Description = "Enter URL of an updating JPEG from a web camera:";
			form.URLs = new string[]
				{
					"http://aleksandriacamk1.it.helsinki.fi/axis-cgi/jpg/image.cgi?resolution=320x240",
					"http://stareat.it.helsinki.fi/axis-cgi/jpg/image.cgi?resolution=320x240",
					"http://194.18.89.220/axis-cgi/jpg/image.cgi?resolution=320x240",
					"http://212.247.228.34/axis-cgi/jpg/image.cgi?resolution=352x240"
				};

			if (form.ShowDialog(this) == DialogResult.OK)
			{
				// create video source
				JPEGSource jpegSource = new JPEGSource();
				jpegSource.VideoSource = form.URL;
                jpegSource.Password = form.Password;
                jpegSource.Login = form.Name;
                jpegSource.PreAuthenticate = form.PreAuthenticate;

				// open it
				OpenVideoSource(jpegSource);
			}
		}

		// Open MJPEG URL
		private void openMJEPGFileItem_Click(object sender, System.EventArgs e)
		{
			URLForm	form = new URLForm();

			form.Description = "Enter URL of an MJPEG video stream:";
			form.URLs = new string[]
				{
					"http://hanselman.dyndns.org:81/mjpeg.cgi",
                    "http://sun.jerseyinsight.com/trafficbeaumont/nph-update.cgi",
					"http://peeper.axisinc.com/nph-manupdate.cgi",
					"http://marc15ter.vac.hu/nphMotionJpeg?Resolution=320x240&Quality=Standard",
					"http://213.200.232.69:8080/axis-cgi/mjpg/video.cgi?resolution=320x240"
				};

			if (form.ShowDialog(this) == DialogResult.OK)
			{
				// create video source
				MJPEGSource mjpegSource = new MJPEGSource();
				mjpegSource.VideoSource = form.URL;
                mjpegSource.Login = form.Login;
                mjpegSource.Password = form.Password;
                mjpegSource.PreAuthenticate = form.PreAuthenticate;
                mjpegSource.AuthWithHomePage = form.AuthWithHomePage;

				// open it
				OpenVideoSource(mjpegSource);
			}
		}

		// Open MMS
		private void openMMSFileItem_Click(object sender, System.EventArgs e)
		{
			MMSForm	form = new MMSForm();

			if (form.ShowDialog(this) == DialogResult.OK)
			{
				// create video source
				VideoStream mmsSource = new VideoStream();
				mmsSource.VideoSource = form.URL;

				// open it
				OpenVideoSource(mmsSource);
			}
		}

		// Open local capture device
		private void openLocalFileItem_Click(object sender, System.EventArgs e)
		{
			CaptureDeviceForm form = new CaptureDeviceForm();

			if (form.ShowDialog(this) == DialogResult.OK)
			{
				// create video source
				CaptureDevice localSource = new CaptureDevice();
				localSource.VideoSource = form.Device;

				// open it
				OpenVideoSource(localSource);
			}
		}

		// Open video source
		private void OpenVideoSource(IVideoSource source)
		{
			// set busy cursor
			this.Cursor = Cursors.WaitCursor;

			// close previous file
			CloseFile();

			// create camera
			Camera camera = new Camera(source, detector);
			// start camera
			camera.Start();

			// attach camera to camera window
			cameraWindow.Camera = camera;

			// reset statistics
			statIndex = statReady = 0;

			// start timer
			timer.Start();

			this.Cursor = Cursors.Default;
		}

		// Close current file
		private void CloseFile()
		{
			Camera	camera = cameraWindow.Camera;

			if (camera != null)
			{
				// detach camera from camera window
				cameraWindow.Camera = null;

				// signal camera to stop
				camera.SignalToStop();
				// wait for the camera
				camera.WaitForStop();

				camera = null;

				if (detector != null)
					detector.Reset();
			}
		}

		// On timer event - gather statistic
		private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
		{
			Camera	camera = cameraWindow.Camera;
		
			if (camera != null)
			{
				// get number of frames for the last second
				statCount[statIndex] = camera.FramesReceived;

				// increment indexes
				if (++statIndex >= statLength)
					statIndex = 0;
				if (statReady < statLength)
					statReady++;

				float	fps = 0;

				// calculate average value
				for (int i = 0; i < statReady; i++)
				{
					fps += statCount[i];
				}
				fps /= statReady;

				statCount[statIndex] = 0;

				fpsPanel.Text = fps.ToString("F2") + " fps";
			}
		}


		// Update motion detector
		private void SetMotionDetector()
		{
			Camera	camera = cameraWindow.Camera;
		
			if (camera != null)
			{
				camera.Lock();
				camera.MotionDetector = detector;

				// reset statistics
				statIndex = statReady = 0;
				camera.Unlock();
			}
		}

        private void thresholdTrackBar_Scroll(object sender, EventArgs e)
        {
            // Update value on the label
            thresholdLabel.Text = "Current threshold: " + thresholdTrackBar.Value.ToString();
            threshold = thresholdTrackBar.Value;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            detector.mForm = this;
        }

        private void controlMPlayerWmpItem_Click(object sender, EventArgs e)
        {
            controlMPlayerWmpItem.Checked = !(controlMPlayerWmpItem.Checked);
            
            if (controlMPlayerWmpItem.Checked == true)
                controlWMP = true;
            else
                controlWMP = false;
        }

	}
}

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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
India India

Comments and Discussions