Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

Hand Tracking

9. Dezember 2011

With the help of the SimpleOpenNI we created permutations that react on handpositions. I've coded a simple program with a small menu to choose a shape.
import fullscreen.*;
import SimpleOpenNI.*;

HandCapture   handCapture;
boolean       drawFlag=false;

int       mainmenu=0;
int       formmode=0;

PImage noHand;
PImage mainmenupic;
PFont font;

FullScreen fullScreen; 

float max_distance;
float anzahl = 7;

void setup() {
  handCapture = new HandCapture(this);

  size(1024, 768); //BEAMER RESOLUTION
  smooth();
  noStroke();
  max_distance = dist(0, 0, width, height);

  fullScreen = new FullScreen(this);
  fullScreen.enter();

  noCursor();

  noHand = loadImage("no_hand.jpg");
  mainmenupic = loadImage("mainmenu.jpg");
  font = loadFont("Calibri.vlw");
}

void draw() 
{
  
  // update the hand tracking
  handCapture.update();

  PVector handPos = handCapture.handPos();

  handPos.x = map(handPos.x, 0, 640, 0, 1024);
  handPos.y = map(handPos.y, 0, 480, 0, 768);
  handPos.z = map(handPos.z, 400, 1500, 0.2, 1);

  background(255);

  for (int i = 55; i <= width; i += width/anzahl/1.75) {
    for (int j = 50; j <= height; j += height/anzahl/1.3) {
      if (handCapture.isHandTracked() && mainmenu==1)
      {      
        float size = dist(handPos.x, handPos.y, i, j);
        size = size/max_distance * 33;
        if (formmode==1)
        {
          pushMatrix();
          rectMode(CENTER);
          fill(0);
          rect(i, j, size+60*handPos.z, size+60*handPos.z);
          fill(255);
          rect(i, j, size+50, size+50);
          fill(0);
          rect(i, j, size+40 * handPos.z, size+40 * handPos.z);
          fill(255);
          rect(i, j, size+30, size+30);
          fill(0);
          rect(i, j, size+20 * handPos.z, size+20 * handPos.z);
          fill(255);
          rect(i, j, size+10, size+10);
          fill(0);
          rect(i, j, size+0 *handPos.z, size+0 * handPos.z);
          popMatrix();
        }
        else if (formmode==2)
        {
          pushMatrix();
          fill(0);
          ellipse(i, j, size+60*handPos.z, size+60*handPos.z);
          fill(255);
          ellipse(i, j, size+50, size+50);
          fill(0);
          ellipse(i, j, size+40 * handPos.z, size+40 * handPos.z);
          fill(255);
          ellipse(i, j, size+30, size+30);
          fill(0);
          ellipse(i, j, size+20 * handPos.z, size+20 * handPos.z);
          fill(255);
          ellipse(i, j, size+10, size+10);
          fill(0);
          ellipse(i, j, size+0 *handPos.z, size+0 * handPos.z);
          popMatrix();
        }
        else if (formmode==3)
        {
          pushMatrix();
          rectMode(CENTER);
          fill(0);
          rect(i, j, (handPos.x/anzahl/1.75)+60, (handPos.y/anzahl/1.3)+60);
          fill(255);
          rect(i, j, (handPos.x/anzahl/1.75)+50, (handPos.y/anzahl/1.3)+50);
          fill(0);
          rect(i, j, (handPos.x/anzahl/1.75)+40, (handPos.y/anzahl/1.3)+40);
          fill(255);
          rect(i, j, (handPos.x/anzahl/1.75)+30, (handPos.y/anzahl/1.3)+30);
          fill(0);
          rect(i, j, (handPos.x/anzahl/1.75)+20, (handPos.y/anzahl/1.3)+20);
          fill(255);
          rect(i, j, (handPos.x/anzahl/1.75)+10, (handPos.y/anzahl/1.3)+10);
          fill(0);
          rect(i, j, handPos.x/anzahl/1.75, handPos.y/anzahl/1.3);
          popMatrix();
        }
      }
      else if (mainmenu==1) {
        imageMode(CENTER);
        image(noHand, width/2, height/2);
      }
    }
  }

  if (mainmenu==0) {
    background(255);
    ellipse(211, 382, 128, 128);
    rectMode(CORNER);
    rect(728, 321, 125, 125);
    rect((width/2)-30, 150, 60, 120);
    textFont(font, 15); 
    textAlign(CENTER);
    text("choose a shape", width/2, 400);
    fill(0);
    ellipse(handPos.x, handPos.y, 10, 10);
    if (handPos.x >= 142 && handPos.y >= 313 && handPos.x <= 280 && handPos.y <= 450) {
      mainmenu=1;
      formmode=2;
    }
    else if (handPos.x >= 727 && handPos.y >= 320 && handPos.x <= 854 && handPos.y <= 450) {
      mainmenu=1;
      formmode=1;
    }
    else if (handPos.x >= (width/2)-30 && handPos.y >= 150 && handPos.x <= (width/2)+30 && handPos.y <= 270) {
      mainmenu=1;
      formmode=3;
    }
  }
}

void mousePressed() {
  mainmenu=0;
  }

// -----------------------------------------------------------------
// hand events

void onCreateHands(int handId, PVector pos, float time)
{
  handCapture.onCreateHands(handId, pos, time);
}

void onUpdateHands(int handId, PVector pos, float time)
{
  handCapture.onUpdateHands(handId, pos, time);
}

void onDestroyHands(int handId, float time)
{
  handCapture.onDestroyHands(handId, time);
}

void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition)
{
  handCapture.onRecognizeGesture(strGesture, idPosition, endPosition);
}

void onProgressGesture(String strGesture, PVector position, float progress)
{
  handCapture.onProgressGesture(strGesture, position, progress);
}

Class:
import SimpleOpenNI.*;

class HandCapture
{
  SimpleOpenNI  _context;
  boolean       _drawFlag=false;
  PVector       _handVec = new PVector();
  String        _lastGesture = "";
  PVector       _screenPos = new PVector();
  PApplet       _parent;
  boolean       _handsTrackFlag = false;

  HandCapture(PApplet parent)
  {
    _parent = parent;

    _context = new SimpleOpenNI(_parent);

    // mirror is by default enabled
    _context.setMirror(true);

    // enable depthMap 
    _context.enableDepth();

    // enable camera
    _context.enableRGB();

    _context.enableHands();  
    _context.enableGesture();

    _context.addGesture("RaiseHand");

    // align depth data to image data
    _context.alternativeViewPointDepthToImage();

  }

  boolean isHandTracked() { return _handsTrackFlag; } 
  
  PVector handPos() { return _screenPos; }
  PVector handPos3d() { return _handVec; }
  
  PImage depthImage() { return _context.depthImage(); }
  PImage rgbImage() { return _context.rgbImage(); }
  

  int width() { return _context.depthWidth(); }
  int height() { return _context.depthHeight(); }
  
  void update()
  {
    _context.update();
    
    _context.convertRealWorldToProjective(_handVec,_screenPos);
  }

  void onCreateHands(int handId, PVector pos, float time)
  {
    _handsTrackFlag = true;
    _handVec = pos;
  }

  void onUpdateHands(int handId, PVector pos, float time)
  {
    _handVec = pos;
  }

  void onDestroyHands(int handId, float time)
  {
    _handsTrackFlag = false;
    _context.addGesture(_lastGesture);
  }

  void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition)
  {
    _lastGesture = strGesture;
    _context.removeGesture(strGesture); 
    _context.startTrackingHands(endPosition);
  }

  void onProgressGesture(String strGesture, PVector position, float progress)
  {
  }
}