簡體   English   中英

使用 Leap Motion SDK V2 檢測拳頭

[英]Detecting a Fist with Leap Motion SDK V2

我想檢查跳躍運動框架中的手當前是否為拳頭。

通常建議的方法是尋找值為 1 的hand.grabStrength 。問題是,即使使用“類爪”手或其他任何手指非常輕微卷曲的手,該值也會跳到 1。

另一種方法是檢查每個手指是否extended 但這有一個類似的問題,手指只有在完全伸直的情況下才算伸展。 因此,即使我檢查所有手指都沒有伸出,也會發生與上述相同的問題(爪狀手被識別為被抓住)。

結合這兩種方法也不能解決問題,考慮到它們都遇到相同的問題,這並不奇怪。

現在,我們確實擁有每個手指的所有骨骼,以及位置和所有內容。 但我不知道從哪里開始用數學來檢測手指是否卷曲。

基本上我現在有這個設置:

var controller = Leap.loop(function(frame){
   if(frame.hands.length>0){
       //we only look at the first available hand
       var hand = frame.hands[0];
       //we get the index finger only, but later on we should look at all 5 fingers.
       var index = hands.fingers[1];
       //after that we get the positions of the joints between the bones in a hand
       //the position of the metacarpal bone (i.e. the base of your hand)
       var carp = index.carpPosition;
       //the position of the joint on the knuckle of your hand
       var mcp = index.mcpPosition;
       //the position of the following joint, between the proximal and the intermediate bones
       var pip = index.pipPosition;
       //the position of the distal bone (the very tip of your finger)
       var dip = index.dipPosition;

       //and now we need the angle between each of those positions, which is where i'm stuck
   }
});

那么,我如何獲得其中兩個位置之間的角度(鯉魚到 mcp,mcp 到 pip,pip 到 dip)? 有任何想法嗎?

好吧,我想我找到了一種有效的方法來檢測真正的拳頭,而不是爪子。

首先,我們需要每個骨骼的距離向量,而不是關節的位置。

然后我們計算掌骨和近端骨之間的點積,以及近端和中間骨之間的點積。 我們可以忽略 Distal 骨骼,它不會改變太多結果。

我們對所有計算出的點積求和(總共 10 個)並計算平均值(我們除以 10)。 這將給我們一個介於 0 和 1 之間的值。拳頭低於 0.5,而高於此值的所有東西基本上都不是拳頭。

此外,您可能還想檢查手上伸出的手指數量並檢查它是否為 0。這將確保“豎起大拇指”和類似的 1 位姿勢不會被識別為拳頭。

這是我的實現:

const minValue = 0.5;

var controller = Leap.loop(function(frame){
   if(frame.hands.length>0)
   {
      var hand = frame.hands[0];
      var isFist = checkFist(hand);
   }
});

function getExtendedFingers(hand){
   var f = 0;
   for(var i=0;i<hand.fingers.length;i++){
      if(hand.fingers[i].extended){
         f++;
      }
   }
   return f;
}

function checkFist(hand){
   var sum = 0;
   for(var i=0;i<hand.fingers.length;i++){
      var finger = hand.fingers[i];
      var meta = finger.bones[0].direction();
      var proxi = finger.bones[1].direction();
      var inter = finger.bones[2].direction();
      var dMetaProxi = Leap.vec3.dot(meta,proxi);
      var dProxiInter = Leap.vec3.dot(proxi,inter);
      sum += dMetaProxi;
      sum += dProxiInter
   }
   sum = sum/10;

   if(sum<=minValue && getExtendedFingers(hand)==0){
       return true;
   }else{
       return false;
   }
}

雖然這可以正常工作,但我懷疑這是檢測 Fist 的正確和最佳方法。 所以,如果你知道更好的方法,請發布它。


解決方案完美無缺,您是否有機會解釋為什么除以 10 以及為什么 minValue 是 0.5? 謝謝!

好吧,老實說,它並沒有那么好用。 我很快就會開始從事一個小項目,該項目的目標是使用 Leap Motion 改進對拳頭的檢測。

關於您的問題,我們將總和除以 10,因為我們每個手指有 2 個骨關節,有 5 個手指。 我們想要所有這些計算總和的平均值,因為並非所有手指都以相同的方式傾斜。 所以我們想要一些將所有這些值包含在一個單一值中的值:平均值。 鑒於我們總共有 10 次計算(每個手指 2 次,5 根手指),我們將這些計算的總和相除,然后就可以了。 我們將得到一個介於 0 和 1 之間的值。

關於 minValue:Trial&Error。 在我的一個項目中,我使用了 0.6 的值。 這是這種方法的另一個問題:理想情況下,平手的值應該接近 0,而拳頭的值應該是 1。

我知道這是一個古老的話題,但如果你們仍然在答案周圍,只需使用sphereRadius()就可以更簡單;

我發現“grabStrength”很好

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM