About to lose my mind - please help!

edited March 2017 in Kinect

Hi,

Trying to use motion tracking for a sketch. I've seen all of the Shiffman videos like 5 times (he's great) and still not getting it. If someone could help me out I would really appreciate it. Using a Kinect 1 and pasting the code for the sketch I'm playing around with here.

final int nbWeeds = 125;
SeaWeed[] weeds;
PVector rootNoise = new PVector(random(123456), random(123456));
int mode = 1;
float radius = 750;
Boolean noiseOn = true;
PVector center;

void setup()
{
  size(1000, 1000, P2D);
  center = new PVector(width/2, height/2);
  strokeWeight(5);
  weeds = new SeaWeed[nbWeeds];
  for (int i = 0; i < nbWeeds; i++)
  {
    weeds[i] = new SeaWeed(i*TWO_PI/nbWeeds, 3*radius);
  }
}

void draw()
{
  //background(50);
  noStroke();
  fill(25, 15, 25);//, 50);
  rect(0, 0, width, height);
  rootNoise.add(new PVector(.05, .05));
  strokeWeight(1);
  for (int i = 0; i < nbWeeds; i++)
  {
    weeds[i].update();
  }
  stroke(200, 100, 100, 200);
  strokeWeight(4);
  noFill();
  ellipse(center.x, center.y, 2*radius, 2*radius);
}

void keyPressed()
{
  if (key == 'n')
  {
    noiseOn = !noiseOn;
  } else
  {
    mode = (mode + 1) % 2;
  }
}


class MyColor
{
  float R, G, B, Rspeed, Gspeed, Bspeed;
  final static float minSpeed = .2;
  final static float maxSpeed = 2.0;
  final static float minR = 200;
  final static float maxR = 255;
  final static float minG = 20;
  final static float maxG = 120;
  final static float minB = 100;
  final static float maxB = 140;

  MyColor()
  {
    init();
  }

  public void init()
  {
    R = random(minR, maxR);
    G = random(minG, maxG);
    B = random(minB, maxB);
    Rspeed = (random(1) > .5 ? 1 : -1) * random(minSpeed, maxSpeed);
    Gspeed = (random(1) > .5 ? 1 : -1) * random(minSpeed, maxSpeed);
    Bspeed = (random(1) > .5 ? 1 : -1) * random(minSpeed, maxSpeed);
  }

  public void update()
  {
    Rspeed = ((R += Rspeed) > maxR || (R < minR)) ? -Rspeed : Rspeed;
    Gspeed = ((G += Gspeed) > maxG || (G < minG)) ? -Gspeed : Gspeed;
    Bspeed = ((B += Bspeed) > maxB || (B < minB)) ? -Bspeed : Bspeed;
  }

  public color getColor()
  {
    return color(R, G, B);
  }
}
class SeaWeed
{
  final static float DIST_MAX = 5.5;//length of each segment
  final static float maxWidth = 50;//max width of the base line
  final static float minWidth = 11;//min width of the base line
  final static float FLOTATION = -3.5;//flotation constant
  float mouseDist;//mouse interaction distance
  int nbSegments;
  PVector[] pos;//position of each segment
  color[] cols;//colors array, one per segment
  float[] rad;
  MyColor myCol = new MyColor();
  float x, y;//origin of the weed
  float cosi, sinu;

  SeaWeed(float p_rad, float p_length)
  {
    nbSegments = (int)(p_length/DIST_MAX);
    pos = new PVector[nbSegments];
    cols = new color[nbSegments];
    rad = new float[nbSegments];
    cosi = cos(p_rad);
    sinu = sin(p_rad);
    x = width/2 + radius*cosi;
    y = height/2 + radius*sinu;
    mouseDist = 40;
    pos[0] = new PVector(x, y);
    for (int i = 1; i < nbSegments; i++)
    {
      pos[i] = new PVector(pos[i-1].x - DIST_MAX*cosi, pos[i-1].y - DIST_MAX*sinu);
      cols[i] = myCol.getColor();
      rad[i] = 3;
    }
  }

