Friday, February 21, 2014

During Final presentation






During the presentation setup, i found that the projector and kinect camera focus & projection area have a different length, the distance difference is around 5 feet long. Therefore the equipment i prepared is not enough heigh to make the mapping together. Beside, the projector i hang on top the pillar is keep overheating because the fan couldn't run properly.

After an hour of struggle, i dismantle the vertical installation and change it to a horizontal  walk way installation. The above video and image is the demonstration for the walkway installation.

Saturday, February 15, 2014

Last tutorial session

After the last tutorial session, i had solve the minim sound conflict code.

In the evening, i go and build my acrylic container for the table surface.

In the night i had try the code with a transparent ruler and my hand too. and yeah! i manage to activate the trigger zone within  2cm from the surface!
Below is my testing video with my iMac screen.





Friday, February 7, 2014

Stacking with the audio code

for the audio, i choose minim2.2 from processing library to generate the audio.
source:http://code.compartmental.net/tools/minim/
What i used in the library is the "BandPassFilter" code that can control the sound volume and the compress sound filter.
What i faced in this problem is the sound control will crash the program when i trigger the audio.

Therefore, i had ignore this part and make some option for the screen preview 1st.

Above coding is two different calculation for additional option for the screen preview & projector preview.

Saturday, February 1, 2014

Meeting with Yee siang on 29th @ cyberjaya

After i found some bug that causes delay after the processing start after 15 minutes. An additional meeting session made with Yee Siang at Cyberjaya near his office.
In the tutorial session, Yee Siang assist me to point out and delete the coding part that having conflict that cause the bug.
The meeting only stay around 1hour as this is minor debug section.


After the debug process finally the output become smoother and wont cause any delay and crash.

Below is the 3 part of the coding after debug.

Part 1 - Average tracking point

"

import org.openkinect.*;
import org.openkinect.processing.*;


KinectTracker tracker;
Kinect kinect;


int ssizeW = 640;
int ssizeH = 480;
float heatmap[][][] = new float[2][ssizeW][ssizeH];
int index = 0;
Gradient g;

int depth[];

void setup() {
  size(ssizeW, ssizeH);
  kinect = new Kinect(this);
  tracker = new KinectTracker();


  g = new Gradient();
  g.addColor(color(0, 0, 0));
  g.addColor(color(102, 0, 102));
  g.addColor(color(0, 144, 255));
  g.addColor(color(0, 255, 207));
  g.addColor(color(51, 204, 102));
  g.addColor(color(111, 255, 0));
  g.addColor(color(191, 255, 0));
  g.addColor(color(255, 240, 0));
  g.addColor(color(255, 153, 102));
  g.addColor(color(204, 51, 0));
  g.addColor(color(153, 0, 0));

  //initialize heat map array value
  for(int i = 0; i < ssizeW; ++i)
    for(int j = 0; j < ssizeH; ++j)
      heatmap[index][i][j] = 0.0;

}

void draw() {
  background(255);

  // Run the tracking analysis
  tracker.track();
  // Show the image
  //tracker.display();

  // Let's draw the raw location
  PVector v1 = tracker.getPos();
  {
  player.play();
}


  PImage img = kinect.getDepthImage();
  depth = kinect.getRawDepth();

    for(int x = 0; x < ssizeW; x+=16)
    {
      for(int y = 0; y < ssizeH; y+=16)
      {
            int offset = ssizeW-x-1+y*ssizeW;
   
        int rawDepth = depth[offset];


        if (rawDepth < tracker.getThreshold())
        {
          apply_heat(x, y, 10, 1);
        }
        else
        {
          apply_heat(x, y, 15, -.25);

        }
      }
    }


  {

  }
  update_heatmap();
  render_heatmap();


  fill(50,100,250,200);
  noStroke();
  ellipse(v1.x,v1.y,20,20);


  int t = tracker.getThreshold();
  fill(255);
  text("threshold: " + t + "    " +  "framerate: " + (int)frameRate + "    " + "UP increase threshold, DOWN decrease threshold",10,470);
}

void keyPressed() {
  int t = tracker.getThreshold();
  if (key == CODED) {
    if (keyCode == UP) {
      t+=5;
      tracker.setThreshold(t);
    }
    else if (keyCode == DOWN) {
      t-=5;
      tracker.setThreshold(t);
    }
  }
}

void stop() {
  tracker.quit();
  super.stop();
}

void update_heatmap()
{

  for(int i = 0; i < ssizeW; i++)
  {
    for(int j = 0; j < ssizeH; j++)
    {
      heatmap[index ^ 1][i][j] = calc_pixel(i, j);
    }
  }
  index ^= 1;
}

void render_heatmap()
{
  for(int i = 0; i < ssizeW; i++)
  {
    for(int j = 0; j < ssizeH; j++)
    {
      set(i, j, g.getGradient(heatmap[index][i][j]));
    }
  }
}



