2012-07-18 54 views
0

我正在使用簡單的OpenNI和處理的Kinect,並且我試圖使用手的Z位置來模擬按鈕按下。到目前爲止,當我用一隻手試用它時,它的工作非常好,但是,當我嘗試使用第二隻手工作時,只有一隻手可以工作。 (我知道通過移動除if語句之外的所有東西可以更有效率,但是我保留那些以防萬一我想更改尺寸或其他東西。)仿真按鈕按下使用Kinect/SimpleOpenNI +處理深度

irz和ilz是最初的Z當他們第一次被onCreateHands識別並且rz和lz是當前Z位置時手的位置。截至目前,代碼一方面可以正常工作,另一方面可以保持按下或不按下。如果我評論其中的一個部分,它也可以正常工作。

if (rz - irz > 0) { 
pushStyle(); 
fill(60); 
ellipse(rx, ry, 10, 10); 
popStyle(); 
rpressed = true; 
} 
else { 
pushStyle(); 
noFill(); 
ellipse(rx, ry, 10, 10); 
popStyle(); 
rpressed = false; 
} 

if (lz - ilz > 0) { 
pushStyle(); 
fill(60); 
ellipse(lx, ly, 10, 10); 
popStyle(); 
lpressed = true; 
} 
else { 
pushStyle(); 
noFill(); 
ellipse(lx, ly, 10, 10); 
popStyle(); 
lpressed = false; 
} 

我試圖輸出RZ的值 - IRZ和LZ - ILZ和號範圍從較小的負的值,以用於小LZ正值(約-8至8) - ILZ。但rz - irz輸出8到30之間的數字,具體取決於每次運行時的數字,並且永遠不會一致。另外,當我註釋掉lz-ilz的代碼時,rz-irz的值看起來很好,它按照預期運行。追蹤兩個Z位置的原因是否有一個原因?有沒有辦法讓它起作用?

謝謝!

回答

1

我有一對夫婦的想法:

  1. 使用NITE「點擊」的手勢
  2. 使用你現在的樣子手的z位置,而且跟蹤的差異Z軸運動

SimpleOpenNI似乎比NITE手勢更像雙手,比如「點擊」(你應該看到一條消息,在手被拿起然後向前和向後移動你的手後打印)。 貝婁是一個簡單的例子。請注意,我正在跟蹤Z上的+/-差異,並使用閾值僅基於特定距離進行觸發,例如,這可能是範圍。

import SimpleOpenNI.*; 
SimpleOpenNI context; 
boolean  handsTrackFlag = false; 
PVector  handVec = new PVector(); 
PVector  handVec2D = new PVector();//just for drawing 
String  lastGesture = ""; 
float  lastZ = 0; 
boolean  isPushing,wasPushing; 
float  yourClickThreshold = 20;//set this up as you see fit for your interaction 

void setup(){ 
    size(640,480); 
    context = new SimpleOpenNI(this); 
    context.enableDepth(); 
    // 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"); 

} 

void draw() 
{ 
    context.update(); 
    image(context.depthImage(),0,0); 
    // draw the tracked hand 
    if(handsTrackFlag){ 
    context.convertRealWorldToProjective(handVec,handVec2D); 
    float diff = (handVec.z-lastZ); 
    isPushing = diff < 0; 
    if(diff > yourClickThreshold){ 
     if(!wasPushing && isPushing) fill(255,0,0); 
     if(wasPushing && !isPushing) fill(0,255,0); 
    }else fill(255); 
    lastZ = handVec.z; 
    wasPushing = isPushing; 
    ellipse(handVec2D.x,handVec2D.y,10,10); 
    } 

} 


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

void onCreateHands(int handId,PVector pos,float time){ 
    println("onCreateHands - handId: " + handId + ", pos: " + pos + ", time:" + time); 

    handsTrackFlag = true; 
    handVec = pos; 
} 

void onUpdateHands(int handId,PVector pos,float time){ 
    //println("onUpdateHandsCb - handId: " + handId + ", pos: " + pos + ", time:" + time); 
    handVec = pos; 
} 

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){ 
    if(strGesture == "Click") 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); 
} 

另一種獲得兩隻手做骨架跟蹤時使用的SKEL_PROFILE_HEAD_HANDS,但要注意手的精度較低。