使用HTML5开发Kinect体感游戏
Kinect有三个镜头,中间镜头类似普通摄像头,获取彩色图像。左右两边镜头则是通过红外线获取深度数据。我们使用微软提供的SDK去读取以下类型数据:
- 色彩数据:彩色图像;
- 深度数据:颜色尝试信息;
- 人体骨骼数据:基于以上数据经计算,获取到人体骨骼数据。
我尝试和了解过的框架,基本上是以socket让浏览器进程与服务器进行通信 ,进行数据传输:
- Kinect-HTML5 用C#搭建服务端,色彩数据、尝试数据、骨骼数据均有提供;
- ZigFu 支持H5、U3D、Flash进行开发,API较为完整,貌似收费;
- DepthJS 以浏览器插件形式提供数据访问;
- Node-Kinect2 以Nodejs搭建服务器端,提供数据比较完整,实例较多。

- Kinect: 捕获玩家数据,比如深度图像、彩色图像等;
- Node-Kinect2: 从Kinect获取相应数据,并进行二次加工;
- 浏览器: 监听node应用指定接口,获取玩家数据并完成游戏开发。
这是硬性要求,我曾在不符合要求的环境下浪费太多时间。
- USB3.0
- 支持DX11的显卡
- win8及以上系统
- 支持Web Sockets的浏览器
- 当然Kinect v2传感器是少不了的
- 连接上Kinect v2
- 安装 KinectSDK-v2.0
- 安装 Nodejs
- 安装 Node-Kinect2
npm install kinect2

