系统中在学生学习完单词后会有一个巩固单词做题的小测试,测试为选择题的方式,因为系统是投影到用户面前的大屏幕上的所以选择使用kinect对用户动作进行捕捉,判断用户的选择。
选择题界面:
kinect开发:
系统中使用kinect v2进行动作捕捉,首先需要下载kinect v2 sdk
官方下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=44561
下载安装后得到:
打开SDK Browser
因为整个系统是采用c#语言进行开发的,选用Sample:c#,因为我们的目的是通过获取用户动作判断用户的选择,所以选择
Body Basic-WPF
选择install,得到一个Windows的标准wpf程序,文件结构如下:
使用Visual Studio打开.sln文件:
这个脚本中包含了对骨骼点的记录,通过建立数组对判断用户动作所需的骨骼点数据进行保存:
用于判断用户输入的方法:
//通过七个骨骼节点在K帧内的位置判断所做动作对应的ABC选项
public int PointWhere(point[] HandTipLeft, point[] HandTipRight,point[] Spine,point[] ShoulderCenter, point[] ShoulderLeft, point[] ShoulderRight,point[] HipCenter,int i, int k)
{
int A = 0;
int B = 0;
int C = 0;
for(; k>0&&i-k>0; k--)
{
double midY = (ShoulderCenter[i-k].y + HipCenter[i-k].y) / 2.0;
if (HandTipRight[i-k].y <= midY && HandTipLeft[i - k].y <= midY) continue;
double X = 0;
if (HandTipLeft[i - k].y > midY) X = HandTipLeft[i - k].x;
if (HandTipRight[i - k].y > midY) X = HandTipRight[i - k].x;
if (X != 0)
{
if (X < ShoulderLeft[i - k].x) A++;
if (X > ShoulderLeft[i - k].x && HandTipRight[i - k].x < ShoulderRight[i - k].x) B++;
if (X > ShoulderRight[i - k].x) C++;
}
}
if (A <= 30 && B <= 30 && C <= 30) return 0;
if (A > B && A > C) return 1;
if (B > A && B > C) return 2;
return 3;
}
通过得到k帧的数据将用户的右手与驱赶夹角判断用户手臂的指向以判断用户的输入。
在unity下的系统项目中的小测试场景的脚本与该程序进行数据通信,使unity项目可以实时使用该程序的判断结果。
动作判断的完整脚本如下
//------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace Microsoft.Samples.Kinect.BodyBasics
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Kinect;
using System.Threading;
/// <summary>
/// Interaction logic for MainWindow
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
int i = 0;
point[] HandTipLeft = new point[200000];
point[] HandTipRight = new point[200000];
point[] Spine = new point[200000];
point[] ShoulderCenter = new point[200000];
point[] ShoulderLeft = new point[200000];
point[] ShoulderRight = new point[200000];
point[] HipCenter = new point[200000];
/// <summary>
/// Radius of drawn hand circles
/// </summary>
private const double HandSize = 30;
/// <summary>
/// Thickness of drawn joint lines
/// </summary>
private const double JointThickness = 3;
/// <summary>
/// Thickness of clip edge rectangles
/// </summary>
private const double ClipBoundsThickness = 10;
/// <summary>
/// Constant for clamping Z values of camera space points from being negative
/// </summary>
private const float InferredZPositionClamp = 0.1f;
/// <summary>
/// Brush used for drawing hands that are currently tracked as closed
/// </summary>
private readonly Brush handClosedBrush = new SolidColorBrush(Color.FromArgb(128, 255, 0, 0));
/// <summary>
/// Brush used for drawing hands that are currently tracked as opened
/// </summary>
private readonly Brush handOpenBrush = new SolidColorBrush(Color.FromArgb(128, 0, 255, 0));
/// <summary>
/// Brush used for drawing hands that are currently tracked as in lasso (pointer) position
/// </summary>
private readonly Brush handLassoBrush = new SolidColorBrush(Color.FromArgb(128, 0, 0, 255));
/// <summary>
/// Brush used for drawing joints that are currently tracked
/// </summary>
private readonly Brush trackedJointBrush = new SolidColorBrush(Color.FromArgb(255, 68, 192, 68));
/// <summary>
/// Brush used for drawing joints that are currentl