float calc_pixel(int i, int j)
{
  float total = 0.0;
  int count = 0;


  for(int ii = -1; ii < 2; ii++)
  {
    for(int jj = -1; jj < 2; jj++)
    {
      if(i + ii < 0 || i + ii >= width || j + jj < 0 || j + jj >= height)
        continue;

      count++;
      total += heatmap[index][i + ii][j + jj];
    }
  }

  return total / count;
}

void apply_heat(int i, int j, int r, float delta)
{
  for(int ii = -(r / 2); ii < (r / 2); ii++)
  {
    for(int jj = -(r / 2); jj < (r / 2); jj++)
    {
      if(i + ii < 0 || i + ii >= width || j + jj < 0 || j + jj >= height)
        continue;
   
      heatmap[index][i + ii][j + jj] += delta;
      heatmap[index][i + ii][j + jj] = constrain(heatmap[index][i + ii][j + jj], 0.0, 20.0);
    }
  }
}


"


2nd Part - Kinect Tracker

"
class KinectTracker {



  // Size of kinect image
  int kw = 640;
  int kh = 480;
  int threshold = 745;

  // Raw location
  PVector loc;

  // Interpolated location
  PVector lerpedLoc;

  // Depth data
  int[] depth;


  PImage display;

  KinectTracker() {
    kinect.start();
    kinect.enableDepth(true);


    kinect.processDepthImage(true);

    display = createImage(kw,kh,PConstants.RGB);

    loc = new PVector(0,0);
    lerpedLoc = new PVector(0,0);
  }

  void track() {


    depth = kinect.getRawDepth();


    if (depth == null) return;

    float sumX = 0;
    float sumY = 0;
    float count = 0;

    for(int x = 0; x < kw; x++) {
      for(int y = 0; y < kh; y++) {

        int offset = kw-x-1+y*kw;

        int rawDepth = depth[offset];

        if (rawDepth < threshold) {
          sumX += x;
          sumY += y;
          count++;
        }
      }
    }

    if (count != 0) {
      loc = new PVector(sumX/count,sumY/count);
    }

 
    lerpedLoc.x = PApplet.lerp(lerpedLoc.x, loc.x, 0.3f);
    lerpedLoc.y = PApplet.lerp(lerpedLoc.y, loc.y, 0.3f);
  }

  PVector getLerpedPos() {
    return lerpedLoc;
  }

  PVector getPos() {
    return loc;
  }

  void display() {
    PImage img = kinect.getDepthImage();


    if (depth == null || img == null) return;


    display.loadPixels();
    for(int x = 0; x < kw; x++) {
      for(int y = 0; y < kh; y++) {
        // mirroring image
        int offset = kw-x-1+y*kw;
        // Raw depth
        int rawDepth = depth[offset];

        int pix = x+y*display.width;
        if (rawDepth < threshold) {
          // A red color instead
          display.pixels[pix] = color(150,50,50);
        }
        else {
          display.pixels[pix] = img.pixels[offset];
        }
      }
    }
    display.updatePixels();

    // Draw the image
    image(display,0,0);
  }

  void quit() {
    kinect.quit();
  }

  int getThreshold() {
    return threshold;
  }

  void setThreshold(int t) {
    threshold =  t;
  }
}

"

3rd Part- Gradient
"
class Gradient
{
  ArrayList colors;


  Gradient()
  {
    colors = new ArrayList();
  }

  void addColor(color c)
  {
    colors.add(c);
  }

  color getGradient(float value)
  {

    if(colors.size() == 0)
      return #000000;
 

    if(value <= 0.0)
      return (color)(Integer) colors.get(0);
 

    if(value >= colors.size() - 1)
      return (color)(Integer) colors.get(colors.size() -  1);
 
    int color_index = (int)value;
    color c1 = (color)(Integer) colors.get(color_index);
    color c2 = (color)(Integer) colors.get(color_index + 1);
 
    return lerpColor(c1, c2, value - color_index);
  }
}
"

Monday, January 27, 2014

Appointment with Yee xiang on 26th at bandar sunway

The problem in the coding is the kinect camera size was different with the screen resolution. The kinect camera only support 480 x 640 screen resolution and i couldn't do anythings with adjusting the resolution. Any figure above this size will crashing the processing application.

In the total of 6 hour tutorial session on monday,
We had take an option to decrease the project resolution size to make the application wont crash in the middle. Another problem i had solve today is linking the openkinect code, average track point to the gradient preview.

inorder not crashing the processing i had change the size of the pixel to "ssizew & ssizeH" to represent the hight and width of the screen.

void setup() {
  size(ssizeW, ssizeH);
  kinect = new Kinect(this);
  tracker = new KinectTracker();
 
  g = new Gradient();
  g.addColor(color(0, 0, 0));
  g.addColor(color(102, 0, 102));
  g.addColor(color(0, 144, 255));
  g.addColor(color(0, 255, 207));
  g.addColor(color(51, 204, 102));
  g.addColor(color(111, 255, 0));
  g.addColor(color(191, 255, 0));
  g.addColor(color(255, 240, 0));
  g.addColor(color(255, 153, 102));
  g.addColor(color(204, 51, 0));
  g.addColor(color(153, 0, 0));
 
What i do to link the gradient with the openkinet is changing the library
apply_heat(mouseX, mouseY, 15, -.25);
to
apply_heat(x, y, 15, -.25);
that represent the kinect tracking space to triggle it.

Beside, i had done the calculation for the color for threshold in kinect for length  calibration.

int t = tracker.getThreshold();
  fill(255);
  text("threshold: " + t + "    " +  "framerate: " + (int)frameRate + "    " + "UP increase threshold, DOWN decrease threshold",10,470);
}

