2014-10-30 9 views
5

Chcę sprawdzić, czy dłoń w ramce ruchu skokowego jest obecnie pięścią.Wykrywanie pięści za pomocą Leap Motion SDK V2

Zazwyczaj sugerowaną metodą jest szukanie hand.grabStrength o wartości 1. Problem polega na tym, że wartość przeskakuje do 1, nawet z ręką "podobną do pazura", lub cokolwiek innego z lekko lekko zwiniętymi palcami.

Innym podejściem byłoby sprawdzenie każdego palca, jeśli jest to extended. Ale to ma podobny problem, Palce liczą się jako rozszerzone, jeśli są całkowicie proste. Więc nawet jeśli sprawdzę, czy wszystkie palce nie są wysunięte, pojawia się ten sam problem, co powyżej (ręce podobne do pazurów zostają rozpoznane jako chwycone).

Połączenie tych dwóch metod również nie rozwiązuje problemu, co nie jest zaskakujące, biorąc pod uwagę, że obaj cierpią na te same problemy.

Teraz mamy wszystkie kości każdego palca dostępne, z pozycjami i wszystkim. Ale nie mam pojęcia, od czego zacząć od matematyki, aby wykryć, czy palec jest zwinięty.

Zasadniczo mam tej konfiguracji teraz:

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 
    } 
}); 

Tak, jak mogę uzyskać kąt pomiędzy dwoma z tych stanowisk (karp do MCP, MCP do pip, pip zanurzyć)? Jakieś pomysły?

Odpowiedz

3

W porządku, myślę, że znalazłem coś w rodzaju działającego podejścia do wykrywania prawdziwej pięści, a nie pazura.

Po pierwsze, zamiast pozycji stawów, potrzebujemy odległości Wektory dla każdej kości.

Następnie obliczamy produkt Dot pomiędzy kością śródręczną i proksymalną, a także kropką pomiędzy kością proksymalną i pośrednią. Możemy zignorować dystalną kość, nie zmienia to zbytnio wyniku.

Sumujemy wszystkie wyliczone produkty dot (łącznie 10) i obliczamy średnią wartość (dzielimy przez 10). Da nam to wartość od 0 do 1. Pięść jest poniżej 0,5, a wszystko powyżej to w zasadzie nie pięść.

Dodatkowo możesz również sprawdzić ilość przedłużonych palców na dłoni i sprawdzić, czy jest ona równa 0. Zapewni to, że "Kciuk w górę" i podobne 1-cyfrowe pozy nie zostaną rozpoznane jako Pięść .

Oto moja realizacja:

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; 
    } 
} 

Chociaż to działa tak jak powinien, to wątpię, że jest to właściwe i najlepsze podejście do wykrywania pięść. Więc proszę, jeśli znasz lepszy sposób, opublikuj go.


Rozwiązanie działa idealnie, jakaś szansa można wyjaśnić, dlaczego należy podzielić przez 10 i dlaczego MINVALUE 0.5? Dzięki!

Cóż, to nie działa tak dobrze, szczerze mówiąc. Wkrótce zacznę pracować nad małym projektem, którego celem jest poprawienie wykrywania pięści za pomocą Leap Motion.

Jeśli chodzi o pytania, dzielimy sumę przez 10, ponieważ mamy 2 stawy do kości na palec, 5 palców.Chcemy średniej wartości z sumy wszystkich tych obliczeń, ponieważ nie wszystkie palce będą nachylone w ten sam sposób. Chcemy więc pewnej wartości, która obejmuje wszystkie te wartości w jedną: średnią wartość. Biorąc pod uwagę, że mamy łącznie 10 obliczeń (2 na każdy palec, 5 palców), dzielimy sumę tych obliczeń i tam jedziemy. Otrzymamy wartość z przedziału od 0 do 1.

Odnośnie mina: Błąd w wersji próbnej &. W moim projekcie użyłem zamiast tego wartości 0,6. To jest kolejny problem tego podejścia: idealnie płaska ręka powinna mieć wartość prawie 0, a pięść powinna być 1.

+0

Czy to nie przebije również złamanych palców w stawie, wskazując kątowy kierunek przeciwny potrzebny zrobić pięść (jak gdyby całkowicie nieograniczona zasięgiem stawu)? :RE. * Cringe * –

+0

Przypuszczam, że tak, ale ta matematyka jest dla mnie zbyt skomplikowana. : P – DodgerThud

+0

Znalazłem dobre rozwiązanie wykorzystując odległość między każdym palcem a dłonią. Oblicz sumę tych odległości i sprawdź, czy jest poniżej pewnego progu. – whoabackoff

Powiązane problemy