  void update()
  {
    PVector mouse = new PVector(mouseX, mouseY);

    pos[0] = new PVector(x, y);
    for (int i = 1; i < nbSegments; i++)
    {
      float n = noise(rootNoise.x + .002 * pos[i].x, rootNoise.y + .002 * pos[i].y);
      float noiseForce = (.5 - n) * 7;
      if (noiseOn)
      {
        pos[i].x += noiseForce;
        pos[i].y += noiseForce;
      }
      PVector pv = new PVector(cosi, sinu);
      pv.mult(map(i, 1, nbSegments, FLOTATION, .6*FLOTATION));
      pos[i].add(pv);

      //mouse interaction
      //if(pmouseX != mouseX || pmouseY != mouseY)
      {
        float d = PVector.dist(mouse, pos[i]);
        if (d < mouseDist)// && pmouseX != mouseX && abs(pmouseX - mouseX) < 12)
        {
          PVector tmpPV = mouse.get();       
          tmpPV.sub(pos[i]);
          tmpPV.normalize();
          tmpPV.mult(mouseDist);
          tmpPV = PVector.sub(mouse, tmpPV);
          pos[i] = tmpPV.get();
        }
      }

      PVector tmp = PVector.sub(pos[i-1], pos[i]);
      tmp.normalize();
      tmp.mult(DIST_MAX);
      pos[i] = PVector.sub(pos[i-1], tmp);

      //keep the points inside the circle
      if (PVector.dist(center, pos[i]) > radius)
      {
        PVector tmpPV = pos[i].get();
        tmpPV.sub(center);
        tmpPV.normalize();
        tmpPV.mult(radius);
        tmpPV.add(center);
        pos[i] = tmpPV.get();
      }
    }

    updateColors();

    if (mode == 0)
    {
      stroke(0, 100);
    }     
    beginShape();
    noFill(); 
    for (int i = 0; i < nbSegments; i++)
    { 
      float r = rad[i];
      if (mode == 1)
      {
        stroke(cols[i]);
        vertex(pos[i].x, pos[i].y);
        //line(pos[i].x, pos[i].y, pos[i+1].x, pos[i+1].y);
      } else
      {
        fill(cols[i]);
        noStroke();
        ellipse(pos[i].x, pos[i].y, 2, 2);
      }
    }
    endShape();
  }

  void updateColors()
  {
    myCol.update();
    cols[0] = myCol.getColor();
    for (int i = nbSegments-1; i > 0; i--)
    {
      cols[i] = cols[i-1];
    }
  }
}

