Loading...
Logo
Processing Forum
Hi,

I was just wondering if there is anyone who's brave enough to hack into the Xbox Kinect and enable it to work with processing?

If it was hacked? Did you managed to get the camera's working with processing and also the voice recognition with processing?

Any sample processing applications to share Kinect's capabilities?


FM

Replies(7)

Daniel Shiffman has written a library. It's still in it's early stages but it'll get you going nonetheless:   http://www.shiffman.net/2010/11/14/kinect-and-processing/
Victor Martins (aka pixelnerve) posted a new driver... check out his post.

CLNUI 4 Java (Kinect)
I checked Daniel Shiffman's lib and it works very well! 
The depth map provided by the kinect is very clean and very easy to manipulate.
The only issue: a super low framerate… around 8 fps (sketch, not the cam!)

Anyone with better results here?

Side note: had to switch in 32 bit mode (eclipse) to make it work.


I think the problem with the framerate is because, from reading his tweets and whatnot, Daniel started working on the processing port before the usblib was patched and is now in the midst of another professional project... so he is prioritizing... too bad for us. I spent a little time trying to update it myself, but i dont have much experience with making .JNILIBs (not to mention im not that smart!) so I reckon he will beat me to it regardless of his other commitments.

But other than the framerate and a pesky memory leak and a few other vestigial remnants from the heady hero-days of DISKinecting the Kinect from the XBOX, its totally useable and fun as hell...

if you got em, throw on ur 3D glasses and take a look:

http://www.screencast.com/users/powderly/folders/Jing/media/3b681624-3468-4c76-abe2-2e098a5b7d0c

DISKinect depthmap to old school dynamic anaglyphic 3D... red-blue and red-cyan modes.

i threw this together tonite in my copious otaku time... it works ok. especially if you tilt your screen... then it pops like Captian EO...

framerate is mud thanks to aforementioned non-patched usblib but the choppiness is really due to the screen recorder (what screen recorder doesnt suck for the mac?)

I'm using the depthmap output because the depthmap pixels and the video input pixels don't align so well... i'm still working on warping/flattening the distortion caused by (i reckon) the IR speckle's corner-stretched throw...

http://www.futurepicture.org/

atleast in my rough estimation, the mis-alignment seems to fit that skew.

maybe that is something the newer patches correct in the library (?). it could be something simpler im not considering. After that's handled, i'll draw on desaturated live video...  when i get some proper diopter red-cyan glasses (i had to make my own glasses from acetate hence the red-blue mode) i can do color... multiprojector output would make it possible to do full on polarized 3D...

this is in someway a part of my larger project to waste max time? :) and make In-real-life 4D (IRL4D). 4D cinema is hella popular where i live.

 my nights-worth of code, built using other projects on openprocessing, is below if you wanna play with it... but its really just something to give my students an idea what they can do with the kinect (i got my school to buy a few cameras for the students to play with...)

jp

