Kinect 开发 —— 控制PPT播放
实现Kinect控制幻灯片播放很简单,主要思路是:使用Kinect捕捉人体动作,然后根据识别出来的动作向系统发出点击向前,向后按键的事件,从而使得幻灯片能够切换。 这里的核心功能在于手势的识别,我们在开发之前需要定义怎么样的手势算是向前或者向后切换幻灯片。手势和姿势识别在我的Kinect开发入门第九,第十,十一篇文章有详细介绍。本文仅讨论主要思路及关键代码部分。
通过姿势实现PPT控制
姿势(pose)识别是通过关节点与关节点之间的相对位置关系来进行判断,相对来说比较容易,只需要通过某一帧骨骼关节点数据即可进行判断。而手势(gesture)识别则是通过对连续的一段时间内的动作来进行判断,比较复杂。但是两者对于我们需要实现特定的目的来说并没有优劣之分,就像常用的算法那样,并不是越复杂越好,有些方法就非常简单高效。
在控制ppt播放命令中,我们设定,如果右手关节点在x轴上的距离比头部关节点大于0.45的话,认为用户试图进行点击键盘上的right按钮。如果头部关节点位置在x轴方向是比左手关节点在x轴上的位置大于0.45的话,认为用户试图点击键盘上的left按钮。0.45这个值是通过反复试验的出来的,这种通过试验的方法在Kinect开发中比较常见。关键代码如下:
private void ProcessForwardBackGesture(Joint head, Joint rightHand, Joint leftHand)
{
if (rightHand.Position.X > head.Position.X + 0.45)
{
if (!isBackGestureActive && !isForwardGestureActive)
{
isForwardGestureActive = true;
System.Windows.Forms.SendKeys.SendWait("{Right}");
}
}
else
{
isForwardGestureActive = false;
} if (leftHand.Position.X < head.Position.X - 0.45)
{
if (!isBackGestureActive && !isForwardGestureActive)
{
isBackGestureActive = true;
System.Windows.Forms.SendKeys.SendWait("{Left}");
}
}
else
{
isBackGestureActive = false;
}
}
上面的代码中,当判断到用户向右挥手动作是,执行System.Windows.Forms.SendKeys.SendWait("{Right}")语句从而发出点击键盘向右按键; 该方法执行时,要求PowerPoint程序处于当前活动的状态,这样里面的PPT才会向右键盘点击事件。需要注意的是方法中isBackGestureActive和isForwardGestureActive这两个布尔型的标志位,可以防止当用户一直处于某一个动作时会一直发送System.Windows.Forms.SendKeys.SendWait("{xx}")。
上面的方法可以放在sensor_SkeletonFrameReady事件中,首先获取头部,左手右手关节点数据,然后调用该方法。
void sensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (var skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame == null)
return; if (skeletons == null ||
skeletons.Length != skeletonFrame.SkeletonArrayLength)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
} skeletonFrame.CopySkeletonDataTo(skeletons); Skeleton closestSkeleton = (from s in skeletons
where s.TrackingState == SkeletonTrackingState.Tracked &&
s.Joints[JointType.Head].TrackingState == JointTrackingState.Tracked
select s).OrderBy(s => s.Joints[JointType.Head].Position.Z)
.FirstOrDefault(); if (closestSkeleton == null)
return; var head = closestSkeleton.Joints[JointType.Head];
var rightHand = closestSkeleton.Joints[JointType.HandRight];
var leftHand = closestSkeleton.Joints[JointType.HandLeft]; if (head.TrackingState != JointTrackingState.Tracked ||
rightHand.TrackingState != JointTrackingState.Tracked ||
leftHand.TrackingState != JointTrackingState.Tracked)
{
//Don't have a good read on the joints so we cannot process gestures
return;
} ProcessForwardBackGesture(head, rightHand, leftHand);
}
}
通过姿势识别来进行幻灯片控制简单高效,但是也存在着两个主要问题:
首先是,如果幻灯片中嵌套有视频,flash或者其他多媒体要素的话,可能不能很好的控制这些要素的播放和暂停,一种处理办法是使用动画,使得用户在点击键盘显示多媒体的时候就开始播放。还有一种方法是使用VSTO编写针对PowerPoint的插件,来监听鼠标来控制多媒体播放。
其次是误操作问题,这个问题是使用基于姿势识别存在的最大问题。有时候可能出于肢体语言表达需要,可能需要张开双臂,或者弯下腰来捡东西,这样会使得头部关节点位置和手部关节点位置的相对关系可能会满足之前我们设定的距离,从而产生误操作。
使用姿势识别的第一个问题是一个普遍存在的问题,即使使用ppt控制器也存在该问题,ppt控制器似乎也是通过发送键盘点击事件来进行幻灯片控制的。第二个问题可以使用手势识别的方式来在一定程度上避免。
Skeleton closestSkeleton = (from s in skeletons
where s.TrackingState == SkeletonTrackingState.Tracked &&
s.Joints[JointType.Head].TrackingState == JointTrackingState.Tracked
select s).OrderBy(s => s.Joints[JointType.Head].Position.Z)
.FirstOrDefault();
手势识别控制
手势识别通过判断在一定时间内一系列连续的动作之间的前后相关关系来进行动作的识别,在第十篇 文章中对swip这一动作如何识别有详细介绍。在Kinect for Windows Developer ToolKit v 1.5中,增加了一个名为Slideshow Gesture-WPF的例子。
要使用该dll提供的手势识别,必须先创建一个Recognizer对象。然后初始化改Recognizer。在初始化的时候注册左右挥动识别后进行的操作,该操作可以通过方法提供,由于方法体比较小,这里使用lambda表达式。
private readonly Recognizer activeRecognizer;
this.activeRecognizer = this.CreateRecognizer();
private Recognizer CreateRecognizer()
{
// Instantiate a recognizer.
var recognizer = new Recognizer();
// swipe right to press right key .
recognizer.SwipeRightDetected += (s, e) =>
{
System.Windows.Forms.SendKeys.SendWait("{Right}");
};
// swipe left to press left key ..
recognizer.SwipeLeftDetected += (s, e) =>
{
System.Windows.Forms.SendKeys.SendWait("{Left}");
};
return recognizer;
}然后在sensor_SkeletonFrameReady事件中调用即可
private Skeleton[] skeletons = new Skeleton[];
private void sensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
// Get the frame.
using (var frame = e.OpenSkeletonFrame())
{
// Ensure we have a frame.
if (frame != null)
{
// Resize the skeletons array if a new size (normally only on first call).
if (this.skeletons.Length != frame.SkeletonArrayLength)
{
this.skeletons = new Skeleton[frame.SkeletonArrayLength];
}
// Get the skeletons.
frame.CopySkeletonDataTo(this.skeletons);
// Pass skeletons to recognizer.
this.activeRecognizer.Recognize(sender, frame, this.skeletons);
}
}
}
把上面的代码放到程序中,运行即可看到使用左手向左挥手,使用右手向右挥手即可控制幻灯片向左向右切换。如前面的文章所述,使用手势识别动作有一个时间阈值和一定的规则,如果该动作在某一时间内没有完成则识别失败。所以在本例中,如果挥手动作过慢,可能导致识别不出。而不像之前使用姿势识别例子中的那样,只需保持某个动作即可完成识别操作,这在一定程度上减少了第一种情况下出现误识别的概率。
Kinect 开发 —— 控制PPT播放的更多相关文章
- 基于windowsphone7的控制ppt播放
最近突然想起了一个学长的一个利用手机控制ppt播放的一个创意,并想将其在windows phone7上实现一下. 经过几天的努力已经可以控制ppt的播放,暂停,上一张,下一张了,并且电脑会将当前ppt ...
- Kinect开发文章目录
整理了一下去年为止到现在写的和翻译的Kinect的相关文章,方便大家查看.另外,最近京东上微软在搞活动, 微软 Kinect for Windows 京东十周年专供礼包 ,如果您想从事Kinect开发 ...
- Kinect开发笔记之二Kinect for Windows 2.0新功能
这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家. ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
- iOS开发—音乐的播放
iOS开发—音乐的播放 一.简单说明 音乐播放用到一个叫做AVAudioPlayer的类,这个类可以用于播放手机本地的音乐文件. 注意: (1)该类(AVAudioPlayer)只能用于播放本地音频. ...
- 手机控制PPT good
以前做了一个小东西,通过手机来控制PPT的翻页,最大化和最小化,东西很简单,近期整理电脑发现了拿来和大家分享一下 主要分为两个部分,客户端和服务器 客户端实现 当初考虑到跨平台的特性就选择了qt来写的 ...
- Kinect开发资源汇总
Kinect开发资源汇总 转自: http://www.sigvc.org/bbs/forum.php?mod=viewthread&tid=254&highlight=kinec ...
- 自己编写的一个有关安卓应用开发培训PPT
这个是我自己编写的一个有关安卓应用开发培训PPT,适合新手. 在这里下载PPT
- Swift实战-豆瓣电台(九)简单手势控制暂停播放(全文完)
Swift实战-豆瓣电台(九)简单手势控制暂停播放 全屏清晰观看地址:http://www.tudou.com/programs/view/tANnovvxR8U/ 这节我们主要讲UITapGestu ...
随机推荐
- win环境操作mysql
第一步:登录数据库 第二步:查看数据库 第三步:进入数据库 第四步:创建表 第五步:删除数据库 第六步:进入数据库查看表状态
- 为什么 linux 上不能用 localhost 链接数据库?
因为 linux 连接的时候不是通过 tcp 协议,而是通过 sockect 来连接.所以 写localhost 之后就会默认去找 sockect 链接[此文件在 /var/lib/mysq ...
- HTML5按键打开摄像头和拍照
HTML5实现按键打开摄像头和拍照 步骤: 1.创建一个打开摄像头按钮的标签.video标签.拍照的按钮标签.画布 2.实现打开摄像头的功能 3.实现拍照功能 具体实现代码: <!DOCTY ...
- ubuntu18.04安装dash-to-dock出错的问题
之前在安装dash-to-dock出现了这种错误: TypeError: ExtensionUtils.initTranslations is not a function Stack trace:i ...
- P1872 回文串计数(回文树)
题目描述 小a虽然是一名理科生,但他常常称自己是一名真正的文科生.不知为何,他对于背诵总有一种莫名其妙的热爱,这也促使他走向了以记忆量大而闻名的生物竞赛.然而,他很快发现这并不能满足他热爱背诵的心,但 ...
- 洛谷——P1965 转圈游戏
https://www.luogu.org/problem/show?pid=1965 题目描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n- ...
- 洛谷—— P1003 铺地毯
https://www.luogu.org/problem/show?pid=1003 题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形 ...
- Android布局文件的载入过程分析:Activity.setContentView()源代码分析
大家都知道在Activity的onCreate()中调用Activity.setContent()方法能够载入布局文件以设置该Activity的显示界面.本文将从setContentView()的源代 ...
- C# double保留四位小数
2.保留N位,四舍五入 . decimal d= decimal.Round(decimal.Parse("0.55555"),4); 3.保留N位四舍五入 Math.Round( ...
- 手把手教你如何在Ubuntu系统中安装Pycharm
前几天带大家一起安装了Ubuntu14.04系统,没来得及上车的伙伴可以戳这篇文章:手把手教你在VMware虚拟机中安装Ubuntu14.04系统.今天小编带大家一起在Ubuntu14.04中安装Py ...