Testing Kinect Interaction: Part 3—Then There Were Two

May 1, 2018

I moved on from the prototype and started testing the two new frames with the demo code. 

 

 

Here's the modified code I used in my tests:

import org.openkinect.freenect.*;
import org.openkinect.freenect2.*;
import org.openkinect.processing.*;
import org.openkinect.tests.*;

Particle[] p = new Particle[15];

boolean sensed;

PImage img;
PImage imgB;

// Angle for rotation
float a = 0;

// We'll use a lookup table so that we don't have to repeat the math over and over
float[] depthLookUp = new float[2048];
float[] depthLookUpB = new float[2048];

float minThresh = 450;
float maxThresh = 750;

// -----

ArrayList<Kinect> multiKinect;

boolean ir = false;
boolean colorDepth = false;

int numDevices = 0;

//index to change the current device changes
int deviceIndex = 0;

void setup() {
  fullScreen(P3D);
  //size(1024, 720);

  //get the actual number of devices before creating them
  numDevices = Kinect.countDevices();
  println("number of Kinect v1 devices  "+numDevices);

  //creat the arraylist
  multiKinect = new ArrayList<Kinect>();

  //iterate though all the devices and activate them
  for (int i  = 0; i < numDevices; i++) {
    Kinect tmpKinect = new Kinect(this);
    tmpKinect.activateDevice(i);
    tmpKinect.initDepth();
    tmpKinect.enableColorDepth(colorDepth);

    multiKinect.add(tmpKinect);
  }

  // For each Kinect's image:

  img = createImage(multiKinect.get(0).width, multiKinect.get(0).height, RGB);
  imgB = createImage(multiKinect.get(1).width, multiKinect.get(1).height, RGB);

  // Lookup table for all possible depth values (0 - 2047)

  for (int i = 0; i < depthLookUp.length; i++) {
    depthLookUp[i] = rawDepthToMeters(i);
  }

  for (int i = 0; i < p.length; i++) {
    p[i] = new Particle();              // Declare every single particle
  }
}

void draw() {
  background(40);

  sensed = false;

  // SCREEN A:

  img.loadPixels();    
  pushMatrix();
  translate((width/10)*3.9, height/2, 515);// Operate on the pixels themselves.

  minThresh = 400;
  maxThresh = 820;

  int[] depth = multiKinect.get(1).getRawDepth();                // Create an array of Raw Depth Values (indexed from 0 to 2048)

  float sumX = 0; // Keep track of the average X pixels; Add up all the X's
  float sumY = 0;  // Keep track of the average Y pixels; Add up all the Y's
  float totalPixels = 0; // Keep track of the average of both pixels; Add up all the pixels picked up

  imageMode(CENTER);

  for (int x = 0; x < multiKinect.get(1).width; x++) {           // Loop through the Kinect's width and height (with skip)
    for (int y = 0; y < multiKinect.get(1).height; y++) {
      int offset = x + y*multiKinect.get(1).width;               // Create an number index for each Kinect pixel
      int d = depth[offset];                         // Convert kinect data to world xyz coordinate
      // So now, the "rawDepth" variable keeps the "getRawDepth" value from the iteration

      if (d > minThresh && d < maxThresh) {          // If the pixels fit within the range...
        img.pixels[offset] = color(255, 0, 0);       // Fill every pixel with red.

        pushMatrix();
        translate(width/2, 0);
        imgB.pixels[offset] = color(0);       // Fill every pixel with color.
        popMatrix();

        sumX += x;     // Add up all the X pixels
        sumY += y;     // Add up all the Y pixels
        totalPixels++;  // Count all the pixels picked up

        sensed = true;
      } else {
        img.pixels[offset] = color(0, 255, 0, 20);               // Else, change to green.
      }
    }
  }
  img.updatePixels();
  tint(255, 100);
  image(img, 0, 0); 

  float avgX = sumX / totalPixels;          // Create an average of the X pixels/all pixels;
  float avgY = sumY / totalPixels;          // Create an average of the Y pixels/all pixels;

  if (sensed == true && avgX > 180 && avgX < 400) { // This limits the ball only to the screen dimensions
    if (sensed == true) {
      fill(150, 0, 255);                        // Create a circle at the average point
      ellipse(avgX-width/4, avgY-height/3.5, 20, 20);
    }
    popMatrix();

    // SCREEN B: //

    pushMatrix();
    translate((width/10)*6.1, height/2, 515);// Operate on the pixels themselves.

    int[] depthL = multiKinect.get(0).getRawDepth();                // Create an array of Raw Depth Values (indexed from 0 to 2048)

    float sumXL = 0; // Keep track of the average X pixels; Add up all the X's
    float sumYL = 0;  // Keep track of the average Y pixels; Add up all the Y's
    float totalPixelsL = 0; // Keep track of the average of both pixels; Add up all the pixels picked up

    imageMode(CENTER);

    for (int x = 0; x < multiKinect.get(0).width; x++) {           // Loop through the Kinect's width and height (with skip)
      for (int y = 0; y < multiKinect.get(0).height; y++) {
        int offset = x + y*multiKinect.get(0).width;               // Create an number index for each Kinect pixel
        int d = depthL[offset];                         // Convert kinect data to world xyz coordinate
        // So now, the "rawDepth" variable keeps the "getRawDepth" value from the iteration

        if (d > minThresh && d < maxThresh) {          // If the pixels fit within the range...
          imgB.pixels[offset] = color(255, 255, 100);       // Fill every pixel with orange.

          sumXL += x;     // Add up all the X pixels
          sumYL += y;     // Add up all the Y pixels
          totalPixelsL++;  // Count all the pixels picked up

          sensed = true;
        } else {
          imgB.pixels[offset] = color(0, 255, 255);               // Else, change to light blue.
        }
      }
    }
    imgB.updatePixels();
    tint(255, 100);
    image(imgB, 0, 0); 

    float avgXL = sumXL / totalPixelsL;          // Create an average of the X pixels/all pixels;
    float avgYL = sumYL / totalPixelsL;          // Create an average of the Y pixels/all pixels;

    if (sensed == true && avgXL > 180 && avgXL < 400) { // This limits the ball only to the screen dimensions
      fill(150, 0, 255);                        // Create a circle at the average point
      ellipse(avgXL-width/4, avgYL-height/3.5, 20, 20);
    }

    popMatrix();
  }
}