// uses the shiffman.kinect library and a .vlw
Copy code
  1. /*
    ////////////////////////////////////////
    DISKinect to 3D
    by Powderly, Shiffman, Birtchnell
    November 23rd, 2010, 3:09 AM
    Seoul, South Korea

    Hwaiting!!!!!!!!!!

    For Hongik University Interactive Scripting and Interactive Design Studio

    Shiffman.kinect by Daniel Shiffman
    http://www.shiffman.net/2010/11/14/kinect-and-processing/

    OpenKinect by Hector Martin
    https://github.com/OpenKinect/libfreenect

    OfKinect and the perverse pleasure of kinect on the mac by Theo Watson
    http://vimeo.com/16734124

    Depth paint by William Birtchnell, licensed under Creative Commons Attribution-Share Alike 3.0 and GNU GPL license.
    Work: http://openprocessing.org/visuals/?visualID=10838
    License:
    http://creativecommons.org/licenses/by-sa/3.0/
    http://creativecommons.org/licenses/GPL/2.0/

    This code is licensed under (c)rap-in-the-PublicDomain 0.1
    http://fffff.at

    make your own 3D glasses:
    http://stereo.gsfc.nasa.gov/classroom/glasses.shtml

    the more you know:
    http://en.wikipedia.org/wiki/Anaglyph_image

    ////////////////////////////////////////
    */

    //kinect libraries
    import shiffman.kinect.*;

    //PImage objects
    PImage depthm;
    PImage video;
    PImage videoBorder; // pimage with border
    int border = 60;

    //2D array for depth map
    int[][] dMap = new int[1000][800];// depth map
    int depth;
    int maxOffset;
    int minOffset;

    //font file path and font object
    String   fontFilePath= "AT.vlw";
    PFont theFont;
     
    //variables for loopinbg through pixels array and depth map
    int ix,iy;
    //offsets to handle image border to avoid array out of bounds exceptions
    int xOff,xOff2,yOff;

    //PVector variables for our video size and output screen size and windowing

    PVector vidSize;
    PVector smallVid;

    int _red;
    int currentBlue;

    void setup()
    {
      vidSize = new PVector(640,480);
      smallVid = new PVector(320, 240);
     
      //load and initialize the font
      theFont = loadFont(fontFilePath);
      textFont(theFont);
     
      //create our screen cast out floats to ints
      size((int)vidSize.x,(int)vidSize.y+(int)smallVid.y,P3D);
      //like it matters... this library still has a memory leak and usb transfer problems
      //we wait for daniel to patch it... if only we were as smart as he we would do it ouselves...
      frameRate(30);
     
      //initialize the kinect opbject
      NativeKinect.init();
      // prefill our array with values... for testing purposes
      for (ix=0;ix<1000;ix++){for(iy=0;iy<800;iy++){dMap[ix][iy]=-10;}}
     
      println("init DISKinect");
     
      //intitialize three pimage objects for our live feed, depth map and 3D depthmap
      video = createImage((int)vidSize.x,(int)vidSize.y, RGB);
      depthm = createImage((int)vidSize.x,(int)vidSize.y, RGB);
      //put a border on this one so we dont go out of bounds
      videoBorder = createImage((int)vidSize.x+border,(int)vidSize.y+border,RGB);
     
      //initialize out colors
      _red = 0xff0000;
      currentBlue = 0x00ffff ;
      //initialize our 3D offset
      depth = 20;
      //a value to help us understand the maximum and minimum offsets we get using the dynamicdepth3D function for diagnostics
      maxOffset = 0;
      minOffset = 24;
     
      println("setup done...");
    }
     
    void draw()
    {
      //updates the kinect objects with data from usblib
      NativeKinect.update();
     
      //grab the pixels, update out pimage
      video.pixels = NativeKinect.getPixels();
      video.updatePixels();
     
      //grab the depthmap from the usblib, update out depthm pimage
      depthm.pixels = NativeKinect.getDepthMap();
      depthm.updatePixels();
      //copy the depthm over to the videoborder image object
      videoBorder.copy(depthm, 0, 0, video.width, video.height, border/2, border/2, (int)vidSize.x, (int)vidSize.y);
     
      //load the videoborder image into the system pixelarray pixels[]
      loadPixels();
     
      //draw our 3D onto the pimage based on a threshhold value
      //depthThresh23D();
     
      //create 3D offset based on depth information
      dynamicDepth23D();
     
      //place our images onto the screen
      //live video from usblib
      image(video,0,(int)vidSize.y,(int)smallVid.x,(int)smallVid.y);
     
      //convert the live video to chunky FFFFFAT colors
      depthThresh2Colors();
     
      // draw our depth map on the screen
      //image(depthm,(int)smallVid.x,(int)vidSize.y,(int)smallVid.x,(int)smallVid.y);
     
      //draw our FFFFFAT-ified live video on the screen
      image(video,(int)smallVid.x,(int)vidSize.y,(int)smallVid.x,(int)smallVid.y);

      //write some diagnostic text to the screen
      cPanelText();
    }

    // funtion to desaturate the image
    // we dont use this anymore but its there
    // yea it could be faster but bitshifting and hex
    // tends to cause my students to space out and
    // start checking their email in class

    void desaturate(PImage pImg){
      for(int x=0; x<pImg.width; x++)
        {
           for(int y=0; y<pImg.height; y++)
           {
             color c = pImg.get(x,y);
             float red = red(c);
             float green = green(c);
             float blue = blue(c);
             int grey = (int)(red+green+blue)/3;
             color Color =color(grey,grey,grey);
             pImg.set(x,y,Color);
         }
      }
    }

    // function to draw out red-cyan 3D onto the image
    void depthThresh23D(){
      int thresh = 75;
     // draw our 3D onto the image thank to Birtchnell
      for (iy=0;iy<(int)vidSize.y;iy++){
        int xOff = iy*(int)vidSize.x;
        int xOff2 = (iy+border/2)*videoBorder.width;
        for (ix=0;ix<(int)vidSize.x;ix++){
          //revers the logic and raise the min thresh to get a surface level forground image
          //if(green(videoBorder.pixels[xOff2+ix+border/2])>20 && green(videoBorder.pixels[xOff2+ix+border/2])<thresh ){
          if(green(videoBorder.pixels[xOff2+ix+border/2])>thresh){
            pixels[xOff+ix]= (videoBorder.pixels[xOff2+ix+border/2+depth] & _red) | (videoBorder.pixels[xOff2+ix+border/2-depth] & currentBlue);
          }else {
            pixels[xOff+ix]= videoBorder.pixels[xOff2+ix+border/2] ;
          }
        }
      }
    }

    // function to draw out red-cyan 3D onto the image
    void dynamicDepth23D(){
     // draw our 3D onto the image thank to Birtchnell
      for (iy=0;iy<(int)vidSize.y;iy++){
        int xOff = iy*(int)vidSize.x;
        int xOff2 = (iy+border/2)*videoBorder.width;
        for (ix=0;ix<(int)vidSize.x;ix++){
          //test for min depth requirement to become 3D
          if(green(videoBorder.pixels[xOff2+ix+border/2])>20){
            //create depth from depthmap field
            int tempinput = (int)green(videoBorder.pixels[xOff2+ix+border/2]);
            //adjust range for a reasonable offset
            depth = (int)map(tempinput, 30, 255, 0, 25);
            //constrain to positive numbers within our offset range
            depth = constrain(depth, 0, 25);
            pixels[xOff+ix]= (videoBorder.pixels[xOff2+ix+border/2+depth] & _red) | (videoBorder.pixels[xOff2+ix+border/2-depth] & currentBlue);
          }else{
            pixels[xOff+ix]= videoBorder.pixels[xOff2+ix+border/2] ;
          }
          //calculate max and min for diagnostics
          maxOffset= calculateMax(depth, maxOffset);
          minOffset= calculateMin(depth, minOffset);
        }
      }
    }

    //fucntion to set the 3D mode to red-blue 3D glasses or red-cyan 3D glasses
    void keyPressed(){
      if(key=='c'){
        currentBlue = 0x00ffff;
      }else if(key=='b'){
        currentBlue = 0x0000ff;
      } else if (keyCode == LEFT){
        depth--;
      } else if (keyCode == RIGHT){
        depth++;
      }
    }

    // function to pimp out (ie, slow down frame rate of) the live video with 0xff00ff and 0xfff000 and 0x000fff (FFFFFAT) colors
    //not fast, not smart, just understandable to 20 year old design students

    //also useful in understanding the distortion between the live video signal and the depth map
    //due to the way the laser scanner speckle has a skewed throw
    // http://www.futurepicture.org/

    void depthThresh2Colors(){
     
      int index=0;
      color front = 0xff00ff;
      color middle = 0x00ffff;
      color back = 0xfff000;
     
      int fthresh = 75;
      int mthresh = 20;
      int bthresh = 0;
     
      for(int y=0;y<(int)vidSize.y;y++){
        for(int x=0;x<(int)vidSize.x;x++){
          if(green(depthm.pixels[index])>=fthresh){
            video.pixels[index]= front; 
          }
         
          if((green(depthm.pixels[index])>=mthresh) && (green(depthm.pixels[index])<fthresh)){
            video.pixels[index]= middle; 
          }
         
          if((green(depthm.pixels[index])>=bthresh) && (green(depthm.pixels[index])<mthresh)){
            video.pixels[index]= back; 
          }
         
          index++;
        }
      }
    }

    int calculateMax(int inVal, int inMax){
      inMax = max(inVal, inMax);
      return inMax;
    }

    int calculateMin(int inVal, int inMin){
      inMin = min(inVal, inMin);
      return inMin;
    }

    void cPanelText(){
      pushMatrix();
      fill(150);
      textSize(15);
      text("fps = " + frameRate, 20, height- 35);
      text("depth = " + depth, 20, height-20);
      text("min = " + minOffset + " " + "max = " + maxOffset, 20, height-5);
      popMatrix();
    }

Hello all!  Yes, I am so sorry about not updating the library.  Basically I found a full day free when the kinect first came out and hacked something together very quickly with the original driver (with the slow framerate).  I am planning on revisiting the library and updating it with new features, the newest openkinect driver, etc.  All of this will happen after December 3rd when my students show ( http://itp.nyu.edu/bigscreens2010/) is finished!  (I will really try to get to it sooner though.)