This program is similar to the basic skeleton tracking but also extracts position datas is he. This program will display the angle of all 4 major joints in your body in radians. This is helpful for robotic applications.
import SimpleOpenNI.*; /*--------------------------------------------------------------- Variables ----------------------------------------------------------------*/ // 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(); // vector to scalar ratio float vectorScalar = 525; // size of drawn dot on each jpint float dotSize = 30; // Vector values for all joints PVector SKEL_HEAD = new PVector(); PVector SKEL_LEFT_SHOULDER = new PVector(); PVector SKEL_LEFT_ELBOW = new PVector(); PVector SKEL_LEFT_HAND = new PVector(); PVector SKEL_RIGHT_SHOULDER = new PVector(); PVector SKEL_RIGHT_ELBOW = new PVector(); PVector SKEL_RIGHT_HAND = new PVector(); PVector SKEL_TORSO = new PVector(); PVector SKEL_LEFT_HIP = new PVector(); PVector SKEL_LEFT_KNEE = new PVector(); PVector SKEL_LEFT_FOOT = new PVector(); PVector SKEL_RIGHT_HIP = new PVector(); PVector SKEL_RIGHT_KNEE = new PVector(); PVector SKEL_RIGHT_FOOT = new PVector(); // z coordinates of each limb float SKEL_HEADZ; float SKEL_LEFT_SHOULDERZ; float SKEL_LEFT_ELBOWZ; float SKEL_LEFT_HANDZ; float SKEL_RIGHT_SHOULDERZ; float SKEL_RIGHT_ELBOWZ; float SKEL_RIGHT_HANDZ; float SKEL_TORSOZ; float SKEL_LEFT_HIPZ; float SKEL_LEFT_KNEEZ; float SKEL_LEFT_FOOTZ; float SKEL_RIGHT_HIPZ; float SKEL_RIGHT_KNEEZ; float SKEL_RIGHT_FOOTZ; // angle variables float leftShoulderElbowX; float leftShoulderElbowY; float leftShoulderElbowZ; float leftWristElbowX; float leftWristElbowY; float leftWristElbowZ; float rightShoulderElbowX; float rightShoulderElbowY; float rightShoulderElbowZ; float rightWristElbowX; float rightWristElbowY; float rightWristElbowZ; float leftHipKneeX; float leftHipKneeY; float leftHipKneeZ; float leftFootKneeX; float leftFootKneeY; float leftFootKneeZ; float rightHipKneeX; float rightHipKneeY; float rightHipKneeZ; float rightFootKneeX; float rightFootKneeY; float rightFootKneeZ; // actual angles in radians of knees and elbows float leftElbowAngle; float rightElbowAngle; float leftKneeAngle; float rightKneeAngle; /*--------------------------------------------------------------- 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;iconfidenceLevel){ // change draw color based on hand id# stroke(userColor[(i)]); // fill the ellipse with the same color fill(userColor[(i)]); // get coordinates of all joints getCoordinates(userID[i]); // subtract vectors of limbs subtractVectors(); // get angles of joints getJointAngles(); } } } } /*--------------------------------------------------------------- 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){ } /*--------------------------------------------------------------- Gets XYZ coordinates of all joints of tracked user and draws a small circle on each joint ----------------------------------------------------------------*/ void getCoordinates(int userID){ // get postion of all joints kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_HEAD,SKEL_HEAD); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_SHOULDER,SKEL_LEFT_SHOULDER); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_ELBOW,SKEL_LEFT_ELBOW); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_HAND,SKEL_LEFT_HAND); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_SHOULDER,SKEL_RIGHT_SHOULDER); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_ELBOW,SKEL_RIGHT_ELBOW); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_HAND,SKEL_RIGHT_HAND); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_TORSO,SKEL_TORSO); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_HIP,SKEL_LEFT_HIP); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_KNEE,SKEL_LEFT_KNEE); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_LEFT_FOOT,SKEL_LEFT_FOOT); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_HIP,SKEL_RIGHT_HIP); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_KNEE,SKEL_RIGHT_KNEE); kinect.getJointPositionSkeleton(userID, SimpleOpenNI.SKEL_RIGHT_FOOT,SKEL_RIGHT_FOOT); // convert real world point to projective space kinect.convertRealWorldToProjective(SKEL_HEAD,SKEL_HEAD); kinect.convertRealWorldToProjective(SKEL_LEFT_SHOULDER,SKEL_LEFT_SHOULDER); kinect.convertRealWorldToProjective(SKEL_LEFT_ELBOW,SKEL_LEFT_ELBOW); kinect.convertRealWorldToProjective(SKEL_LEFT_HAND,SKEL_LEFT_HAND); kinect.convertRealWorldToProjective(SKEL_RIGHT_SHOULDER,SKEL_RIGHT_SHOULDER); kinect.convertRealWorldToProjective(SKEL_RIGHT_ELBOW,SKEL_RIGHT_ELBOW); kinect.convertRealWorldToProjective(SKEL_RIGHT_HAND,SKEL_RIGHT_HAND); kinect.convertRealWorldToProjective(SKEL_TORSO,SKEL_TORSO); kinect.convertRealWorldToProjective(SKEL_LEFT_HIP,SKEL_LEFT_HIP); kinect.convertRealWorldToProjective(SKEL_LEFT_KNEE,SKEL_LEFT_KNEE); kinect.convertRealWorldToProjective(SKEL_LEFT_FOOT,SKEL_LEFT_FOOT); kinect.convertRealWorldToProjective(SKEL_RIGHT_HIP,SKEL_RIGHT_HIP); kinect.convertRealWorldToProjective(SKEL_RIGHT_KNEE,SKEL_RIGHT_KNEE); kinect.convertRealWorldToProjective(SKEL_RIGHT_FOOT,SKEL_RIGHT_FOOT); // scale z vector of each joint to scalar form SKEL_HEADZ = (vectorScalar/SKEL_HEAD.z); SKEL_LEFT_SHOULDERZ = (vectorScalar/SKEL_LEFT_SHOULDER.z); SKEL_LEFT_ELBOWZ = (vectorScalar/SKEL_LEFT_ELBOW.z); SKEL_LEFT_HANDZ = (vectorScalar/SKEL_LEFT_HAND.z); SKEL_RIGHT_SHOULDERZ = (vectorScalar/SKEL_RIGHT_SHOULDER.z); SKEL_RIGHT_ELBOWZ = (vectorScalar/SKEL_RIGHT_ELBOW.z); SKEL_RIGHT_HANDZ = (vectorScalar/SKEL_RIGHT_HAND.z); SKEL_TORSOZ = (vectorScalar/SKEL_TORSO.z); SKEL_LEFT_HIPZ = (vectorScalar/SKEL_LEFT_HIP.z); SKEL_LEFT_KNEEZ = (vectorScalar/SKEL_LEFT_KNEE.z); SKEL_LEFT_FOOTZ = (vectorScalar/SKEL_LEFT_FOOT.z); SKEL_RIGHT_HIPZ = (vectorScalar/SKEL_RIGHT_HIP.z); SKEL_RIGHT_KNEEZ = (vectorScalar/SKEL_RIGHT_KNEE.z); SKEL_RIGHT_FOOTZ = (vectorScalar/SKEL_RIGHT_FOOT.z); // fill the dot color by the user id fill(userColor[userID-1]); // draw the circle at the position of the joint with the // diameter dependent on the z axis ellipse(SKEL_HEAD.x,SKEL_HEAD.y,SKEL_HEADZ*dotSize,SKEL_HEADZ*dotSize); ellipse(SKEL_LEFT_SHOULDER.x,SKEL_LEFT_SHOULDER.y,SKEL_LEFT_SHOULDERZ*dotSize,SKEL_LEFT_SHOULDERZ*dotSize); ellipse(SKEL_LEFT_ELBOW.x,SKEL_LEFT_ELBOW.y,SKEL_LEFT_ELBOWZ*dotSize,SKEL_LEFT_ELBOWZ*dotSize); ellipse(SKEL_LEFT_HAND.x,SKEL_LEFT_HAND.y,SKEL_LEFT_HANDZ*dotSize,SKEL_LEFT_HANDZ*dotSize); ellipse(SKEL_RIGHT_SHOULDER.x,SKEL_RIGHT_SHOULDER.y,SKEL_RIGHT_SHOULDERZ*dotSize,SKEL_RIGHT_SHOULDERZ*dotSize); ellipse(SKEL_RIGHT_ELBOW.x,SKEL_RIGHT_ELBOW.y,SKEL_RIGHT_ELBOWZ*dotSize,SKEL_RIGHT_ELBOWZ*dotSize); ellipse(SKEL_RIGHT_HAND.x,SKEL_RIGHT_HAND.y,SKEL_RIGHT_HANDZ*dotSize,SKEL_RIGHT_HANDZ*dotSize); ellipse(SKEL_TORSO.x,SKEL_TORSO.y,SKEL_TORSOZ*dotSize,SKEL_TORSOZ*dotSize); ellipse(SKEL_LEFT_HIP.x,SKEL_LEFT_HIP.y,SKEL_LEFT_HIPZ*dotSize,SKEL_LEFT_HIPZ*dotSize); ellipse(SKEL_LEFT_KNEE.x,SKEL_LEFT_KNEE.y,SKEL_LEFT_KNEEZ*dotSize,SKEL_LEFT_KNEEZ*dotSize); ellipse(SKEL_LEFT_FOOT.x,SKEL_LEFT_FOOT.y,SKEL_LEFT_FOOTZ*dotSize,SKEL_LEFT_FOOTZ*dotSize); ellipse(SKEL_RIGHT_HIP.x,SKEL_RIGHT_HIP.y,SKEL_RIGHT_HIPZ*dotSize,SKEL_RIGHT_HIPZ*dotSize); ellipse(SKEL_RIGHT_KNEE.x,SKEL_RIGHT_KNEE.y,SKEL_RIGHT_KNEEZ*dotSize,SKEL_RIGHT_KNEEZ*dotSize); ellipse(SKEL_RIGHT_FOOT.x,SKEL_RIGHT_FOOT.y,SKEL_RIGHT_FOOTZ*dotSize,SKEL_RIGHT_FOOTZ*dotSize); } /*--------------------------------------------------------------- Subtracts each vector from each limb combination from each other ----------------------------------------------------------------*/ void subtractVectors() { // take vector[] shoulder and subtract from vector[] elbow leftShoulderElbowX = SKEL_LEFT_SHOULDER.x - SKEL_LEFT_ELBOW.x; leftShoulderElbowY = SKEL_LEFT_SHOULDER.y - SKEL_LEFT_ELBOW.y; leftShoulderElbowZ = SKEL_LEFT_SHOULDER.z - SKEL_LEFT_ELBOW.z; // take vector[] hand and subtract from vector[] elbow leftWristElbowX = SKEL_LEFT_HAND.x - SKEL_LEFT_ELBOW.x; leftWristElbowY = SKEL_LEFT_HAND.y - SKEL_LEFT_ELBOW.y; leftWristElbowZ = SKEL_LEFT_HAND.z - SKEL_LEFT_ELBOW.z; // take vector[] shoulder and subtract from vector[] elbow rightShoulderElbowX = SKEL_RIGHT_SHOULDER.x - SKEL_RIGHT_ELBOW.x; rightShoulderElbowY = SKEL_RIGHT_SHOULDER.y - SKEL_RIGHT_ELBOW.y; rightShoulderElbowZ = SKEL_RIGHT_SHOULDER.z - SKEL_RIGHT_ELBOW.z; // take vector[] hand and subtract from vector[] elbow rightWristElbowX = SKEL_RIGHT_HAND.x - SKEL_RIGHT_ELBOW.x; rightWristElbowY = SKEL_RIGHT_HAND.y - SKEL_RIGHT_ELBOW.y; rightWristElbowZ = SKEL_RIGHT_HAND.z - SKEL_RIGHT_ELBOW.z; // take vector[] hip and subtract from vector[] knee leftHipKneeX = SKEL_LEFT_HIP.x - SKEL_LEFT_KNEE.x; leftHipKneeY = SKEL_LEFT_HIP.y - SKEL_LEFT_KNEE.y; leftHipKneeZ = SKEL_LEFT_HIP.z - SKEL_LEFT_KNEE.z; // take vector[] foot and subtract from vector[] knee leftFootKneeX = SKEL_LEFT_FOOT.x - SKEL_LEFT_KNEE.x; leftFootKneeY = SKEL_LEFT_FOOT.y - SKEL_LEFT_KNEE.y; leftFootKneeZ = SKEL_LEFT_FOOT.z - SKEL_LEFT_KNEE.z; // take vector[] hip and subtract from vector[] knee rightHipKneeX = SKEL_RIGHT_HIP.x - SKEL_RIGHT_KNEE.x; rightHipKneeY = SKEL_RIGHT_HIP.y - SKEL_RIGHT_KNEE.y; rightHipKneeZ = SKEL_RIGHT_HIP.z - SKEL_RIGHT_KNEE.z; // take vector[] foot and subtract from vector[] knee rightFootKneeX = SKEL_RIGHT_FOOT.x - SKEL_RIGHT_KNEE.x; rightFootKneeY = SKEL_RIGHT_FOOT.y - SKEL_RIGHT_KNEE.y; rightFootKneeZ = SKEL_RIGHT_FOOT.z - SKEL_RIGHT_KNEE.z; } /*--------------------------------------------------------------- Gets angles of joints based on Z axis and prints them. Example math: Let the coordinates of elbow (x,y,z) be denoted as E, shoulder S, and wrist W. Define the vector EW = W - E = (x_w-x_e, y_w-y_e, z_w,z_e) and ES = S - E. Then the angle between vector EW and vector ES is given by arccos(EW dot ES / (mag(EW) * mag (ES)). Where mag(X) is the magnitude of a vector, given by sqrt(x2 + y2 + z2 ), and A dot B is the dot product of vectors A and B, given by A_x*B_x + A_y*B_y + A_z*B_z ----------------------------------------------------------------*/ void getJointAngles() { leftElbowAngle = acos((leftShoulderElbowX*leftWristElbowX+leftShoulderElbowY*leftWristElbowY+leftShoulderElbowZ*leftWristElbowZ)/(sqrt(leftWristElbowX*leftWristElbowX+leftWristElbowY*leftWristElbowY+leftWristElbowZ*leftWristElbowZ)*(sqrt(leftShoulderElbowX*leftShoulderElbowX+leftShoulderElbowY*leftShoulderElbowY+leftShoulderElbowZ*leftShoulderElbowZ)))); rightElbowAngle = acos((rightShoulderElbowX*rightWristElbowX+rightShoulderElbowY*rightWristElbowY+rightShoulderElbowZ*rightWristElbowZ)/(sqrt(rightWristElbowX*rightWristElbowX+rightWristElbowY*rightWristElbowY+rightWristElbowZ*rightWristElbowZ)*(sqrt(rightShoulderElbowX*rightShoulderElbowX+rightShoulderElbowY*rightShoulderElbowY+rightShoulderElbowZ*rightShoulderElbowZ)))); leftKneeAngle = acos((leftHipKneeX*leftFootKneeX+leftHipKneeY*leftFootKneeY+leftHipKneeZ*leftFootKneeZ)/(sqrt(leftFootKneeX*leftFootKneeX+leftFootKneeY*leftFootKneeY+leftFootKneeZ*leftFootKneeZ)*(sqrt(leftHipKneeX*leftHipKneeX+leftHipKneeY*leftHipKneeY+leftHipKneeZ*leftHipKneeZ)))); rightKneeAngle = acos((rightHipKneeX*rightFootKneeX+rightHipKneeY*rightFootKneeY+rightHipKneeZ*rightFootKneeZ)/(sqrt(rightFootKneeX*rightFootKneeX+rightFootKneeY*rightFootKneeY+rightFootKneeZ*rightFootKneeZ)*(sqrt(rightHipKneeX*rightHipKneeX+rightHipKneeY*rightHipKneeY+rightHipKneeZ*rightHipKneeZ)))); // print angles print("Left elbow angle: "); println(leftElbowAngle); print("Right elbow angle: "); println(rightElbowAngle); print("Left knee angle: "); println(leftKneeAngle); print("Right knee angle: "); println(rightKneeAngle); }