Answers

  • edited March 2017

    Posting the code again because it seems to have displayed sloppy.

    final int nbWeeds = 125;
    SeaWeed[] weeds;
    PVector rootNoise = new PVector(random(123456), random(123456));
    int mode = 1;
    float radius = 750;
    Boolean noiseOn = true;
    PVector center;
    
    void setup()
    {
      size(1000, 1000, P2D);
      center = new PVector(width/2, height/2);
      strokeWeight(5);
      weeds = new SeaWeed[nbWeeds];
      for (int i = 0; i < nbWeeds; i++)
      {
        weeds[i] = new SeaWeed(i*TWO_PI/nbWeeds, 3*radius);
      }
    }
    
    void draw()
    {
      //background(50);
      noStroke();
      fill(25, 15, 25);//, 50);
      rect(0, 0, width, height);
      rootNoise.add(new PVector(.05, .05));
      strokeWeight(1);
      for (int i = 0; i < nbWeeds; i++)
      {
        weeds[i].update();
      }
      stroke(200, 100, 100, 200);
      strokeWeight(4);
      noFill();
      ellipse(center.x, center.y, 2*radius, 2*radius);
    }
    
    void keyPressed()
    {
      if (key == 'n')
      {
        noiseOn = !noiseOn;
      } else
      {
        mode = (mode + 1) % 2;
      }
    }
    
    
    class MyColor
    {
      float R, G, B, Rspeed, Gspeed, Bspeed;
      final static float minSpeed = .2;
      final static float maxSpeed = 2.0;
      final static float minR = 200;
      final static float maxR = 255;
      final static float minG = 20;
      final static float maxG = 120;
      final static float minB = 100;
      final static float maxB = 140;
    
      MyColor()
      {
        init();
      }
    
      public void init()
      {
        R = random(minR, maxR);
        G = random(minG, maxG);
        B = random(minB, maxB);
        Rspeed = (random(1) > .5 ? 1 : -1) * random(minSpeed, maxSpeed);
        Gspeed = (random(1) > .5 ? 1 : -1) * random(minSpeed, maxSpeed);
        Bspeed = (random(1) > .5 ? 1 : -1) * random(minSpeed, maxSpeed);
      }
    
      public void update()
      {
        Rspeed = ((R += Rspeed) > maxR || (R < minR)) ? -Rspeed : Rspeed;
        Gspeed = ((G += Gspeed) > maxG || (G < minG)) ? -Gspeed : Gspeed;
        Bspeed = ((B += Bspeed) > maxB || (B < minB)) ? -Bspeed : Bspeed;
      }
    
      public color getColor()
      {
        return color(R, G, B);
      }
    }
    class SeaWeed
    {
      final static float DIST_MAX = 5.5;//length of each segment
      final static float maxWidth = 50;//max width of the base line
      final static float minWidth = 11;//min width of the base line
      final static float FLOTATION = -3.5;//flotation constant
      float mouseDist;//mouse interaction distance
      int nbSegments;
      PVector[] pos;//position of each segment
      color[] cols;//colors array, one per segment
      float[] rad;
      MyColor myCol = new MyColor();
      float x, y;//origin of the weed
      float cosi, sinu;
    
      SeaWeed(float p_rad, float p_length)
      {
        nbSegments = (int)(p_length/DIST_MAX);
        pos = new PVector[nbSegments];
        cols = new color[nbSegments];
        rad = new float[nbSegments];
        cosi = cos(p_rad);
        sinu = sin(p_rad);
        x = width/2 + radius*cosi;
        y = height/2 + radius*sinu;
        mouseDist = 40;
        pos[0] = new PVector(x, y);
        for (int i = 1; i < nbSegments; i++)
        {
          pos[i] = new PVector(pos[i-1].x - DIST_MAX*cosi, pos[i-1].y - DIST_MAX*sinu);
          cols[i] = myCol.getColor();
          rad[i] = 3;
        }
      }
    
      void update()
      {
        PVector mouse = new PVector(mouseX, mouseY);
    
        pos[0] = new PVector(x, y);
        for (int i = 1; i < nbSegments; i++)
        {
          float n = noise(rootNoise.x + .002 * pos[i].x, rootNoise.y + .002 * pos[i].y);
          float noiseForce = (.5 - n) * 7;
          if (noiseOn)
          {
            pos[i].x += noiseForce;
            pos[i].y += noiseForce;
          }
          PVector pv = new PVector(cosi, sinu);
          pv.mult(map(i, 1, nbSegments, FLOTATION, .6*FLOTATION));
          pos[i].add(pv);
    
          //mouse interaction
          //if(pmouseX != mouseX || pmouseY != mouseY)
          {
            float d = PVector.dist(mouse, pos[i]);
            if (d < mouseDist)// && pmouseX != mouseX && abs(pmouseX - mouseX) < 12)
            {
              PVector tmpPV = mouse.get();       
              tmpPV.sub(pos[i]);
              tmpPV.normalize();
              tmpPV.mult(mouseDist);
              tmpPV = PVector.sub(mouse, tmpPV);
              pos[i] = tmpPV.get();
            }
          }
    
          PVector tmp = PVector.sub(pos[i-1], pos[i]);
          tmp.normalize();
          tmp.mult(DIST_MAX);
          pos[i] = PVector.sub(pos[i-1], tmp);
    
          //keep the points inside the circle
          if (PVector.dist(center, pos[i]) > radius)
          {
            PVector tmpPV = pos[i].get();
            tmpPV.sub(center);
            tmpPV.normalize();
            tmpPV.mult(radius);
            tmpPV.add(center);
            pos[i] = tmpPV.get();
          }
        }
    
        updateColors();
    
        if (mode == 0)
        {
          stroke(0, 100);
        }     
        beginShape();
        noFill(); 
        for (int i = 0; i < nbSegments; i++)
        { 
          float r = rad[i];
          if (mode == 1)
          {
            stroke(cols[i]);
            vertex(pos[i].x, pos[i].y);
            //line(pos[i].x, pos[i].y, pos[i+1].x, pos[i+1].y);
          } else
          {
            fill(cols[i]);
            noStroke();
            ellipse(pos[i].x, pos[i].y, 2, 2);
          }
        }
        endShape();
      }
    
      void updateColors()
      {
        myCol.update();
        cols[0] = myCol.getColor();
        for (int i = nbSegments-1; i > 0; i--)
        {
          cols[i] = cols[i-1];
        }
      }
    }
    
  • And it's still sloppy.

    Press the gear icon to edit your post.
    Select your code and press ctrl + o to indent.
    Leave a line above and below the code.

  • Sorry about that. Cleaned it up. Hopefully its easier to read now. Thanks for the tip!

  • I believe you said that you're using Kinect, yet I cannot find any reference to Kinect in the sketch?

  • You're exactly right. I am using Kinect and did not include code. Attaching the code I'd like to integrate. When I attempt to put the code for Kinect into the sketch I run into a series of errors. Things like saying setup exists in both files. Included just the sketch because it works fine as is. The second I try to use the Kinect with it its all down hill. That's why I'm here. I'm so incredibly confused.

    This is the code:

    import processing.video.*;
    
    Capture video;
    PImage prev;
    
    float threshold = 25;
    
    float motionX = 0;
    float motionY = 0;
    
    float lerpX = 0;
    float lerpY = 0;
    
    
    void setup() {
      size(640, 360);
      String[] cameras = Capture.list();
      printArray(cameras);
      video = new Capture(this, cameras[3]);
      video.start();
      prev = createImage(640, 360, RGB);
      // Start off tracking for red
    }
    
    
    void mousePressed() {
    }
    
    void captureEvent(Capture video) {
      prev.copy(video, 0, 0, video.width, video.height, 0, 0, prev.width, prev.height);
      prev.updatePixels();
      video.read();
    }
    
    void draw() {
      video.loadPixels();
      prev.loadPixels();
      image(video, 0, 0);
    
      //threshold = map(mouseX, 0, width, 0, 100);
      threshold = 50;
    
    
      int count = 0;
    
      float avgX = 0;
      float avgY = 0;
    
      loadPixels();
      // Begin loop to walk through every pixel
      for (int x = 0; x < video.width; x++ ) {
        for (int y = 0; y < video.height; y++ ) {
          int loc = x + y * video.width;
          // What is current color
          color currentColor = video.pixels[loc];
          float r1 = red(currentColor);
          float g1 = green(currentColor);
          float b1 = blue(currentColor);
          color prevColor = prev.pixels[loc];
          float r2 = red(prevColor);
          float g2 = green(prevColor);
          float b2 = blue(prevColor);
    
          float d = distSq(r1, g1, b1, r2, g2, b2); 
    
          if (d > threshold*threshold) {
            //stroke(255);
            //strokeWeight(1);
            //point(x, y);
            avgX += x;
            avgY += y;
            count++;
            pixels[loc] = color(255);
          } else {
            pixels[loc] = color(0);
          }
        }
      }
      updatePixels();
    
      // We only consider the color found if its color distance is less than 10. 
      // This threshold of 10 is arbitrary and you can adjust this number depending on how accurate you require the tracking to be.
      if (count > 200) { 
        motionX = avgX / count;
        motionY = avgY / count;
        // Draw a circle at the tracked pixel
      }
    
      lerpX = lerp(lerpX, motionX, 0.1); 
      lerpY = lerp(lerpY, motionY, 0.1); 
    
      fill(255, 0, 255);
      strokeWeight(2.0);
      stroke(0);
      ellipse(lerpX, lerpY, 36, 36);
    
      //image(video, 0, 0, 100, 100);
      //image(prev, 100, 0, 100, 100);
    
      //println(mouseX, threshold);
    }
    
    float distSq(float x1, float y1, float z1, float x2, float y2, float z2) {
      float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) +(z2-z1)*(z2-z1);
      return d;
    }
    
Sign In or Register to comment.