Kinect 开发 —— WaveHand
基本注释都写了,就不废话了
<Window x:Class="KinectBasicHandTrackingFrameworkTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="800" xmlns:my="clr-namespace:KinectBasicHandTrackingFramework;assembly=KinectBasicHandTrackingFramework">
<Grid Background="#CCFFFF">
<!--自定义控件-->
<my:KinectButton Content="Kinect Button" Height="130" Width="130" HorizontalAlignment="Left" Margin="576,51,0,0" Name="kinectButton1" VerticalAlignment="Top" Click="Button_Click" Background="Red" KinectCursorLeave="Button_KinectCursorLeave" />
<my:HoverButton Content="Hover Button" Height="130" Width="130" HorizontalAlignment="Left" Margin="576,227,0,0" Name="hoverButton1" VerticalAlignment="Top" Click="Button_Click" Background="Red" KinectCursorLeave="Button_KinectCursorLeave"/>
<my:MagnetButton Content="Magnet Button" Height="130" Width="130" HorizontalAlignment="Left" Margin="576,395,0,0" Name="magnetButton1" VerticalAlignment="Top" Click="Button_Click" Background="Red" KinectCursorLeave="Button_KinectCursorLeave" />
<ListBox Height="306" HorizontalAlignment="Left" Margin="46,51,0,0" Name="listBox1" VerticalAlignment="Top" Width="296" />
</Grid>
</Window>
namespace KinectBasicHandTrackingFrameworkTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private KinectSensor _kinectDevice;
private Skeleton[] _FrameSkeletons;
private WaveGesture _WaveGesture; // 此应用程序只能识别这一个手势,有待添加 public MainWindow()
{
InitializeComponent();
this._WaveGesture = new WaveGesture();
this._WaveGesture.GestureDetected += new EventHandler(_WaveGesture_GestureDetected); // 绑定事件,可以检测wave动作
this._kinectDevice = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
this._kinectDevice.SkeletonFrameReady += KinectDevice_SkeletonFrameReady;
} private void Button_Click(object sender, RoutedEventArgs e)
{
var button = sender as KinectButton; // 重写点击方法
button.Background = new SolidColorBrush(Colors.Green);
} private void Button_KinectCursorLeave(object sender, KinectCursorEventArgs e)
{
var button = sender as KinectButton;
button.Background = new SolidColorBrush(Colors.Red);
} private void KinectDevice_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame frame = e.OpenSkeletonFrame())
{
if (frame != null)
{
this._FrameSkeletons = new Skeleton[_kinectDevice.SkeletonStream.FrameSkeletonArrayLength];
frame.CopySkeletonDataTo(this._FrameSkeletons); DateTime startMarker = DateTime.Now; // 时间戳
this._WaveGesture.Update(this._FrameSkeletons, frame.Timestamp);
}
}
} private void _WaveGesture_GestureDetected(object sender, EventArgs e)
{
listBox1.Items.Add(string.Format("Wave Detected {0}", DateTime.Now.ToLongTimeString())); }
}
}
namespace KinectBasicHandTrackingFrameworkTest
{
public class WaveGesture
{
#region Member Variables
private const float WAVE_THRESHOLD = 0.1f;
private const int WAVE_MOVEMENT_TIMEOUT = ;
private const int LEFT_HAND = ;
private const int RIGHT_HAND = ;
private const int REQUIRED_ITERATIONS = ; private WaveGestureTracker[,] _PlayerWaveTracker = new WaveGestureTracker[, ]; public event EventHandler GestureDetected; // 表示将处理不包含事件数据的事件的方法
#endregion Member Variables #region Methods
public void Update(Skeleton[] skeletons, long frameTimestamp)
{
if (skeletons != null)
{
Skeleton skeleton; for (int i = ; i < skeletons.Length; i++)
{
skeleton = skeletons[i]; if (skeleton.TrackingState != SkeletonTrackingState.NotTracked)
{
TrackWave(skeleton, true, ref this._PlayerWaveTracker[i, LEFT_HAND], frameTimestamp); // 六个人分别检测左右手是否挥动
TrackWave(skeleton, false, ref this._PlayerWaveTracker[i, RIGHT_HAND], frameTimestamp);
}
else
{
this._PlayerWaveTracker[i, LEFT_HAND].Reset();
this._PlayerWaveTracker[i, RIGHT_HAND].Reset();
}
}
}
} private void TrackWave(Skeleton skeleton, bool isLeft, ref WaveGestureTracker tracker, long timestamp)
{
JointType handJointId = (isLeft) ? JointType.HandLeft : JointType.HandRight;
JointType elbowJointId = (isLeft) ? JointType.ElbowLeft : JointType.ElbowRight;
Joint hand = skeleton.Joints[handJointId];
Joint elbow = skeleton.Joints[elbowJointId]; if (hand.TrackingState != JointTrackingState.NotTracked && elbow.TrackingState != JointTrackingState.NotTracked)
{
if (tracker.State == WaveGestureState.InProgress && tracker.Timestamp + WAVE_MOVEMENT_TIMEOUT < timestamp) // 超过规定时间仍未完成
{
tracker.UpdateState(WaveGestureState.Failure, timestamp);
System.Diagnostics.Debug.WriteLine("Fail!");
}
else if (hand.Position.Y > elbow.Position.Y)
{
//Using the raw values where (0, 0) is the middle of the screen. From the user's perspective, the X-Axis grows more negative left and more positive right.
// 右手坐标系,Z轴射出,Y轴向上,X轴向左,坐标系的单位为米
if (hand.Position.X <= elbow.Position.X - WAVE_THRESHOLD)
{
tracker.UpdatePosition(WavePosition.Left, timestamp);
}
else if (hand.Position.X >= elbow.Position.X + WAVE_THRESHOLD)
{
tracker.UpdatePosition(WavePosition.Right, timestamp);
}
else
{
tracker.UpdatePosition(WavePosition.Neutral, timestamp);
} if (tracker.State != WaveGestureState.Success && tracker.IterationCount == REQUIRED_ITERATIONS)
{
tracker.UpdateState(WaveGestureState.Success, timestamp); // 重置
System.Diagnostics.Debug.WriteLine("Success!"); if (GestureDetected != null)
{
GestureDetected(this, new EventArgs());
}
}
}
else
{
if (tracker.State == WaveGestureState.InProgress)
{
tracker.UpdateState(WaveGestureState.Failure, timestamp);
System.Diagnostics.Debug.WriteLine("Fail!");
}
else
{
tracker.Reset();
}
}
}
else
{
// 关节点未成功跟踪,重置
tracker.Reset();
}
}
#endregion Methods #region Helper Objects
private enum WavePosition
{
None = ,
Left = ,
Right = ,
Neutral =
} private enum WaveGestureState
{
None = ,
Success = ,
Failure = ,
InProgress =
} private struct WaveGestureTracker
{
public int IterationCount;
public WaveGestureState State;
public long Timestamp;
public WavePosition StartPosition;
public WavePosition CurrentPosition; public void UpdateState(WaveGestureState state, long timestamp)
{
State = state;
Timestamp = timestamp;
} public void Reset()
{
IterationCount = ;
State = WaveGestureState.None;
Timestamp = ;
StartPosition = WavePosition.None;
CurrentPosition = WavePosition.None;
} public void UpdatePosition(WavePosition position, long timestamp)
{
if (CurrentPosition != position)
{
if (position == WavePosition.Left || position == WavePosition.Right)
{
if (State != WaveGestureState.InProgress)
{ // 若向左或向右但不是处理状态(None ,Success ,Failure) ,则重置
State = WaveGestureState.InProgress;
IterationCount = ;
StartPosition = position;
} IterationCount++; // 挥手过程中状态改变,迭代数++
} CurrentPosition = position; // 状态重置
Timestamp = timestamp;
}
}
}
#endregion Helper Objects
}
}
Kinect 开发 —— WaveHand的更多相关文章
- Kinect开发文章目录
整理了一下去年为止到现在写的和翻译的Kinect的相关文章,方便大家查看.另外,最近京东上微软在搞活动, 微软 Kinect for Windows 京东十周年专供礼包 ,如果您想从事Kinect开发 ...
- Kinect开发资源汇总
Kinect开发资源汇总 转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinec ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- Kinect开发笔记之二Kinect for Windows 2.0新功能
这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家. ...
- Kinect 开发 —— 杂一
Kinect 提供了非托管(C++)和托管(.NET)两种开发方式的SDK,如果您用C++开发的话,需要安装Speech Runtime(V11),Kinect for Windows Runtime ...
- Kinect 开发 —— 控制PPT播放
实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换. 这里的核心功能在于手势的识别,我们在 ...
- Kinect 开发 —— 全息图
Kinect的另一个有趣的应用是伪全息图(pseudo-hologram).3D图像可以根据人物在Kinect前面的各种位置进行倾斜和移动.如果方法够好,可以营造出3D控件中3D图像的效果,这样可以用 ...
- Kinect 开发 —— 进阶指引(上)
本文将会介绍一些第三方类库如何来帮助处理Kinect传感器提供的数据.使用不同的技术进行Kinect开发,可以发掘出Kinect应用的强大功能.另一方面如果不使用这些为了特定处理目的而开发的一些类库, ...
- Kinect开发 —— 基础知识
转自:http://www.cnblogs.com/yangecnu/archive/2012/04/02/KinectSDK_Application_Fundamentals_Part2.html ...
随机推荐
- 服务器http处理流程
网络请求.处理的组织: context Facade模式/指令处理引擎/简单处理机: 响应码: 只要有响应码就代表服务器已经接收到请求:无响应代表网络层出现问题,与服务器无关. 处理步骤: 1)模块( ...
- TrueOS 不再想要成为“桌面 BSD”了
作者: John Paul Wohlscheid 译者: LCTT geekpi | 2018-07-13 22:53 TrueOS 很快会有一些非常重大的变化.今天,我们将了解桌面 BSD 领域将会 ...
- Remmina:一个 Linux 下功能丰富的远程桌面共享工具(转载)
Remmina:一个 Linux 下功能丰富的远程桌面共享工具 作者: Aaron Kili 译者: LCTT geekpi | 2017-05-10 09:05 评论: 2 收藏: 4 Remm ...
- How Javascript works (Javascript工作原理) (十五) 类和继承及 Babel 和 TypeScript 代码转换探秘
个人总结:读完这篇文章需要15分钟,文章主要讲解了Babel和TypeScript的工作原理,(例如对es6 类的转换,是将原始es6代码转换为es5代码,这些代码中包含着类似于 _classCall ...
- caioj 1413 动态规划4:打鼹鼠
记住一定要区分n和m分别代表什么,我已经因为这个两道题浪费很多时间了 然后这个道题有点类似最长上升子序列n平方的做法,只是判断的条件不同而已 #include<cstdio> #inclu ...
- USART
串口通信是一种设备间非常常用的串行通行方式,其简单便捷,大部分电子设备都支持. 一.物理层 常用RS-232标准,主要规定了信号的用途.通信接口以及信号的电平标准. “DB9接口”之间通过串口信号线 ...
- MySQL日志设置及查看方法
MySQL有以下几种日志: 错误日志: -log-err 查询日志: -log 慢查询日志: -log-slow-queries 更新日志: -log-update 二进制日志: -log-bin 默 ...
- ArcGIS api for javascript——地理编码任务-地理编码地址
描述 本例允许用户输入一个地址,然后显示匹配的地址的位置.这通常地被称为地理编码.在ArcGIS JavaScript API中,使用Locator类执行地理编码. 定位器构造函数需要ArcGIS S ...
- 书剑恩仇录online全套源代码(服务端+client+文档)
书剑恩仇录online全套源代码(服务端+client+文档).vc++开发,解压后将近10G大小,眼下网上最完整版本号,包括client源代码.服务端源代码.工具源代码.sdk.文档-- <书 ...
- 改动npm包管理器的registry为淘宝镜像(npm.taobao.org)
起因 安装了node.安装了npm之后,官方的源实在是 太慢了! 看了看淘宝的npm镜像, http://npm.taobao.org/ 居然说让我再下载一个cnpm,要不然就每次都得install ...