1、服务器端
创建web服务器,并将骨骼数据发送到浏览器端,代码如下:
var Kinect2 = require('../../lib/kinect2'),
express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server); var kinect = new Kinect2();
// 打开kinect
if(kinect.open()) {
// 监听8000端口
server.listen(8000);
// 指定请求指向根目录
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/index.html');
});
// 将骨骼数据发送给浏览器端
kinect.on('bodyFrame', function(bodyFrame){
io.sockets.emit('bodyFrame', bodyFrame);
});
// 开始读取骨骼数据
kinect.openBodyReader();
}
2、浏览器端
浏览器端获取骨骼数据,并用canvas描绘出来,关键代码如下:
var socket = io.connect('/');
var ctx = canvas.getContext('2d');
socket.on('bodyFrame', function(bodyFrame){
ctx.clearRect(0, 0, canvas.width, canvas.height);
var index = 0;
// 遍历所有骨骼数据
bodyFrame.bodies.forEach(function(body){
if(body.tracked) {
for(var jointType in body.joints) {
var joint = body.joints[jointType];
ctx.fillStyle = colors[index];
// 如果骨骼节点为脊椎中点
if(jointType == 1) {
ctx.fillStyle = colors[2];
}
ctx.fillRect(joint.depthX * 512, joint.depthY * 424, 10, 10);
}
// 识别左右手手势
updateHandState(body.leftHandState, body.joints[7]);
updateHandState(body.rightHandState, body.joints[11]);
index++;
}
});
});
很简单的几行代码,我们便完成了玩家骨骼捕获,有一定 javascript基础的同学应该很容易能看明白,但不明白的是我们能获取哪些数据?如何获取?骨骼节点名称分别是什么?而node-kienct2并没有文档告诉我们这些。
kinect.on('bodyFrame', function(bodyFrame){}); //还有哪些数据类型呢?
bodyFrame | 骨骼数据 |
infraredFrame | 红外数据 |
longExposureInfraredFrame | 类似infraredFrame,貌似精度更高,优化后的数据 |
rawDepthFrame | 未经处理的景深数据 |
depthFrame | 景深数据 |
colorFrame | 彩色图像 |
multiSourceFrame | 所有数据 |
audio | 音频数据,未测试 |
body.joints[11] // joints包括哪些呢?
节点类型 | JointType | 节点名称 |
0 | spineBase | 脊椎基部 |
1 | spineMid | 脊椎中部 |
2 | neck | 颈部 |
3 | head | 头部 |
4 | shoulderLeft | 左肩 |
5 | elbowLeft | 左肘 |
6 | wristLeft | 左腕 |
7 | handLeft | 左手掌 |
8 | shoulderRight | 右肩 |
9 | elbowRight | 右肘 |
10 | wristRight | 右腕 |
11 | handRight | 右手掌 |
12 | hipLeft | 左屁 |
13 | kneeLeft | 左膝 |
14 | ankleLeft | 左踝 |
15 | footLeft | 左脚 |
16 | hipRight | 右屁 |
17 | kneeRight | 右膝 |
18 | ankleRight | 右踝 |
19 | footRight | 右脚 |
20 | spineShoulder | 颈下脊椎 |
21 | handTipLeft | 左手指(食中无小) |
22 | thumbLeft | 左拇指 |
23 | handTipRight | 右手指 |
24 | thumbRight | 右拇指 |
0 | unknown | 不能识别 |
1 | notTracked | 未能检测到 |
2 | open | 手掌 |
3 | closed | 握拳 |
4 | lasso | 剪刀手,并合并中食指 |
body [object] {
bodyIndex [number]:索引,允许6人
joints [array]:骨骼节点,包含坐标信息,颜色信息
leftHandState [number]:左手手势
rightHandState [number]:右手手势
tracked [boolean]:是否捕获到
trackingId
}
on | 监听数据 |
open | 打开Kinect |
close | 关闭 |
openBodyReader | 读取骨骼数据 |
open**Reader | 类似如上方法,读取其它类型数据 |
1.1、通过手势触发开始游戏 |
1.2、玩家化身四代,左右跑动躲避九尾攻击 |
1.3、摆出手势“奥义”,触发四代大招 |
1.4、用户扫描二维码获取自己现场照片 |
游戏需要玩家骨骼数据(移动、手势),彩色图像数据(某一手势下触发拍照),所以我们需要向客户端发送这两部分数据。值得注意的是,彩色图像数据体积过大,需要进行压缩。
var emitColorFrame = false;
io.sockets.on('connection', function (socket){
socket.on('startColorFrame', function(data){
emitColorFrame = true;
});
});
kinect.on('multiSourceFrame', function(frame){ // 发送玩家骨骼数据
io.sockets.emit('bodyFrame', frame.body); // 玩家拍照
if(emitColorFrame) {
var compression = 1;
var origWidth = 1920;
var origHeight = 1080;
var origLength = 4 * origWidth * origHeight;
var compressedWidth = origWidth / compression;
var compressedHeight = origHeight / compression;
var resizedLength = 4 * compressedWidth * compressedHeight;
var resizedBuffer = new Buffer(resizedLength);
// ...
// 照片数据过大,需要压缩提高传输性能
zlib.deflate(resizedBuffer, function(err, result){
if(!err) {
var buffer = result.toString('base64');
io.sockets.emit('colorFrame', buffer);
}
});
emitColorFrame = false;
}
});
kinect.openMultiSourceReader({
frameTypes: Kinect2.FrameType.body | Kinect2.FrameType.color
});
3、客户端
客户端业务逻辑较复杂,我们提取关键步骤进行讲解。
3.1、用户拍照时,由于处理的数据比较大,为防止页面出现卡顿,我们需要使用web worker
(function(){
importScripts('pako.inflate.min.js'); var imageData;
function init() {
addEventListener('message', function (event) {
switch (event.data.message) {
case "setImageData":
imageData = event.data.imageData;
break;
case "processImageData":
processImageData(event.data.imageBuffer);
break;
}
});
}
function processImageData(compressedData) {
var imageBuffer = pako.inflate(atob(compressedData));
var pixelArray = imageData.data;
var newPixelData = new Uint8Array(imageBuffer);
var imageDataSize = imageData.data.length;
for (var i = 0; i < imageDataSize; i++) {
imageData.data[i] = newPixelData[i];
}
for(var x = 0; x < 1920; x++) {
for(var y = 0; y < 1080; y++) {
var idx = (x + y * 1920) * 4;
var r = imageData.data[idx + 0];
var g = imageData.data[idx + 1];
var b = imageData.data[idx + 2];
}
}
self.postMessage({ "message": "imageReady", "imageData": imageData });
}
init();
})();
3.2、接投影仪后,如果渲染面积比较大,会出现白屏,需要关闭浏览器硬件加速。
3.3、现场光线较暗,其它玩家干扰,在追踪玩家运动轨迹的过程中,可能会出现抖动的情况,我们需要去除干扰数据。(当突然出现很大位移时,需要将数据移除)
var tracks = this.tracks;
var len = tracks.length; // 数据过滤
if(tracks[len-1] !== window.undefined) {
if(Math.abs(n - tracks[len-1]) > 0.2) {
return;
}
}
this.tracks.push(n);
3.4、当玩家站立,只是左右少量晃动时,我们认为玩家是站立状态。
// 保留5个数据
if(this.tracks.length > 5) {
this.tracks.shift();
} else {
return;
} // 位移总量
var dis = 0;
for(var i = 1; i < this.tracks.length; i++) {
dis += this.tracks[i] - this.tracks[i-1];
}
if(Math.abs(dis) < 0.01) {
this.stand();
} else {
if(this.tracks[4] > this.tracks[3]) {
this.turnRight();
} else {
this.turnLeft();
}
this.run();
}
2、大量的框架可以应用,比如用JQuery、CreateJS、Three.js(三种不同渲染方式);
3、无限想象空间,试想下体感游戏结合webAR,结合webAudio、结合移动设备,太可以挖掘的东西了……想想都激动不是么!
使用HTML5开发Kinect体感游戏的更多相关文章
- OpenNI结合Unity3D Kinect进行体感游戏开发(转)
OpenNI结合Unity3D Kinect进行体感游戏开发(转) 楼主# 更多 发布于:2012-07-17 16:42 1. 下载安装Unity3D(目前版本为3.4)2. 下载OpenN ...
- 【CityHunter】基于LBS的AR体感游戏设计理念
本人目前还不是游戏行业的圈内人士,并不懂得,游戏行业的生态圈,也不懂得,所谓的什么“中国市场环境”.所以不敢发表关于这方面的见解,不过我在这里想要插一句话,就是我认为啊,行业内,人与人之间还是有分层次 ...
- Kinect外包团队(长年承接微软Kinect体感项目外包,有大型Kinect案例)
承接Kinect体感企业项目.游戏项目外包 北京公司.专业团队,成员为专业WPF产品公司一线开发人员,有大型产品开发经验: 提供优质的售后服务,保证产品质量,轻量级产品可以提供规范清晰的源代码,有业务 ...
- Kinect外包-就找北京动点飞扬软件(长年承接微软Kinect体感项目外包,有大型Kinect案例)
承接Kinect体感企业项目.游戏项目外包 有丰富案例提供演示,可公对公签正规合同,开发票. 我们是北京的公司.专业团队,成员为专业WPF产品公司一线开发人员,有大型产品开发经验: 提供优质的售后服务 ...
- [体感游戏] 1、MPU6050数据采集传输与可视化
最近在研究体感游戏,到目前为止实现了基于51单片机的MPU6050数据采集.利用蓝牙模块将数据传输到上位机,并利用C#自制串口数据高速采集软件,并且将数据通过自制的折线图绘制模块可视化地展示出来等功能 ...
- 使用unity3d和tensorflow实现基于姿态估计的体感游戏
使用unity3d和tensorflow实现基于姿态估计的体感游戏 前言 之前做姿态识别,梦想着以后可以自己做出一款体感游戏,然而后来才发现too young.但是梦想还是要有的,万一实现了呢.趁着p ...
- 制作Kinect体感控制小车教程 <一>
转载请注明出处:http://blog.csdn.net/lxk7280 Kinect体感控制小车 Kine ...
- scratch编程体感游戏
体感游戏有很多种,最常见的就是摄像头和声控了,今天我们要用scratch编写一系列的体感游戏!!!是不是很激动呢? 首先我们来编摄像头类的: No.1拳头打幽灵 挥动头就能打到幽灵了哟! 具体程序如下 ...
- C#开发体感游戏 Kinect应用知识
Kinect首先是一个XBox 360外接体感设备,通过无线方式捕捉动作感知.由PrimeSense提供Range Camera技术,同类产品如任天堂Wii.Play Station Move,必须让 ...
随机推荐
- 开源:Taurus.MVC 框架
为什么要创造Taurus.MVC: 记得被上一家公司忽悠去负责公司电商平台的时候,情况是这样的: 项目原版是外包给第三方的,使用:WebForm+NHibernate,代码不堪入目,Bug无限,经常点 ...
- 分布式锁1 Java常用技术方案
前言: 由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.所以自己结合实际工作中的一些经验和网上看到的一些资 ...
- 【大型网站技术实践】初级篇:借助LVS+Keepalived实现负载均衡
一.负载均衡:必不可少的基础手段 1.1 找更多的牛来拉车吧 当前大多数的互联网系统都使用了服务器集群技术,集群即将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是Web应用服务 ...
- Java基础Collection集合
1.Collection是所有集合的父类,在JDK1.5之后又加入了Iterable超级类(可以不用了解) 2.学习集合从Collection开始,所有集合都继承了他的方法 集合结构如图:
- mac osx 安装redis扩展
1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...
- [转]Patch文件结构详解
N久不来 于是不知道扔在哪儿于是放这里先 如果你觉得碍事的话 帮我扔到合适的版块去.. 导读这是一篇说明文 它介绍了标准冒险岛更新文件(*.patch;*.exe)的格式文章的最后附了一段C#的参考代 ...
- so 问题来了,你现在值多少钱?
年底了一大帮人都写着年底总结,总结一年做过的事.错过的事和做错的事.增长了多少本事,找没找到女朋友……来年做好升职加薪,要么做跳槽的准备,程序猿又开始浮躁了……. so 问题来了,你现在值多少钱? 这 ...
- 中国CIO最关心的八大问题(上)
中国CIO最关心的八大问题(上) 近期,ITValue和ValueResearch联合展开<IT决策者投资与生存状态大调查>,调查范围从关注CIO本身,延展至关注CIO所供职企业--其赖以 ...
- 【干货分享】流程DEMO-加班与调休
流程名: 加班.调休 业务描述: 加班: 工作日加班可以申请调休,也可以申请支付加班费.原则上都应申请调休:周末加班原则上申请调休:法定节假日加班支付加班费. 加班申请以半小时为单位. 当月加班不能 ...
- Open-Test 测试驱动模式与版本号管理机制
以测试用例驱动项目开发,coding/case俩条线并走模式. 1.开发人员只负责功能实现: 2.测试人员提供自测用例,研发人员jenkins持续集成项目后自动化执行自测用例,通过后方可转测试 ...