Click here to Skip to main content
15,887,394 members
Articles / Multimedia / GDI+

C# Application to Create and Recognize Mouse Gestures (.NET)

Rate me:
Please Sign up or sign in to vote.
4.82/5 (39 votes)
17 Mar 2008CPOL5 min read 221.5K   8.1K   144  
This program can create and recognize mouse gestures.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;

namespace MouseGesture
{
	#region HiddenType enum
	//L'enumeratore serve per identificare se si vuole creare una rete con un numero
	//di default di neuroni o con un numero ben preciso di neuroni
	public enum HiddenType
	{
		Default,
		Fixed
	}
	#endregion

	#region NetTrainingForm class
	public class NetTrainingForm : System.Windows.Forms.Form
	{
		#region Visual objects
		private System.Windows.Forms.Label LearningRateLabel;
		private System.Windows.Forms.Label MaxErrorLabel;
		private System.Windows.Forms.Label MomentumLabel;
		private System.Windows.Forms.NumericUpDown LerningRateNumber;
		private System.Windows.Forms.NumericUpDown MomentumNumber;
		private System.Windows.Forms.NumericUpDown MaxErrorNumber;
		private System.Windows.Forms.Button Done;
		private System.Windows.Forms.Button Cancel;
		private System.ComponentModel.Container components = null;
		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.RadioButton HiddenFixed;
		private System.Windows.Forms.RadioButton HiddenFixedDefault;
		private System.Windows.Forms.NumericUpDown HiddenFixedNumber;
		private System.Windows.Forms.NumericUpDown EpochsNumber;
		private System.Windows.Forms.Label EpochsLabel;
		#endregion

		#region Private members
		private double m_LearningRate;
		private double m_Momentum;
		private double m_MaxError;
		private MainBoard m_MainBoard;
		private int m_GestureIndex;
		private int m_HiddenNeurons;
		private HiddenType m_HiddenType=HiddenType.Default;
		private int m_Epochs;
		private Pattern[] m_Patterns;
		private System.Windows.Forms.CheckBox OnlyUntrainedCheck;
		private System.Windows.Forms.CheckBox SaveOnFinishedCheck;
		private System.Windows.Forms.CheckBox UseLoadedCheck;
		private int[] m_Indexes;
		#endregion
		
		#region Events and delegates
		//L'evento viene invocato appena viene addestrata una gesture
		public delegate void GestureTrainedDelegate();
		public event GestureTrainedDelegate GestureTrained;
		#endregion

		#region Contructor
		public NetTrainingForm(MainBoard board, int[] GesturesIndexes)
		{
			this.m_Indexes=GesturesIndexes;	//Vettore degli indici delle gesture con training set
			this.m_MainBoard=board;
			this.InitializeComponent();
			this.LinkHandlers();
		}
		#endregion

		#region Dispose function
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		#endregion

