
This program uses the depth sensors to track multiple users. It will display the skeleton structure on a tracked user. The “confidence level” is a number between 0 and 1 that the kinect will output to show how confident it is tracking that user. I’ve set the confidence level to be at least 0.5 to start tracking the skeleton. The program will select a color to draw based on the user id and draw the skeleton over the user being tracked. On the previous version of SimpleOpenNI, you had to use the “psy” pose to calibrate the tracked user. This is no longer needed and the user can be instantly tracked as soon as it enters the kinect’s field of vision.
import SimpleOpenNI.*;
// create kinect object
SimpleOpenNI kinect;
// image storage from kinect
PImage kinectDepth;
// int of each user being tracked
int[] userID;
// user colors
color[] userColor = new color[]{
color(255,0,0),
color(0,255,0),
color(0,0,255),
color(255,255,0),
color(255,0,255),
color(0,255,255)
};
// postion of head to draw circle
PVector headPosition = new PVector();
// turn headPosition into scalar form
float distanceScalar;
// diameter of head drawn in pixels
float headSize = 200;
// threshold of level of confidence
float confidenceLevel = 0.5;
// the current confidence level that the kinect is tracking
float confidence;
// vector of tracked head for confidence checking
PVector confidenceVector = new PVector();
/*---------------------------------------------------------------
Starts new kinect object and enables skeleton tracking.
Draws window
----------------------------------------------------------------*/
void setup(){
// start a new kinect object
kinect = new SimpleOpenNI(this);
// enable depth sensor
kinect.enableDepth();
// enable skeleton generation for all joints
kinect.enableUser();
// draw thickness of drawer
strokeWeight(3);
// smooth out drawing
smooth();
// create a window the size of the depth information
size(kinect.depthWidth(), kinect.depthHeight());
}
/*---------------------------------------------------------------
Updates Kinect. Gets users tracking and draws skeleton and
head if confidence of tracking is above threshold
----------------------------------------------------------------*/
void draw(){
// update the camera
kinect.update();
// get Kinect data
kinectDepth = kinect.depthImage();
// draw depth image at coordinates (0,0)
image(kinectDepth,0,0);
// get all user IDs of tracked users
userID = kinect.getUsers();
// loop through each user to see if tracking
for(int i=0;i confidenceLevel){
// change draw color based on hand id#
stroke(userColor[(i)]);
// fill the ellipse with the same color
fill(userColor[(i)]);
// draw the rest of the body
drawSkeleton(userID[i]);
}
}
}
}
/*---------------------------------------------------------------
Draw the skeleton of a tracked user. Input is userID
----------------------------------------------------------------*/
void drawSkeleton(int userId){
// get 3D position of head
kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_HEAD,headPosition);
// convert real world point to projective space
kinect.convertRealWorldToProjective(headPosition,headPosition);
// create a distance scalar related to the depth in z dimension
distanceScalar = (525/headPosition.z);
// draw the circle at the position of the head with the head size scaled by the distance scalar
ellipse(headPosition.x,headPosition.y, distanceScalar*headSize,distanceScalar*headSize);
//draw limb from head to neck
kinect.drawLimb(userId, SimpleOpenNI.SKEL_HEAD, SimpleOpenNI.SKEL_NECK);
//draw limb from neck to left shoulder
kinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_LEFT_SHOULDER);
//draw limb from left shoulde to left elbow
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_LEFT_ELBOW);
//draw limb from left elbow to left hand
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_ELBOW, SimpleOpenNI.SKEL_LEFT_HAND);
//draw limb from neck to right shoulder
kinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_RIGHT_SHOULDER);
//draw limb from right shoulder to right elbow
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_RIGHT_ELBOW);
//draw limb from right elbow to right hand
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_RIGHT_HAND);
//draw limb from left shoulder to torso
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
//draw limb from right shoulder to torso
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
//draw limb from torso to left hip
kinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_LEFT_HIP);
//draw limb from left hip to left knee
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_HIP, SimpleOpenNI.SKEL_LEFT_KNEE);
//draw limb from left knee to left foot
kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_KNEE, SimpleOpenNI.SKEL_LEFT_FOOT);
//draw limb from torse to right hip
kinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_RIGHT_HIP);
//draw limb from right hip to right knee
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_RIGHT_KNEE);
//draw limb from right kneee to right foot
kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_KNEE, SimpleOpenNI.SKEL_RIGHT_FOOT);
}
/*---------------------------------------------------------------
When a new user is found, print new user detected along with
userID and start pose detection. Input is userID
----------------------------------------------------------------*/
void onNewUser(SimpleOpenNI curContext, int userId){
println("New User Detected - userId: " + userId);
// start tracking of user id
curContext.startTrackingSkeleton(userId);
}
/*---------------------------------------------------------------
Print when user is lost. Input is int userId of user lost
----------------------------------------------------------------*/
void onLostUser(SimpleOpenNI curContext, int userId){
// print user lost and user id
println("User Lost - userId: " + userId);
}
/*---------------------------------------------------------------
Called when a user is tracked.
----------------------------------------------------------------*/
void onVisibleUser(SimpleOpenNI curContext, int userId){
}