We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi, I found this interesting example of open / close palm gesture using SimpleOpenNI in this LINK. This example only works for single user. Please can anyone suggest how to make it working for multiple users :)
import SimpleOpenNI.*;
SimpleOpenNI context;
float zoomF =0.5f;
float rotX = radians(180);
float rotY = radians(0);
//the hand tracking part
boolean handsTrackFlag = false;//if kinect is tracking hand or not
PVector handVec = new PVector();//the latest/most up to date hand point
ArrayList handVecList = new ArrayList();//the previous points in a list
int handVecListSize = 30;//the number of previous points to be remembered
String lastGesture = "";//used to keep track of gestures
PVector handMin = new PVector();
PVector handMax = new PVector();
float handThresh = 95;
float openThresh = 200;
void setup()
{
size(1024, 768, P3D);
context = new SimpleOpenNI(this);
context.setMirror(true);
if (context.enableDepth() == false)
{
println("Can't open the depthMap, maybe the camera is not connected!");
exit();
return;
}
// enable hands + gesture generation
context.enableGesture();
context.enableHands();
// add focus gestures / here i do have some problems on the mac, i only recognize raiseHand ? Maybe cpu performance ?
context.addGesture("Wave");
context.addGesture("Click");
context.addGesture("RaiseHand");
stroke(255, 255, 255);
smooth();
}
void draw()
{
// update the cam
context.update();
background(0, 0, 0);
// set the scene pos
translate(width/2, height/2, 0);
rotateX(rotX);
rotateY(rotY);
if (handsTrackFlag)
{
//update hand from point cloud
handMin = handVec.get();
handMax = handVec.get();
// draw the 3d point depth map
int[] depthMap = context.depthMap();
int steps = 3; // to speed up the drawing, draw every third point
int index;
PVector realWorldPoint;
for (int y=0;y < context.depthHeight();y+=steps)
{
for (int x=0;x < context.depthWidth();x+=steps)
{
index = x + y * context.depthWidth();
if (depthMap[index] > 0)
{
// draw the projected point
realWorldPoint = context.depthMapRealWorld()[index];
if (realWorldPoint.dist(handVec) < handThresh) {
point(realWorldPoint.x, realWorldPoint.y, realWorldPoint.z);
if (realWorldPoint.x < handMin.x) handMin.x = realWorldPoint.x;
if (realWorldPoint.y < handMin.y) handMin.y = realWorldPoint.y;
if (realWorldPoint.z < handMin.z) handMin.z = realWorldPoint.z;
if (realWorldPoint.x > handMax.x) handMax.x = realWorldPoint.x;
if (realWorldPoint.y > handMax.y) handMax.y = realWorldPoint.y;
if (realWorldPoint.z > handMax.z) handMax.z = realWorldPoint.z;
}
}
}
}
line(handMin.x, handMin.y, handMin.z, handMax.x, handMax.y, handMax.z);
float hDist = handMin.dist(handMax);
if (hDist > openThresh) println("palm open, dist: " + hDist);
else println("palm close, dist: " + hDist);
pushStyle();
stroke(255, 0, 0, 200);
noFill();
beginShape();
for (int i = 0 ; i < handVecList.size(); i++) {
PVector p = (PVector) handVecList.get(i);
vertex(p.x, p.y, p.z);
}
endShape();
stroke(255, 0, 0);
strokeWeight(4);
point(handVec.x, handVec.y, handVec.z);
popStyle();
}
// draw the kinect cam
context.drawCamFrustum();
}
// -----------------------------------------------------------------
// hand events
void onCreateHands(int handId, PVector pos, float time)
{
println("onCreateHands - handId: " + handId + ", pos: " + pos + ", time:" + time);
handsTrackFlag = true;
handVec = pos;
handVecList.clear();
handVecList.add(pos);
}
void onUpdateHands(int handId, PVector pos, float time)
{
//println("onUpdateHandsCb - handId: " + handId + ", pos: " + pos + ", time:" + time);
handVec = pos;
handVecList.add(0, pos);
if (handVecList.size() >= handVecListSize)
{ // remove the last point
handVecList.remove(handVecList.size()-1);
}
}
void onDestroyHands(int handId, float time)
{
println("onDestroyHandsCb - handId: " + handId + ", time:" + time);
handsTrackFlag = false;
context.addGesture(lastGesture);
}
// -----------------------------------------------------------------
// gesture events
void onRecognizeGesture(String strGesture, PVector idPosition, PVector endPosition)
{
println("onRecognizeGesture - strGesture: " + strGesture + ", idPosition: " + idPosition + ", endPosition:" + endPosition);
lastGesture = strGesture;
context.removeGesture(strGesture);
context.startTrackingHands(endPosition);
}
void onProgressGesture(String strGesture, PVector position, float progress)
{
//println("onProgressGesture - strGesture: " + strGesture + ", position: " + position + ", progress:" + progress);
}
Answers
I don't know Kinect / SimpleOpenNI, so as a start, I wonder how you distinguish several users.
SimpleOpenNI generates userID but for that we need to call some library functions. There is also getCOM function which gives user's center of mass position. Click Here
I don't really understand how hand functions works in SimpleOpenNI but I am sure you can distinguish hand. Hand can be tracked by either any of the two ways
Using hand & Gesture Functions or Events
Can we create a class of the Grab gesture and call it for indvidual users according to their handIDs or userIDs. I am not sure it is possible but if there is anyone who can help me please do ...
Hey can any one help me with this please !.......................... Here is the code for multiple hand tracking and I have posted hand grab gesture in the above post but I dont know how to integrate both the codes.
Any help would highly appreciable ..
@PhiLho : Can you suggest me a way to integrate these two different code so that I can perform grab gesture (open/close palm ) for multiple user.
please help me. Thanks !
I don't know if this is any help: http://stackoverflow.com/questions/14742261/simple-openni-getuserpixels
It looks like neither @PhiLho nor I own one, so it's not that easy to comment on Kinect code. Anyone donating Kinects out there? :)
@hamoid: I already used the method here you have given but it not useful in this context so can you give me any hint if possible :P BTW thanks again hamoid for the help :)
maybe somebody help me( i cant to remade for kinect my game for children. they must be catch the ball on the floor
import SimpleOpenNI.*; SimpleOpenNI context;
float x = 120; float y = 60; int radius = 12;
void setup() { size(1024, 768, P3D); kinect = new SimpleOpenNI(this); kinect.enableDepth(); size(kinect.depthWidth(), kinect.depthHeight()); smooth(); ellipseMode(RADIUS); }
void draw() { kinect.update(); background(0);
// float d = dist(mouseX, mouseY, x, y); if (d < radius) { radius++; fill(0); } else { radius = 12; if(frameCount%150 == 0){ x = random(500); y = random(500); } fill(255); } ellipse(x, y, radius, radius); }