void keyPressed() {
  int t = tracker.getThreshold();
  if (key == CODED) {
    if (keyCode == UP) {
      t+=5;
      tracker.setThreshold(t);
    }
    else if (keyCode == DOWN) {
      t-=5;
      tracker.setThreshold(t);
    }
  }
}


Beside, i also come out with the calculation that can make the visual more smooth

float calc_pixel(int i, int j)
{
  float total = 0.0;
  int count = 0;

 
  for(int ii = -1; ii < 2; ii++)
  {
    for(int jj = -1; jj < 2; jj++)
    {
      if(i + ii < 0 || i + ii >= width || j + jj < 0 || j + jj >= height)
        continue;

      count++;
      total += heatmap[index][i + ii][j + jj];
    }
  }
 
  return total / count;
}

void apply_heat(int i, int j, int r, float delta)
{
  for(int ii = -(r / 2); ii < (r / 2); ii++)
  {
    for(int jj = -(r / 2); jj < (r / 2); jj++)
    {
      if(i + ii < 0 || i + ii >= width || j + jj < 0 || j + jj >= height)
        continue;
     
      heatmap[index][i + ii][j + jj] += delta;
      heatmap[index][i + ii][j + jj] = constrain(heatmap[index][i + ii][j + jj], 0.0, 20.0);
    }
  }
}

Tuesday, January 21, 2014

Appointment with Yee siang on monday

During the appointment on monday, we had successfully link the openkinect code with the gradient to archived the very similar effect. But another accident happened again, after the tutorial section i was being robe at ss15 after finished the tutorial session.
My kinect camera, macbook had being robe. All the file i had done is gone and i need to start all over with sketch. I am a little bit lucky because Yee Xiang having the previous 2 week backup file so the things i need is to rush back the 2 week progress. 



So luckily am i, After i brought a new computer and kinect camera.
Yee Xiang arrange an additional tutorial session on 26th Jan in order for keeping me on the track.

Saturday, January 18, 2014

Appointment with Yee Xiang tutorial session

Everythings seems so smooth until i have another incident occure, my company lorry that being hijacked last month been found in Selangor, i need to attend police station and the court to reclaim back my lorry. So i sent a request to my guest lecturer to replacing my tutorial session on monday 20th Jan 2014.


Wednesday, January 15, 2014

During the study break

During the study break, i had found a tutorial that using processing gradient to make the whole visual came out,

Reference:
http://forum.processing.org/two/discussion/150/gradient-color-effect/p1

PImage gradientMap; // This PImage object will hold the gradient
float progress = 0; // The progress variable, a float from 0.0 to 1.0
 
// Initiate sketch
void setup() {
 
    // Set screen size and renderer
    size(200, 720, P2D);
    noStroke();
 
    // Define as much colors as you like
    color[] colors = new color[] { color(255, 0, 0), color(255, 255, 0), color(0, 255, 0), color(0, 0, 255) };
 
    // Create gradient map from the given colors
    gradientMap = createImage(1, colors.length, RGB);
    gradientMap.loadPixels();
    for(int n = 0; n < colors.length; n++)
    gradientMap.pixels[n] = colors[n];
    gradientMap.updatePixels();
 
}
 
// Render sketch
void draw() {
 
    // Fill background
    background(#d1d1d1);
 
    // Calculate progress
    progress += 0.002;
    if(progress > 1)
        progress = 1;
 
    // Calculate gradient position
    float y = height - height * progress;
    float u = gradientMap.height * progress;
 
    // Render gradient
    beginShape(QUADS);
    texture(gradientMap);
    vertex(70, y, 0, u);
    vertex(120, y, 1, u);
    vertex(120, height, 0, 0);
    vertex(70, height, 1, 0);
    endShape();

}


I decided to make my own gradient according the code above with different variation of color. therefore i come out with my own code and adjusting the color according the hue color code i get from photoshop

The gradient i had done with another .pde file that can linked with the open kinect to generate the color



 class Gradient { ArrayList colors; Gradient() { colors = new ArrayList(); } void addColor(color c) { colors.add(c); } color getGradient(float value) { if(colors.size() == 0) return #000000; if(value <= 0.0) return (color)(Integer) colors.get(0); if(value >= colors.size() - 1) return (color)(Integer) colors.get(colors.size() - 1); int color_index = (int)value; color c1 = (color)(Integer) colors.get(color_index); color c2 = (color)(Integer) colors.get(color_index + 1); return lerpColor(c1, c2, value - color_index); } }