		#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()
		{
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(NetTrainingForm));
			this.LearningRateLabel = new System.Windows.Forms.Label();
			this.MaxErrorLabel = new System.Windows.Forms.Label();
			this.MomentumLabel = new System.Windows.Forms.Label();
			this.LerningRateNumber = new System.Windows.Forms.NumericUpDown();
			this.MomentumNumber = new System.Windows.Forms.NumericUpDown();
			this.MaxErrorNumber = new System.Windows.Forms.NumericUpDown();
			this.Done = new System.Windows.Forms.Button();
			this.Cancel = new System.Windows.Forms.Button();
			this.groupBox1 = new System.Windows.Forms.GroupBox();
			this.HiddenFixedDefault = new System.Windows.Forms.RadioButton();
			this.HiddenFixed = new System.Windows.Forms.RadioButton();
			this.HiddenFixedNumber = new System.Windows.Forms.NumericUpDown();
			this.EpochsNumber = new System.Windows.Forms.NumericUpDown();
			this.EpochsLabel = new System.Windows.Forms.Label();
			this.OnlyUntrainedCheck = new System.Windows.Forms.CheckBox();
			this.SaveOnFinishedCheck = new System.Windows.Forms.CheckBox();
			this.UseLoadedCheck = new System.Windows.Forms.CheckBox();
			((System.ComponentModel.ISupportInitialize)(this.LerningRateNumber)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.MomentumNumber)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.MaxErrorNumber)).BeginInit();
			this.groupBox1.SuspendLayout();
			((System.ComponentModel.ISupportInitialize)(this.HiddenFixedNumber)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.EpochsNumber)).BeginInit();
			this.SuspendLayout();
			// 
			// LearningRateLabel
			// 
			this.LearningRateLabel.Location = new System.Drawing.Point(8, 10);
			this.LearningRateLabel.Name = "LearningRateLabel";
			this.LearningRateLabel.Size = new System.Drawing.Size(80, 17);
			this.LearningRateLabel.TabIndex = 0;
			this.LearningRateLabel.Text = "Learning rate:";
			// 
			// MaxErrorLabel
			// 
			this.MaxErrorLabel.Location = new System.Drawing.Point(184, 8);
			this.MaxErrorLabel.Name = "MaxErrorLabel";
			this.MaxErrorLabel.Size = new System.Drawing.Size(56, 17);
			this.MaxErrorLabel.TabIndex = 3;
			this.MaxErrorLabel.Text = "Max error:";
			// 
			// MomentumLabel
			// 
			this.MomentumLabel.Location = new System.Drawing.Point(8, 42);
			this.MomentumLabel.Name = "MomentumLabel";
			this.MomentumLabel.Size = new System.Drawing.Size(80, 17);
			this.MomentumLabel.TabIndex = 4;
			this.MomentumLabel.Text = "Momentum:";
			// 
			// LerningRateNumber
			// 
			this.LerningRateNumber.DecimalPlaces = 4;
			this.LerningRateNumber.Increment = new System.Decimal(new int[] {
																				1,
																				0,
																				0,
																				262144});
			this.LerningRateNumber.Location = new System.Drawing.Point(88, 8);
			this.LerningRateNumber.Maximum = new System.Decimal(new int[] {
																			  1,
																			  0,
																			  0,
																			  0});
			this.LerningRateNumber.Minimum = new System.Decimal(new int[] {
																			  1,
																			  0,
																			  0,
																			  262144});
			this.LerningRateNumber.Name = "LerningRateNumber";
			this.LerningRateNumber.Size = new System.Drawing.Size(72, 20);
			this.LerningRateNumber.TabIndex = 1;
			this.LerningRateNumber.Value = new System.Decimal(new int[] {
																			5,
																			0,
																			0,
																			65536});
			// 
			// MomentumNumber
			// 
			this.MomentumNumber.DecimalPlaces = 4;
			this.MomentumNumber.Increment = new System.Decimal(new int[] {
																			 1,
																			 0,
																			 0,
																			 262144});
			this.MomentumNumber.Location = new System.Drawing.Point(88, 40);
			this.MomentumNumber.Maximum = new System.Decimal(new int[] {
																		   1,
																		   0,
																		   0,
																		   0});
			this.MomentumNumber.Minimum = new System.Decimal(new int[] {
																		   1,
																		   0,
																		   0,
																		   262144});
			this.MomentumNumber.Name = "MomentumNumber";
			this.MomentumNumber.Size = new System.Drawing.Size(72, 20);
			this.MomentumNumber.TabIndex = 3;
			this.MomentumNumber.Value = new System.Decimal(new int[] {
																		 5000,
																		 0,
																		 0,
																		 262144});
			// 
			// MaxErrorNumber
			// 
			this.MaxErrorNumber.DecimalPlaces = 4;
			this.MaxErrorNumber.Increment = new System.Decimal(new int[] {
																			 1,
																			 0,
																			 0,
																			 262144});
			this.MaxErrorNumber.Location = new System.Drawing.Point(240, 8);
			this.MaxErrorNumber.Maximum = new System.Decimal(new int[] {
																		   1,
																		   0,
																		   0,
																		   0});
			this.MaxErrorNumber.Minimum = new System.Decimal(new int[] {
																		   1,
																		   0,
																		   0,
																		   262144});
			this.MaxErrorNumber.Name = "MaxErrorNumber";
			this.MaxErrorNumber.Size = new System.Drawing.Size(72, 20);
			this.MaxErrorNumber.TabIndex = 2;
			this.MaxErrorNumber.Value = new System.Decimal(new int[] {
																		 1,
																		 0,
																		 0,
																		 196608});
			// 
			// Done
			// 
			this.Done.Location = new System.Drawing.Point(232, 232);
			this.Done.Name = "Done";
			this.Done.Size = new System.Drawing.Size(80, 24);
			this.Done.TabIndex = 0;
			this.Done.Text = "&Train";
			// 
			// Cancel
			// 
			this.Cancel.Location = new System.Drawing.Point(8, 232);
			this.Cancel.Name = "Cancel";
			this.Cancel.Size = new System.Drawing.Size(80, 24);
			this.Cancel.TabIndex = 10;
			this.Cancel.Text = "&Cancel";
			this.Cancel.Click += new System.EventHandler(this.OnCancel);
			// 
			// groupBox1
			// 
			this.groupBox1.Controls.Add(this.HiddenFixedDefault);
			this.groupBox1.Controls.Add(this.HiddenFixed);
			this.groupBox1.Controls.Add(this.HiddenFixedNumber);
			this.groupBox1.Location = new System.Drawing.Point(8, 72);
			this.groupBox1.Name = "groupBox1";
			this.groupBox1.Size = new System.Drawing.Size(304, 72);
			this.groupBox1.TabIndex = 11;
			this.groupBox1.TabStop = false;
			this.groupBox1.Text = "Hidden neurons:";
			// 
			// HiddenFixedDefault
			// 
			this.HiddenFixedDefault.Checked = true;
			this.HiddenFixedDefault.Location = new System.Drawing.Point(16, 16);
			this.HiddenFixedDefault.Name = "HiddenFixedDefault";
			this.HiddenFixedDefault.Size = new System.Drawing.Size(144, 24);
			this.HiddenFixedDefault.TabIndex = 5;
			this.HiddenFixedDefault.TabStop = true;
			this.HiddenFixedDefault.Text = "Default hidden neurons";
			this.HiddenFixedDefault.CheckedChanged += new System.EventHandler(this.OnHiddenFixedDefaultChanged);
			// 
			// HiddenFixed
			// 
			this.HiddenFixed.Location = new System.Drawing.Point(16, 40);
			this.HiddenFixed.Name = "HiddenFixed";
			this.HiddenFixed.Size = new System.Drawing.Size(136, 24);
			this.HiddenFixed.TabIndex = 6;
			this.HiddenFixed.Text = "Fixed hidden neurons";
			this.HiddenFixed.CheckedChanged += new System.EventHandler(this.OnHiddenFixedChanged);
			// 
			// HiddenFixedNumber
			// 
			this.HiddenFixedNumber.Enabled = false;
			this.HiddenFixedNumber.Location = new System.Drawing.Point(160, 40);
			this.HiddenFixedNumber.Maximum = new System.Decimal(new int[] {
																			  1000,
																			  0,
																			  0,
																			  0});
			this.HiddenFixedNumber.Minimum = new System.Decimal(new int[] {
																			  1,
																			  0,
																			  0,
																			  0});
			this.HiddenFixedNumber.Name = "HiddenFixedNumber";
			this.HiddenFixedNumber.Size = new System.Drawing.Size(48, 20);
			this.HiddenFixedNumber.TabIndex = 7;
			this.HiddenFixedNumber.Value = new System.Decimal(new int[] {
																			1,
																			0,
																			0,
																			0});
			// 
			// EpochsNumber
			// 
			this.EpochsNumber.Location = new System.Drawing.Point(240, 40);
			this.EpochsNumber.Maximum = new System.Decimal(new int[] {
																		 100000,
																		 0,
																		 0,
																		 0});
			this.EpochsNumber.Minimum = new System.Decimal(new int[] {
																		 1,
																		 0,
																		 0,
																		 0});
			this.EpochsNumber.Name = "EpochsNumber";
			this.EpochsNumber.Size = new System.Drawing.Size(72, 20);
			this.EpochsNumber.TabIndex = 4;
			this.EpochsNumber.Value = new System.Decimal(new int[] {
																	   1,
																	   0,
																	   0,
																	   0});
			// 
			// EpochsLabel
			// 
			this.EpochsLabel.Location = new System.Drawing.Point(184, 40);
			this.EpochsLabel.Name = "EpochsLabel";
			this.EpochsLabel.Size = new System.Drawing.Size(48, 17);
			this.EpochsLabel.TabIndex = 12;
			this.EpochsLabel.Text = "Epochs:";
			// 
			// OnlyUntrainedCheck
			// 
			this.OnlyUntrainedCheck.Location = new System.Drawing.Point(8, 152);
			this.OnlyUntrainedCheck.Name = "OnlyUntrainedCheck";
			this.OnlyUntrainedCheck.Size = new System.Drawing.Size(296, 16);
			this.OnlyUntrainedCheck.TabIndex = 8;
			this.OnlyUntrainedCheck.Text = "Train only untrained gestures";
			// 
			// SaveOnFinishedCheck
			// 
			this.SaveOnFinishedCheck.Location = new System.Drawing.Point(8, 176);
			this.SaveOnFinishedCheck.Name = "SaveOnFinishedCheck";
			this.SaveOnFinishedCheck.Size = new System.Drawing.Size(296, 16);
			this.SaveOnFinishedCheck.TabIndex = 9;
			this.SaveOnFinishedCheck.Text = "Save net at the end of the training process";
			// 
			// UseLoadedCheck
			// 
			this.UseLoadedCheck.Location = new System.Drawing.Point(8, 200);
			this.UseLoadedCheck.Name = "UseLoadedCheck";
			this.UseLoadedCheck.Size = new System.Drawing.Size(296, 16);
			this.UseLoadedCheck.TabIndex = 13;
			this.UseLoadedCheck.Text = "Use loaded values (if available)";
			// 
			// NetTrainingForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(322, 264);
			this.Controls.Add(this.UseLoadedCheck);
			this.Controls.Add(this.SaveOnFinishedCheck);
			this.Controls.Add(this.OnlyUntrainedCheck);
			this.Controls.Add(this.EpochsNumber);
			this.Controls.Add(this.EpochsLabel);
			this.Controls.Add(this.groupBox1);
			this.Controls.Add(this.Cancel);
			this.Controls.Add(this.Done);
			this.Controls.Add(this.MaxErrorNumber);
			this.Controls.Add(this.MomentumNumber);
			this.Controls.Add(this.LerningRateNumber);
			this.Controls.Add(this.MomentumLabel);
			this.Controls.Add(this.MaxErrorLabel);
			this.Controls.Add(this.LearningRateLabel);
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.MaximizeBox = false;
			this.MinimizeBox = false;
			this.Name = "NetTrainingForm";
			this.ShowInTaskbar = false;
			this.Text = "Training parameters";
			((System.ComponentModel.ISupportInitialize)(this.LerningRateNumber)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.MomentumNumber)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.MaxErrorNumber)).EndInit();
			this.groupBox1.ResumeLayout(false);
			((System.ComponentModel.ISupportInitialize)(this.HiddenFixedNumber)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.EpochsNumber)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion

		#region Linking handlers
		//La funzione collega gli eventi ai relativi handlers
		private void LinkHandlers()
		{
			this.Done.Click+=new EventHandler(OnDone);
			this.GestureTrained+=new GestureTrainedDelegate( this.m_MainBoard.OnGestureTrained);
			this.Closed+=new EventHandler(this.OnClose);
		}
		#endregion

		#region Event Handlers
		
		#region OnDone handler
		//La funzione da inizio al training della funzione
		private void OnDone(object sender, EventArgs e)
		{
			//Caricogli input impostati dall'utente
			this.m_LearningRate=(double)this.LerningRateNumber.Value;
			this.m_Momentum=(double)this.MomentumNumber.Value;
			this.m_MaxError=(double)this.MaxErrorNumber.Value;
			this.m_Epochs=(int)this.EpochsNumber.Value;
			if(this.m_HiddenType==HiddenType.Fixed)
				this.m_HiddenNeurons=(int)(this.HiddenFixedNumber.Value);
			else
				this.m_HiddenNeurons=-1;

			this.Enabled=false;
			this.Visible=false;
			//Do inizio al thread di training
			Thread TrainTread=new Thread(new ThreadStart(this.StartBatchTraining));
			TrainTread.Start();
		}
		#endregion

		#region OnCancel handler
		private void OnCancel(object sender, System.EventArgs e)
		{
			this.Close();
		}
		#endregion
		
		#region OnHiddenFixedDefaultChanged handler
		//La funzione aggiorna la modalit� di generazione dei neuroni in default
		private void OnHiddenFixedDefaultChanged(object sender, System.EventArgs e)
		{
			if(this.HiddenFixedDefault.Checked)
			{
				this.m_HiddenType=HiddenType.Default;
				this.HiddenFixedNumber.Enabled=false;
			}
		}
		#endregion

		#region OnHiddenFixedChanged handler
		//La funzione aggiorna la modalit� di generazione dei neuroni in fixed
		private void OnHiddenFixedChanged(object sender, System.EventArgs e)
		{
			if(this.HiddenFixed.Checked)
			{
				this.m_HiddenType=HiddenType.Fixed;
				this.HiddenFixedNumber.Enabled=true;
			}
		}
		#endregion

		#region OnClose handler
		private void OnClose(object obj, EventArgs e)
		{
			this.m_MainBoard.ShowMessageToBar("Training form: closed",MessageType.Normal);
		}
		#endregion

		#endregion

		#region Training functions
		
		#region Batch training start function
		//La funzione esegue il training su tutte le gestures con training set
		private void StartBatchTraining()
		{
			int Trained=0;
			//Metto la main board in training mode
			this.m_MainBoard.StartTrainingMode(this.m_Epochs);
			for(int i=0; i<this.m_Indexes.Length; i++)
			{
				//Addestro tutte le gestures, a meno che non si sia scelto di addestrare solo quelle non addestrate
				if(!this.OnlyUntrainedCheck.Checked || !((Gesture)this.m_MainBoard.KnownGestures[this.m_Indexes[i]]).Trained)
				{
					Trained++;
					this.m_GestureIndex=this.m_Indexes[i];
					//Inserisco nel RecognizedPanel la gesture di cui sto facendo il training
					this.m_MainBoard.InsertRecognizedGesture(((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Points);
					//Do inizio al training della rete della gesture
					this.StartLearning();
				}
				if(this.GestureTrained!=null)
					this.GestureTrained();
			}

			if(Trained==0)
				MessageBox.Show("Every gesture is already trained.","Info",MessageBoxButtons.OK,MessageBoxIcon.Information);

			//Termino la fase di training
			this.m_MainBoard.Parent.Enabled=true;
			this.m_MainBoard.EndTrainingMode();
			this.Close();
		}
		#endregion

		#region Start learning on current gesture
		//La funzione esegue effettivamente ilt raining della rete neurale
		private void StartLearning()
		{
			//La variabile conterr� il numero di gestures riconosciute
			double Recognized=0d;
			//La vriabile conterr� l'ultimo errore prodotto dal training della rete
			double LastError=0d;
			//La variabile indica il risultato del dialog box alla fine del ciclo while
			DialogResult result;
			//La variabile si occupa di mantenere lo stato originale della rete, prima di qualunque interventosulla stessa
			MultiLayerPerceptron OldNet=((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net;

			do
			{
				Recognized=0d;
				LastError=0d;

				//Ripulisco la main board dai grafici precedenti
				this.m_MainBoard.ClearError();

				//Popolo il vettore del training set definitivo con ilt raining set della gesture (gli esempi)
				this.m_Patterns=new Pattern[((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).GestureTrainingSet.Length];
				((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).GestureTrainingSet.CopyTo(this.m_Patterns,0);

				//Memorizzo la grandezza del vettore, che � l'inidce del primo non esempio
				int NotExampleIndex=this.m_Patterns.Length;
				//Genero i non esempi per la gesture corrente
				this.GenerateNotExamples();

				//Se sto addestrando una rete gi� addestrata, e l'utente ha scelto di addestrare la rete con i valori usati
				//in precendeza, non ricreo la rete
				if(((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Trained && this.UseLoadedCheck.Checked)
				{
					this.m_MainBoard.ShowMessageToBar("Training \'"+((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Name+"\' net by current values",MessageType.Info);
				}
				else
				{
					//Se la rete non era addestrata, o l'utente ha deciso di uasre i nuovi settaggi, controllo
					//se l'utente abbia specificato o meno il numero di neuroni hidden
					if(this.m_HiddenType==HiddenType.Default)
						((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net=new MultiLayerPerceptron(MainBoard.MaximumFeatures,1d,this.m_LearningRate,this.m_Momentum,this.m_Epochs,this.m_MaxError);
					else
						((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net=new MultiLayerPerceptron(this.m_HiddenNeurons,MainBoard.MaximumFeatures,1d,this.m_LearningRate,this.m_Momentum,this.m_Epochs,this.m_MaxError);
					
					this.m_MainBoard.ShowMessageToBar("Training \'"+((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Name+"\' net by specified values values",MessageType.Info);
				}

				//Imposto il training set della rete
				((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.SetTrainingSet(this.m_Patterns,NotExampleIndex);

				//Creo il delegate alla funzione e collego l'evento all'handler
				MouseGesture.MultiLayerPerceptron.TrainedPatternDelegate Delegate=new MouseGesture.MultiLayerPerceptron.TrainedPatternDelegate(this.m_MainBoard.OnEpochEnded);
				((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.EpochEnded+=Delegate;

				LastError=((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.StartTraining(Gesture.ExtractFeatures(((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Points));

				double expected=0;

				//Dopo aver mandato il pattern, mando l'insieme delle gestures stesse, che rappresenta un
				//insieme di features non utilizzate nel training, applico la funzione di soglia e controllo
				//la percentuale di gestures che � stato in grado di riconoscere correttamente
				for(int g=0; g<this.m_Indexes.Length; g++)
				{
					expected=(this.m_Indexes[g]==this.m_GestureIndex)?(1d):(0d);
					if(Neuron.CheckThreashold(((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.Run(((Gesture)this.m_MainBoard.KnownGestures[this.m_Indexes[g]]).ExtractFeatures()))==expected)
						Recognized++;
				}

				//Rimuovo il delegate alla funzione creato in rpecedenza
				((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net.EpochEnded-=Delegate;
				
				//Calcolo al percentuale di riconoscimento
				Recognized/=(double)this.m_Indexes.Length;

				//Faccio apparire il message box relativo al termine del training, l'utente pu�
				//rispondere 'Yes' per accettare il training e salvare la rete, 'No' per ripetere il
				//training o 'Cancel' per evitare il salvataggio della rete appena creata (quella 
				//salvata rester� quella addestrata in precedenza)
				result=MessageBox.Show("The gesture \'"+((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Name+"\' has been successfully trained (Recognized gestures: "+((double)(Recognized*100d))+"%, Last training error: "+LastError+").\nDo you want to accept this net?\n(Press \'YES\' to accept, \'NO\' to re-train and \'CANCEL\' to ignore this net)","Accept and save net?",MessageBoxButtons.YesNoCancel,MessageBoxIcon.Question);
			}
			while(result==DialogResult.No);

			//Se il risultato � stato 'Yes' salvo la rete
			if(result==DialogResult.Yes)
			{
				((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Trained=true;
				if(this.SaveOnFinishedCheck.Checked)
					((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).SaveGesture(false,true);
			}
			else
			{
				//In caso contrario ripristino lo stato della rete attuale (se era untrained rester� tale)
				((Gesture)this.m_MainBoard.KnownGestures[this.m_GestureIndex]).Net=OldNet;
			}
		}
		#endregion

		#region Not examples generation
		//La funzione si occupa della generazione dei non-esempi
		private void GenerateNotExamples()
		{
			//Il numero di pattern da generare in maniera random � pari alla dimensione del training set di
			//esempi della rete
			int TotRandom=this.m_Patterns.Length;
			//Fisso il numero di pattern da prendere da ogni training set
			//delle altre gestures
			int HowMany=(int)(TotRandom/this.m_MainBoard.KnownGestures.Count);
			HowMany=(HowMany<=0)?(1):(HowMany);
			//Inizializzo l'array del training set
			ArrayList RealTrainingSet=new ArrayList(this.m_Patterns);
            
			for(int i=0; i<this.m_MainBoard.KnownGestures.Count; i++)
			{
				if(i!=this.m_GestureIndex && ((Gesture)this.m_MainBoard.KnownGestures[i]).TrainingSetCreated)
				{
					int TotPerGesture=0;		
					for(int j=0; j<((Gesture)this.m_MainBoard.KnownGestures[i]).GestureTrainingSet.Length && TotPerGesture<HowMany; j++)
					{
						RealTrainingSet.Add(((Gesture)this.m_MainBoard.KnownGestures[i]).GestureTrainingSet[j]);
						TotPerGesture++;
					}
				}
			}

			//Aggiungo tanti contro-esempi random quanti sono i pattern positivi del training set
			for(int j=0; j<TotRandom; j++)
				RealTrainingSet.Add(this.GenerateRandomPattern());
			
			//Converto il training set finale da dinamico a statico (salvando nella variabile membro apposita)
			this.m_Patterns=new Pattern[RealTrainingSet.Count];
			RealTrainingSet.CopyTo(this.m_Patterns);
		}

		#region Random features
		//La funzione genera dei pattern con delle features comprese nell'intervallo [-1,1]
		//Anche se esiste la possibilit� di creare dei pattern simili a quello
		//da riconoscere, il fatto che gli esempi positivi siano pari al training set, rende
		//una tale eventualit� (fortuita) piuttosto ininfluente
		private Pattern GenerateRandomPattern()
		{
			Random r=new Random(DateTime.Now.Millisecond);
			double[] Features=new double[MainBoard.MaximumFeatures];
			for(int i=0; i<MainBoard.MaximumFeatures; i++)
				Features[i]=((double)r.Next(-1000,1001))/1000d;

			return new Pattern(Features);
		}
		#endregion

		#endregion
		
		#endregion
	}
	#endregion
}

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 Code Project Open License (CPOL)


Written By
Software Developer (Senior) Apex s.r.l.
Italy Italy
I got my Computer Science (Engineering) Master's Degree at the Siena University (Italy), but I'm from Rieti (a small town next to Rome).
My hobbies are RPG, MMORGP, programming and 3D graphics.
At the moment I'm employed at Apex s.r.l. (Modena, Italy) as a senior software developer, working for a WPF/WCF project in Rome.

Comments and Discussions