The new Kinect for Windows SDK library is now officially listed under the Libraries section of the Processing website. Please try and test. Feedback welcome.
The new Kinect for Windows SDK library is now officially listed under the Libraries section of the Processing website. Please try and test. Feedback welcome.
To work with the official Processing library naming convention, the Kinect for Windows SDK library was renamed to P5Kinect. You can download the new library from the original page at http://www.magicandlove.com/blog/research/kinect-for-processing-library/.
Happy coding.
The updated library is now ready. Please download at my research page. The source is also updated at the corresponding Github page.
Finally, I updated the original PKinect Processing library for the Microsoft Kinect camera with the latest Kinect for Windows SDK 1.8 and built with Java JRE 1.7 update 51. It was tested in the latest Processing version 2.1.1.
The testing library can be temporarily downloaded here. Place the code folder into your Processing sketch folder. The latest sources will be released in Github soon.
This is an interactive display for the Domain Mall public art project, with Otto Li. The mall is in Yau Tong, next to the MTR station. Two Kinect cameras capture the participant images to react with the animation. The season and weather information trigger further variations of the visual imageries.
The Kinect for Processing library page is now ready with documentation, example, download and source codes. Happy coding.
This is a more or less finished version of the Kinect for Processing library. It includes the basic skeleton tracking, the RGB image, depth image and a mask image. I shall move the related posts to the research page with more documentation on the data structure and method description. Stay tune.
The sample Processing code:
import pKinect.PKinect; import pKinect.SkeletonData; PKinect kinect; PFont font; ArrayList<SkeletonData> bodies; PImage img; 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); img = loadImage("background.png"); } void draw() { background(0); image(kinect.GetImage(), 320, 0, 320, 240); image(kinect.GetDepth(), 320, 240, 320, 240); image(img, 0, 240, 320, 240); image(kinect.GetMask(), 0, 240, 320, 240); for (int i=0; i<bodies.size(); i++) { drawSkeleton(bodies.get(i)); drawPosition(bodies.get(i)); } } void mousePressed() { println(frameRate); } void drawPosition(SkeletonData _s) { noStroke(); fill(0, 100, 255); String s1 = str(_s.dwTrackingID); text(s1, _s.position.x*width/2, _s.position.y*height/2); } 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, 255, 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/2, _s.skeletonPositions[_j1].y*height/2, _s.skeletonPositions[_j2].x*width/2, _s.skeletonPositions[_j2].y*height/2); } } void appearEvent(SkeletonData _s) { if (_s.trackingState == PKinect.NUI_SKELETON_NOT_TRACKED) { return; } synchronized(bodies) { bodies.add(_s); } } 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); } } } } 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; } } } } |
You can download the example and the library here.
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:
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.
I found this Java wrapper Jnet for Eclipse for the Kinect for Windows driver.