我想检查闰动画帧中的手是否是当前的拳头。
通常建议的方法是查找值为{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)?有什么想法吗?
答案 0 :(得分:3)
好吧,我想我发现了一种检测实际拳头的工作方法,而不是爪子。
首先,我们需要每个骨骼的距离矢量,而不是关节的位置。
然后我们计算掌骨和近端骨之间的Dot积,以及近端骨和中间骨之间的点积。我们可以忽略远端骨骼,它不会过多地改变结果。
我们计算所有计算的点积(总共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;
}
}
虽然这样做会有所作为,但我怀疑这是检测拳头的正确和最佳方法。所以,如果你知道更好的方法,请发布它。
解决方案是完美的,任何机会你都可以解释为什么你除以10以及为什么minValue为0.5?谢谢!
嗯,说实话,它并没有那么好用。我很快就会开始研究一个旨在通过Leap Motion改进拳头检测的小项目。
关于你的问题,我们将总和除以10,因为每个手指有2个骨关节,有5个手指。我们想要所有这些计算之和的平均值,因为不是所有的手指都会以相同的方式成角度。因此,我们需要一些将所有这些值包含在一个值中的值:平均值。鉴于我们总计有10次计算(每个手指2个,5个手指),我们将这些计算的总和除以我们去的位置。我们将得到一个介于0和1之间的值。
关于minValue:Trial&amp; Error。在我的一个项目中,我使用了0.6的值。 这是这种方法的另一个问题:理想情况下,平手应该是接近0的值,而拳头应该是1.
答案 1 :(得分:0)
我知道这是一个古老的话题,但是如果你们仍然在答案中,只需使用sphereRadius()
即可;
答案 2 :(得分:-1)
我发现“ grabStrength”很好