// These functions come from: http://graphics.stanford.edu/~mdfisher/Kinect.html
// ^ This is a custom function created to read the raw (x, y, d) values from the Kinect.

 

float rawDepthToMeters(int depthValue) {
  if (depthValue < 2047) {
    return (float)(1.0 / ((double)(depthValue) * -0.0030711016 + 3.3309495161));
  }
  return 0.0f;
}

PVector depthToWorld(int x, int y, int depthValue) {

  final double fx_d = 1.0 / 5.9421434211923247e+02;
  final double fy_d = 1.0 / 5.9104053696870778e+02;
  final double cx_d = 3.3930780975300314e+02;
  final double cy_d = 2.4273913761751615e+02;

  PVector result = new PVector();
  double depth =  depthLookUp[depthValue];//rawDepthToMeters(depthValue);
  result.x = (float)((x - cx_d) * depth * fx_d);
  result.y = (float)((y - cy_d) * depth * fy_d);
  result.z = (float)(depth);
  return result;
}

/////

float rawDepthToMetersB(int depthValue) {
  if (depthValue < 2047) {
    return (float)(1.0 / ((double)(depthValue) * -0.0030711016 + 3.3309495161));
  }
  return 0.0f;
}

PVector depthToWorldB(int x, int y, int depthValue) {

  final double fx_d = 1.0 / 5.9421434211923247e+02;
  final double fy_d = 1.0 / 5.9104053696870778e+02;
  final double cx_d = 3.3930780975300314e+02;
  final double cy_d = 2.4273913761751615e+02;

  PVector result = new PVector();
  double depth =  depthLookUpB[depthValue];//rawDepthToMeters(depthValue);
  result.x = (float)((x - cx_d) * depth * fx_d);
  result.y = (float)((y - cy_d) * depth * fy_d);
  result.z = (float)(depth);
  return result;
}

 

Please reload

Featured Posts

Building the Set-up

April 30, 2018

1/7
Please reload

Recent Posts

April 30, 2018

April 14, 2018

March 27, 2018

Please reload

Russell Dela Bueno Balad | russellbalad@gmail.com | Hong Kong

  • Instagram - White Circle
  • SoundCloud - White Circle
  • Vimeo - White Circle
  • LinkedIn - White Circle