This is the new version of the Kinect for Processing library using the Kinect for Windows 1.5 SDK. In this version, I only implement the skeleton tracking, without the previous RGB image and depth image yet. For all the field, method and constant names, I try to use the same ones as in the SDK. It can have multiple skeletons and comes with three events:
- appear (new skeleton enters the screen)
- disappear (existing skeleton leaves the screen)
- move (existing skeleton stay in the screen)
Here is the example Processing code.
import pKinect.PKinect; PKinect kinect; PFont font; ArrayList<SkeletonData> bodies; void setup() { size(640, 480); background(0); kinect = new PKinect(this); bodies = new ArrayList<SkeletonData>(); smooth(); font = loadFont("LucidaSans-18.vlw"); textFont(font, 18); textAlign(CENTER); } void draw() { fill(0, 0, 0, 16); rect(0, 0, width, height); for (int i=0; i<bodies.size(); i++) { drawSkeleton(bodies.get(i)); drawPosition(bodies.get(i)); } } void drawPosition(SkeletonData _s) { noStroke(); fill(0, 255, 255); String s1 = str(_s.dwTrackingID); text(s1, _s.position.x*width, _s.position.y*height); } void drawSkeleton(SkeletonData _s) { // Body DrawBone(_s, PKinect.NUI_SKELETON_POSITION_HEAD, PKinect.NUI_SKELETON_POSITION_SHOULDER_CENTER); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_SHOULDER_CENTER, PKinect.NUI_SKELETON_POSITION_SHOULDER_LEFT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_SHOULDER_CENTER, PKinect.NUI_SKELETON_POSITION_SHOULDER_RIGHT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_SHOULDER_CENTER, PKinect.NUI_SKELETON_POSITION_SPINE); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_SHOULDER_LEFT, PKinect.NUI_SKELETON_POSITION_SPINE); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_SHOULDER_RIGHT, PKinect.NUI_SKELETON_POSITION_SPINE); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_SPINE, PKinect.NUI_SKELETON_POSITION_HIP_CENTER); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_HIP_CENTER, PKinect.NUI_SKELETON_POSITION_HIP_LEFT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_HIP_CENTER, PKinect.NUI_SKELETON_POSITION_HIP_RIGHT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_HIP_LEFT, PKinect.NUI_SKELETON_POSITION_HIP_RIGHT); // Left Arm DrawBone(_s, PKinect.NUI_SKELETON_POSITION_SHOULDER_LEFT, PKinect.NUI_SKELETON_POSITION_ELBOW_LEFT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_ELBOW_LEFT, PKinect.NUI_SKELETON_POSITION_WRIST_LEFT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_WRIST_LEFT, PKinect.NUI_SKELETON_POSITION_HAND_LEFT); // Right Arm DrawBone(_s, PKinect.NUI_SKELETON_POSITION_SHOULDER_RIGHT, PKinect.NUI_SKELETON_POSITION_ELBOW_RIGHT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_ELBOW_RIGHT, PKinect.NUI_SKELETON_POSITION_WRIST_RIGHT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_WRIST_RIGHT, PKinect.NUI_SKELETON_POSITION_HAND_RIGHT); // Left Leg DrawBone(_s, PKinect.NUI_SKELETON_POSITION_HIP_LEFT, PKinect.NUI_SKELETON_POSITION_KNEE_LEFT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_KNEE_LEFT, PKinect.NUI_SKELETON_POSITION_ANKLE_LEFT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_ANKLE_LEFT, PKinect.NUI_SKELETON_POSITION_FOOT_LEFT); // Right Leg DrawBone(_s, PKinect.NUI_SKELETON_POSITION_HIP_RIGHT, PKinect.NUI_SKELETON_POSITION_KNEE_RIGHT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_KNEE_RIGHT, PKinect.NUI_SKELETON_POSITION_ANKLE_RIGHT); DrawBone(_s, PKinect.NUI_SKELETON_POSITION_ANKLE_RIGHT, PKinect.NUI_SKELETON_POSITION_FOOT_RIGHT); } void DrawBone(SkeletonData _s, int _j1, int _j2) { noFill(); stroke(255, 200, 0); if (_s.skeletonPositionTrackingState[_j1] != PKinect.NUI_SKELETON_POSITION_NOT_TRACKED && _s.skeletonPositionTrackingState[_j2] != PKinect.NUI_SKELETON_POSITION_NOT_TRACKED) { line(_s.skeletonPositions[_j1].x*width, _s.skeletonPositions[_j1].y*height, _s.skeletonPositions[_j2].x*width, _s.skeletonPositions[_j2].y*height); } } void appearEvent(SkeletonData _s) { if (_s.trackingState == PKinect.NUI_SKELETON_NOT_TRACKED) { return; } synchronized(bodies) { bodies.add(_s); } println("appearing ..." + _s.dwTrackingID); } void disappearEvent(SkeletonData _s) { synchronized(bodies) { for (int i=bodies.size()-1; i>=0; i--) { if (_s.dwTrackingID == bodies.get(i).dwTrackingID) { bodies.remove(i); } } } println("Disappearing ... " + _s.dwTrackingID); } void moveEvent(SkeletonData _b, SkeletonData _a) { if (_a.trackingState == PKinect.NUI_SKELETON_NOT_TRACKED) { return; } synchronized(bodies) { for (int i=bodies.size()-1; i>=0; i--) { if (_b.dwTrackingID == bodies.get(i).dwTrackingID) { bodies.get(i).copy(_a); break; } } } } |
The Processing code and library can be downloaded here.