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 ...
随机推荐
- Bayes++ Library入门学习之熟悉class-Bayesian_filter_base(1)
在对Bayes++库的名称空间有了一个大概的了解之后,我们开始学习该名称空间下的第一个子类Bayesian_filter::Bayes_filter_base. 该类与其子类的继承关系图如下图所示. ...
- php基础:define()定义常数函数
define(); 常量类似变量,不同之处在于: 在设定以后,常量的值无法更改 常量名不需要开头的美元符号 ($) 作用域不影响对常量的访问 常量值只能是字符串或数字 <?php define( ...
- git提交的规范
- C#中Dictionary排序方式
转载自:https://www.cnblogs.com/5696-an/p/5625142.html 自定义类: https://files.cnblogs.com/files/xunhanliu/d ...
- bzoj 3408 热浪 最短路
一道最短路的模板题,就当练习一下SPFA和dijkstra了 SPFA #include<bits/stdc++.h> using namespace std; struct edge{ ...
- POJ-2393 Yogurt factory 贪心问题
题目链接:https://cn.vjudge.net/problem/POJ-2393 题意 有一个生产酸奶的工厂,还有一个酸奶放在其中不会坏的储存室 每一单元酸奶存放价格为每周s元,在接下来的N周时 ...
- CF732F Tourist Reform(边双联通)
题意 在一张有向图中,设 ri 为从点 i 出发能够到达的点的数量. 定义有向图的“改良值”为 ri 的最小值. 现给出一张无向图,要求给每条边定一个方向,使产生的有向图“改良值”最大. 输出 最大改 ...
- 题解 UVA10328 【Coin Toss】
这道题目其实就是说有N张纸牌,问至少连续K张正面朝上的可能性是多少. 可以用递推做.首先我们将题目所求从 至少K张 转化为 总数 - 至多K张 (为什么要这样自己想) 设F[i][j]为前i个纸牌至多 ...
- cocos2d-x 显示触摸操作(显示水波点击效果,用于视频演示)
昨天刚刚參加玩游戏设计大赛, 积累了一些东西. 接下去将会逐个分享出来. 首先是显示触摸操作. 由于要演示我们的作品.使用试玩过程中, 假设没办法显示我们的触摸操作(像录制视频一样, 点击了屏幕某点, ...
- Consolas 字体
Consolas是一套等宽字体的字型,属无衬线字体,由Lucas de Groot设计. 概述 这套字型使用了微软的ClearType 字型平滑技术,并随同Windows Vista.Office 2 ...