A KinectJS Cheat Sheet
By: Arvind Satyanarayan, Winter 2013.
To begin using KinectJS, we need to identify how many players we wish to track and, for each player, which joints and gestures we care about.
Ensure that kinect.js
is included in the head
section of your page.
document.addEventListener('DOMContentLoaded', function() {
// Joints you want to track
var JOINTS = ['HAND_RIGHT', 'HEAD'];
// A helper function we'll want to use later with coordinates
var jnt = function(j) { return JOINTS.indexOf(j); }
kinect.setUp({
players: 1, // # of players, max = 2
joints: JOINTS, // array of joints to track
relative : true, // Coordinates are now relative
meters : false, // to the center of your body.
gestures: ['ESCAPE', 'JUMP'] // array of gestures to track
})
.sessionPersist()
.modal.make('css/knctModal.css') // Green modal connection bar
.notif.make();
}
KinectJS currently supports tracking the following 20 joints:
- HEAD
- SPINE
- SHOULDER_CENTER
- SHOULDER_LEFT
- SHOULDER_RIGHT
- ELBOW_LEFT
- ELBOW_RIGHT
- HAND_LEFT
- HAND_RIGHT
- WRIST_LEFT
- WRIST_RIGHT
- HIP_CENTER
- HIP_LEFT
- HIP_RIGHT
- KNEE_LEFT
- KNEE_RIGHT
- FOOT_LEFT
- FOOT_RIGHT
- ANKLE_LEFT
- ANKLE_RIGHT
To track these joints, first register then in kinect.setUp()
and then register a joints event listener like so:
kinect.onMessage(function() {
this.sk_len; // # of people in the frame
this.coords; // A 2D array[m][n] of (x, y, z) coordinates of joints.
// m = the ID of the person (either 0 or 1)
// n = the ID of the joint, which is an index into JOINTS above
});
Because it can be difficult to remember the order in which you registered joints with KinectJS, use the jnt
helper. For example:
this.coords[0][jnt('HAND_RIGHT')]; // (x, y, z) for player 1's right hand
KinectJS currently supports 8 gestures. To track a particular gesture, you must register it's corresponding event listener. Each event listener is then notified when a player performs the appropriate gesture.
playerFound:
Fires when a player walks into the frame.kinect.addEventListener('playerFound', function(args) { // args[0] = The number of players in the frame, max 2 }
playerLost:
Fires when a player walks out of the frame.kinect.addEventListener('playerLost', function(args) { // args[0] = The number of players in the frame, max 2 }
noPlayers:
Fires when there are no players in the frame.kinect.addEventListener('noPlayers', function() { ... }
gestureSwipe:
Fires when a player performs a swipe gesture.kinect.addEventListener('gestureSwipe', function(args) { // args[0] = The player who performed the swipe // args[1] = Which joint performed the swipe // args[2] = The direction of the swipe (top, right, bottom, left) }
gestureJump:
Fires when a player jumps.kinect.addEventListener('gestureJump', function(args) { // args[0] = The player who jumped }
gestureEscape:
Fires when a player performs as "escape" gesture by raising and holding their left hand in a "waving hand" position.kinect.addEventListener('gestureEscape', function(args) { // args[0] = The player who jumped }
gestureCrank:
Fires depending on the gesture performed by both hands.gestureCrank_ON
fires when a player has both their arms extended, andgestureCrank_OFF
when contracted.kinect.addEventListener('gestureCrank_ON', function(args) { // args[0] = The player who extended their arms } kinect.addEventListener('gestureCrank_OFF', function(args) { // args[0] = The player who contracted their arms }
gestureFootLean:
Fires when a player kicks.kinect.addEventListener('gestureFootLean', function(args) { // args[0] = The player who kicked // args[1] = Which foot ("left" or "right") // args[2] = The direction of the kick ("left" or "right") }
gestureBodyTurning:
Fires when a player turns (has their shoulders angled relative to the Kinect).kinect.addEventListener('gestureBodyTurning', function(args) { // args[0] = The player who turned // args[1] = Rotation direction ("left" or "right") }
To track pixel data from the Kinect's RGB camera, simply open a socket to the RGB cam and register the appropriate event handlers. The RGB cam produces images at a resolution of 640x480.
kinect.addEventListener('openedSocket', function() {
rgbSocket = kinect.makeRGB(null, true);
rgbSocket.onerror = function(e) {
...
};
rgbSocket.onmessage = function(e) {
// e.data contains rgb data as a base-64 encoded string
};
}, false);
To work with the base-64 string as an array of pixel data, we can load it into a canvas element like so:
rgbSocket.onmessage = function(e) {
var img = new Image();
img.src = e.data;
context.drawImage(img, ...);
var pixels = context.getImageData(...);
// pixels is an array of length 4*numPixels. Each pixel is an [r g b a] value.
};
To track pixel data from the Kinect's depth camera, simply open a socket to the depth cam and register the appropriate event handlers. The depth cam produces images at a resolution of 320x240.
kinect.addEventListener('openedSocket', function() {
depthSocket = kinect.makeDepth();
depthSocket.onerror = function(e) {
...
};
depthSocket.onmessage = function(e) {
// e.data contains rgb data as a base-64 encoded string
};
}, false);
To work with the base-64 string as an array of pixel data, we can load it into a canvas element like so:
depthSocket.onmessage = function(e) {
var img = new Image();
img.src = e.data;
context.drawImage(img, ...);
var pixels = context.getImageData(...);
// pixels is an array of length 4*numPixels. Each pixel is an [r g b a] value.
};
Note: Currently, a bug in KinectJS prevents access to complete depth information. See the image comparing the output of the KinectJS depth camera socket (left) and the official Kinect SDK depth camera (right).