[英]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.