/// <summary> /// Uses a collection of HMMs to recognize which action among a corpus of actions was performed /// </summary> /// <param name="action">The motion sequence representing the action</param> /// <returns></returns> public Tuple<string, double> recognizeAction(ActionSequence<HumanSkeleton> action) { // Compute most likely position action double[] likelihoods = new double[positionActionClassifier.Classes]; int cls = positionActionClassifier.Compute(action.toArray(), out likelihoods); double maxPositionLikelihood = likelihoods.Max(); //maxPositionLikelihood = 0; // Compute most likely joint action likelihoods = new double[jointActionClassifier.Classes]; int jointCls = jointActionClassifier.Compute(action.toArray(true), out likelihoods); double maxJointLikelihood = likelihoods.Max(); double maxLikelihood = Math.Max(maxJointLikelihood, maxPositionLikelihood); if (maxLikelihood < 1e-300 || (jointCls == -1 && cls == -1)) { return Tuple.Create("", maxLikelihood); } // And return the one which is more likely among the two if (maxJointLikelihood > maxPositionLikelihood) { return Tuple.Create(jointClasses[jointCls], maxJointLikelihood); } else { return Tuple.Create(positionClasses[cls], maxPositionLikelihood); } }
private void train(List<string> datafiles) { double[][][] sequences = new double[datafiles.Count][][]; // For each file string actName = ""; string dirName = ""; for (int i = 0; i < datafiles.Count; i++) { string fname = datafiles[i]; actName = System.IO.Path.GetFileNameWithoutExtension(fname); dirName = System.IO.Path.GetDirectoryName(fname); // Read the file List<HumanSkeleton> seq = new List<HumanSkeleton>(); using (StreamReader s = new StreamReader(fname)) { while (!s.EndOfStream) { seq.Add(new HumanSkeleton(s.ReadLine())); } } // convert it into an actionSequence of humanskeletons ActionSequence<HumanSkeleton> actSeq = new ActionSequence<HumanSkeleton>(seq); // Convert that actionSequence in to a double[][] bool useJointVals = Util.shouldUseJVals(actName); double[][] trainSeq = actSeq.toArray(useJointVals); // add that to the sequences array sequences[i] = trainSeq; } bool doTrain = true; if (doTrain) { if (datafiles.Count > 0) { //PrincipalComponentAnalysis pca = computePCA(sequences); // train a HMM //double[][][] projSeqs = getProjectedSequences(sequences, pca); HiddenMarkovModel<MultivariateNormalDistribution> hmm = trainHMM(sequences); // save it to filename.hmm //SerializableHmm s = new SerializableHmm(actName, hmm, pca); SerializableHmm s = new SerializableHmm(actName, hmm); s.SaveToDisk(); } } else { SerializableHmm ser = new SerializableHmm("wave right", MODEL_LIB_PATH); HiddenMarkovModel<MultivariateNormalDistribution> hmm = ser.LoadFromDisk(); PrincipalComponentAnalysis pca = ser.getPCA(); foreach (double[][] seq in sequences) { double[,] data = jaggedToMulti(seq); string fn = System.IO.Path.GetRandomFileName(); using (StreamWriter sr = new StreamWriter("Z:/WindowsFolders/Desktop/" + fn)) { for (int i = 0; i < data.GetLength(0); i++) { for (int j = 0; j < data.GetLength(1); j++) { sr.Write(data[i, j] + " "); } sr.WriteLine(); } } //double[][] projSeq = getProjectedSequence(seq, pca); double l = hmm.Evaluate(seq, false); Console.WriteLine("Likelihood: " + l); } } }