-(video above)-
If it doesn’t play go to this link:
http://vimeo.com/36267446
Skeleton Tracking with Kinect & Processing
/* This 'experimental' code adds features from Greg Borenstein's & Dan O'Sullivan's examples. Skeleton Tracking with semi-voluptuous muscles -Tak Cheung, Computational Cameras 02-06-2012 */ import SimpleOpenNI.*; SimpleOpenNI kinect; float DLUAflip; float DLLAflip; float DRUAflip; float DRLAflip; float dLeftLowerArm; float RightArmAngle; float dRightLowerArm; float LeftArmAngle; float pumpPrevious = 0; float pumpNext = 0; float pumpValue; float depthLeftShoulder; float dLeftShoulder; float depthRightShoulder; float dRightShoulder; float DShoulder; //boolean leftMuscle = false; String muscle = ""; void setup() { kinect = new SimpleOpenNI(this); kinect.enableDepth(); kinect.enableRGB(); kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL); kinect.setMirror(true); size(640, 480); fill(255, 0, 0); stroke(0, 0, 255); strokeWeight(3); smooth(); PFont myFont = createFont("FFScala", 42); textFont(myFont); } void draw() { kinect.update(); float headx = SimpleOpenNI.SKEL_HEAD; ellipse(headx, headx, 100, 100); // PImage rgbImage = kinect.rgbImage(); //---> to display as RGB image // image(rgbImage, 0, 0); image(kinect.depthImage(), 0, 0); //---> to display as depth image //text(" ", 100, 100); //---> testing the code // text(pumpValue, 100, 200); // text(dLeftShoulder, 100, 300); IntVector userList = new IntVector(); kinect.getUsers(userList); if (userList.size() > 0) { int userId = userList.get(0); if ( kinect.isTrackingSkeleton(userId)) { drawSkeleton(userId); } /////////////////////////////////////--->This is where tracking limbs begin. PVector leftHand = new PVector(); kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_LEFT_HAND, leftHand); PVector convertedLeftHand = new PVector(); kinect.convertRealWorldToProjective(leftHand, convertedLeftHand); PVector rightHand = new PVector(); kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_RIGHT_HAND, rightHand); PVector convertedRightHand = new PVector(); kinect.convertRealWorldToProjective(rightHand, convertedRightHand); PVector leftElbow = new PVector(); kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_LEFT_ELBOW, leftElbow); PVector convertedLeftElbow = new PVector(); kinect.convertRealWorldToProjective(leftElbow, convertedLeftElbow); PVector rightElbow = new PVector(); kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, rightElbow); PVector convertedRightElbow = new PVector(); kinect.convertRealWorldToProjective(rightElbow, convertedRightElbow); PVector leftShoulder = new PVector(); kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, leftShoulder); PVector convertedLeftShoulder = new PVector(); kinect.convertRealWorldToProjective(leftShoulder, convertedLeftShoulder); PVector rightShoulder = new PVector(); kinect.getJointPositionSkeleton(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, rightShoulder); PVector convertedRightShoulder = new PVector(); kinect.convertRealWorldToProjective(rightShoulder, convertedRightShoulder); /////////////////////////////////////--->Tracking angles of Arm. float LeftUpperArm = atan2(convertedLeftElbow.x - convertedLeftShoulder.x, convertedLeftElbow.y - convertedLeftShoulder.y); float dLeftUpperArm = degrees(LeftUpperArm); if (dLeftUpperArm =180) { DLLAflip = map (dLeftLowerArm, 360, 180, 0, -180); } else { DLLAflip = dLeftLowerArm; } LeftArmAngle = abs(DLUAflip + DLLAflip);//---> adding the angles together. float RightUpperArm = atan2(convertedRightElbow.x - convertedRightShoulder.x, convertedRightElbow.y - convertedRightShoulder.y); float dRightUpperArm = degrees(RightUpperArm); if (dRightUpperArm =180) { DRLAflip = map (dRightLowerArm, 360, 180, 0, -180); } else { DRLAflip = dRightLowerArm; } RightArmAngle = abs(DRUAflip + DRLAflip);//---> adding the angles together. float LeftShoulder = atan2(convertedLeftShoulder.x - convertedRightShoulder.x, convertedLeftShoulder.y - convertedRightShoulder.y); dLeftShoulder = degrees(LeftShoulder); if (dLeftShoulder Tracking/mapping depth. if (depthLeftShoulder=2200) { depthLeftShoulder=2200; } depthLeftShoulder = map(convertedLeftElbow.z, 700, 2200, 1, .5); if (depthRightShoulder=2200) { depthRightShoulder=2200; } depthRightShoulder = map(convertedRightElbow.z, 700, 2200, 1, .5); /////////////////////////////////////---> Calculating Arm Location Before Drawing Muscle. float UseLeftArmAngle = LeftArmAngle; if (UseLeftArmAngle =130) { UseLeftArmAngle = 130; } float musclePoint1 = map(UseLeftArmAngle, 30, 130, 100, 0); float musclePoint2 = map(UseLeftArmAngle, 30, 130, 50, 0); float UseRightArmAngle = RightArmAngle; if (UseRightArmAngle =130) { UseRightArmAngle = 130; } float musclePoint5 = map(UseRightArmAngle, 30, 130, 0, -100); float musclePoint6 = map(UseRightArmAngle, 30, 130, 0, 50); float musclePoint7 = map(UseRightArmAngle, 30, 130, 50, 0); /////////////////////////////////////---> Pump Action to Muscle. pumpPrevious = pumpValue; pumpNext = LeftArmAngle; pumpValue = abs(pumpPrevious - pumpNext); /////////////////////////////////////---> Yes or No Left Muscle. if (convertedLeftHand.y < convertedLeftShoulder.y) { pushMatrix(); fill(0); strokeWeight(2); stroke(255); translate(convertedLeftShoulder.x, convertedLeftShoulder.y); scale(depthLeftShoulder); rotate(map(LeftUpperArm, 0, 360, 360, 0)-.29); //rect(0, 0, -lineLength/2, -lineLength/2); //bezier(-lineLength/2, 0, -50*lineLength/50, -50*lineLength/50, -100/lineLength/2, -100/lineLength/2, 0, 0); bezier(musclePoint1, 0, musclePoint1, musclePoint2*1.2, 0, musclePoint2*1.2, 0, 0); popMatrix(); } if (convertedRightHand.y < convertedRightShoulder.y) { pushMatrix(); fill(0); strokeWeight(2); stroke(255); translate(convertedRightShoulder.x, convertedRightShoulder.y); scale(depthRightShoulder); rotate(map(RightUpperArm, 0, 360, 360, 0)-3.4); //rect(0, 0, -lineLength/2, -lineLength/2); //bezier(-lineLength/2, 0, -50*lineLength/50, -50*lineLength/50, -100/lineLength/2, -100/lineLength/2, 0, 0); bezier(0, 0, 0, musclePoint6*1.2, musclePoint5, musclePoint6*1.2, musclePoint5, 0); popMatrix(); } if (convertedLeftHand.x > convertedLeftElbow.x && convertedLeftHand.y > convertedLeftShoulder.y) { //&& convertedLeftHand.y > convertedLeftElbow.y pushMatrix(); fill(0); strokeWeight(2); stroke(255); translate(convertedLeftShoulder.x, convertedLeftShoulder.y); //scale(depthLeftShoulder); rotate(map(LeftShoulder, 0, 360, 360, 0)+2.85); bezier(0, 0, 0, musclePoint2*1.35, abs(convertedLeftShoulder.x-convertedRightShoulder.x)/2, musclePoint2*1.35, abs(convertedLeftShoulder.x-convertedRightShoulder.x)/2, 0); strokeWeight(1); //ellipse( abs(convertedLeftShoulder.x-convertedRightShoulder.x)/4, musclePoint2*1.25, 10, 10); popMatrix(); } if (convertedRightHand.x < convertedRightElbow.x && convertedRightHand.y > convertedRightShoulder.y) { //&& convertedLeftHand.y > convertedLeftElbow.y pushMatrix(); fill(0); strokeWeight(2); stroke(255); translate(abs(convertedRightShoulder.x+convertedLeftShoulder.x)/2, abs(convertedRightShoulder.y+convertedLeftShoulder.y)/2); //scale(depthLeftShoulder); float test = map(mouseX, 0, 640, .0, 6.4); println(test); rotate(map(RightShoulder, 0, 360, 360, 0)+6); //ellipse(abs(convertedRightShoulder.x-convertedLeftShoulder.x)/2, 0, 30, 30); //ellipse(0,0,15,15); bezier( abs(convertedRightShoulder.x-convertedLeftShoulder.x)/2, 0, abs(convertedRightShoulder.x-convertedLeftShoulder.x)/2, musclePoint7*1.35, 0, musclePoint7*1.35, 0, 0); strokeWeight(1); //ellipse( abs(convertedLeftShoulder.x-convertedRightShoulder.x)/4, musclePoint2*1.25, 10, 10); popMatrix(); } /* float elbowDistance = getJointDistance(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_LEFT_ELBOW); //float hdist = PVector.dist(leftHand, rightHand); println(elbowDistance ); if (elbowDistance > 450) { youAre = "Chillin'"; } else { youAre = "Guarded"; } */ } //c } void drawSkeleton(int userId) { stroke(0); strokeWeight(5); kinect.drawLimb(userId, SimpleOpenNI.SKEL_HEAD, SimpleOpenNI.SKEL_NECK); kinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_LEFT_SHOULDER); kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_LEFT_ELBOW); kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_ELBOW, SimpleOpenNI.SKEL_LEFT_HAND); kinect.drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_RIGHT_SHOULDER); kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_RIGHT_ELBOW); kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_RIGHT_HAND); kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_TORSO); kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_TORSO); kinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_LEFT_HIP); kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_HIP, SimpleOpenNI.SKEL_LEFT_KNEE); kinect.drawLimb(userId, SimpleOpenNI.SKEL_LEFT_KNEE, SimpleOpenNI.SKEL_LEFT_FOOT); kinect.drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_RIGHT_HIP); kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_RIGHT_KNEE); kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_KNEE, SimpleOpenNI.SKEL_RIGHT_FOOT); kinect.drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_LEFT_HIP); noStroke(); fill(255, 0, 0); drawJoint(userId, SimpleOpenNI.SKEL_HEAD); drawJoint(userId, SimpleOpenNI.SKEL_NECK); drawJoint(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER); drawJoint(userId, SimpleOpenNI.SKEL_LEFT_ELBOW); drawJoint(userId, SimpleOpenNI.SKEL_NECK); drawJoint(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER); drawJoint(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW); drawJoint(userId, SimpleOpenNI.SKEL_TORSO); drawJoint(userId, SimpleOpenNI.SKEL_LEFT_HIP); drawJoint(userId, SimpleOpenNI.SKEL_LEFT_KNEE); drawJoint(userId, SimpleOpenNI.SKEL_RIGHT_HIP); drawJoint(userId, SimpleOpenNI.SKEL_LEFT_FOOT); drawJoint(userId, SimpleOpenNI.SKEL_RIGHT_KNEE); drawJoint(userId, SimpleOpenNI.SKEL_LEFT_HIP); drawJoint(userId, SimpleOpenNI.SKEL_RIGHT_FOOT); drawJoint(userId, SimpleOpenNI.SKEL_RIGHT_HAND); drawJoint(userId, SimpleOpenNI.SKEL_LEFT_HAND); } float getJointDistance(int userId, int jointID1, int jointID2) { PVector joint1 = new PVector(); PVector joint2 = new PVector(); kinect.getJointPositionSkeleton(userId, jointID1, joint1); kinect.getJointPositionSkeleton(userId, jointID2, joint2); return PVector.dist(joint1, joint2); } void drawJoint(int userId, int jointID) { PVector joint = new PVector(); float confidence = kinect.getJointPositionSkeleton(userId, jointID, joint); if (confidence < 0.5) { return; } PVector convertedJoint = new PVector(); kinect.convertRealWorldToProjective(joint, convertedJoint); ellipse(convertedJoint.x, convertedJoint.y, 5, 5); } // user-tracking callbacks! void onNewUser(int userId) { println("start pose detection"); kinect.startPoseDetection("Psi", userId); } void onEndCalibration(int userId, boolean successful) { if (successful) { println(" User calibrated !!!"); kinect.startTrackingSkeleton(userId); } else { println(" Failed to calibrate user !!!"); kinect.startPoseDetection("Psi", userId); } } void onStartPose(String pose, int userId) { println("Started pose for user"); kinect.stopPoseDetection(userId); kinect.requestCalibrationSkeleton(userId, true); }