使用Kinect的c# HMM手势识别

本文关键字:HMM 手势识别 Kinect 使用 | 更新日期: 2023-09-27 18:03:44

我正在研究使用Kinect传感器进行手势识别的解决方案。现在我正在使用Accord . net来训练HMM。我有一个保存手势的数据集。这个数据集有11个手势,每个手势有32帧,保存了18个点。

所以我有一个(double[12][32,18])输入数据集和一个(int[12])输出数据集,但是当我这样做时:双重错误=老师。运行(inputSequences, output),它给我这个:"指定的参数超出了有效值的范围。"

有人知道怎么解决这个问题吗?在hmm教师上使用数据集之前应该对数据集进行处理还是数据集是这样的?

使用Kinect的c# HMM手势识别

我用的是雅阁。它确实是HMM引擎的最佳实现之一。然而,当我训练HMM时,我将HMM参数(即PI, A和B)传递给Baum Welch老师,并使用有组织的excel表格提供输入数据集。(与Accord的作者自己在他的项目中使用的类似)。不知怎的,我觉得既然你把你的数据集存储为一个多维数组,并直接提供给老师,它无法正确处理它。也许你可以一次提供一个手势记录,或者完全改变数据集的存储结构。如果你还没有看过Accord的整个例子,我建议你看一遍,因为它对我来说效果很好。

问题可能是教学算法期望训练序列的形式是 double[12][32][18] ,而不是 double[12][32,18] 。训练数据应该是多变量点序列的集合。还需要注意的是,如果你有11种可能的手势类型,那么int[12]数组中给出的整数标签应该仅由0到10之间的值组成。

因此,如果您有12个手势样本,每个样本包含32帧,并且每个帧是18个点的向量,那么您应该向教师提供包含观察结果的double[12][32][18]数组和包含预期类标签的int[12]数组。

下面的例子,从HiddenMarkovClassifierLearning文档页面中提取,应该有助于给出向量应该如何组织的想法!

// Create a Continuous density Hidden Markov Model Sequence Classifier 
// to detect a multivariate sequence and the same sequence backwards. 
double[][][] sequences = new double[][][]
{
    new double[][] 
    { 
        // This is the first  sequence with label = 0 
        new double[] { 0, 1 },
        new double[] { 1, 2 },
        new double[] { 2, 3 },
        new double[] { 3, 4 },
        new double[] { 4, 5 },
    }, 
    new double[][]
    {
            // This is the second sequence with label = 1 
        new double[] { 4,  3 },
        new double[] { 3,  2 },
        new double[] { 2,  1 },
        new double[] { 1,  0 },
        new double[] { 0, -1 },
    }
};
// Labels for the sequences 
int[] labels = { 0, 1 };

在上面的代码中,我们为2个观测序列设置了问题,其中每个序列包含5个观测值,其中每个观测值由2个值组成。如您所见,这是一个双精度[2][5][2]数组。类标签数组由int[2]给出,只包含0到1之间的值。

现在,为了使示例更完整,我们可以使用以下代码继续创建和训练模型:
var initialDensity = new MultivariateNormalDistribution(2);
// Creates a sequence classifier containing 2 hidden Markov Models with 2 states 
// and an underlying multivariate mixture of Normal distributions as density. 
var classifier = new HiddenMarkovClassifier<MultivariateNormalDistribution>(
    classes: 2, topology: new Forward(2), initial: initialDensity);
// Configure the learning algorithms to train the sequence classifier 
var teacher = new HiddenMarkovClassifierLearning<MultivariateNormalDistribution>(
    classifier,
    // Train each model until the log-likelihood changes less than 0.0001
    modelIndex => new BaumWelchLearning<MultivariateNormalDistribution>(
        classifier.Models[modelIndex])
    {
        Tolerance = 0.0001,
        Iterations = 0,
        FittingOptions = new NormalOptions()
        {
            Diagonal = true,      // only diagonal covariance matrices
            Regularization = 1e-5 // avoid non-positive definite errors
        }
    }
);
// Train the sequence classifier using the algorithm 
double logLikelihood = teacher.Run(sequences, labels);

现在我们可以测试模型,断言输出的类标签确实与我们期望的匹配:

// Calculate the probability that the given 
//  sequences originated from the model 
double likelihood, likelihood2;
// Try to classify the 1st sequence (output should be 0) 
int c1 = classifier.Compute(sequences[0], out likelihood);
// Try to classify the 2nd sequence (output should be 1) 
int c2 = classifier.Compute(sequences[1], out likelihood2);