标签:方式 显卡 his script nec 二维 深度 img 挖掘

npm install kinect2

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 | 剪刀手,并合并中食指 |
| 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();
}
标签:方式 显卡 his script nec 二维 深度 img 挖掘
原文地址:http://www.cnblogs.com/wanbo/p/6222993.html