如何实现非标准Leap Motion手势?

8

Leap Motion API仅支持四种标准手势:圆形、滑动、按键敲击和屏幕敲击。在我的应用程序中,我需要其他手势,但我不知道如何添加它们或是否可以添加更多手势。我阅读了API,但没有得到帮助。

在我的应用程序中,我想允许用户拖动并移动一个物体。使用Leap Motion API是否可能实现?如果是,如何实现?


首先:您使用的是哪种语言进行开发?您必须准确地研究手势的x/y/z轴并对其进行分析。 - Larme
正如Larme所说,您需要提供更多信息,以便我们帮助您。您正在使用哪个Leap Motion API(JS、Objective-C等)?您希望人们如何握住这个物体(手指、握紧的手)?此外,您应该阅读您所呈现的文本,而不是尝试通过将其粘贴到问题中来欺骗系统。 - Brad Larson
好的,我重新表述了你的问题并删除了末尾的垃圾。虽然它仍然有点宽泛,但更接近于可回答的范围。不过,如果能提供更多细节会更有帮助。 - Brad Larson
Leap Motion API中的手势是不可扩展的。如果要识别新手势,您必须从头开始创建自己的手势识别系统。 - Charles Ward
2个回答

8
您需要创建自己的方法来识别手势的开始点、过程和结束点。
开始点: 您的程序将如何识别您正在尝试握住某物?我可以想到一个简单的手势是2个手指与1个手掌链接。因此,在帧中,如果您看到2个手指与1个手掌链接,而手指之间可能相隔10-20毫米,您可以将其识别为握住某物的手势。当这些条件满足时,程序将识别手势,并且您可以在这些条件内编写一些代码。
对于一个非常丑陋的C#示例:
开始点: 布尔类型的gesture_detected = false;
Frame frame = controller.Frame();
HandList hands = controller.Hands;

if (hands.Count == 1)
{
   foreach (Hand hand in hands)
   {
       if (hand.fingers.Count == 2)
       {
           int fingerA_x,fingerB_x;
           foreach (Finger finger in hand.fingers)
           {
               if(fingerA_x == 0)
               {
                   fingerA_x = finger.x;
               } else
               {
                   fingerB_x = finger.x;
               }
           }
       }
   }

   if((fingerA_x - fingerB_x) < 20)
   {
         //Gesture is detected. Do something...
         gesture_detected = true;
   }
}

流程: 您的手势想要做什么?如果您想四处移动,就必须调用一个鼠标方法来进行拖动。在PInvoke下使用事件MOUSEEVENTF_LEFTDOWN,在C++中搜索mouse_event() 方法。

结束点: 拖动完成后,您需要调用一个鼠标方法事件,比如MOUSEEVENTF_LEFTUP来模拟已经完成的鼠标拖动。但是,当您应该停止拖动时,您的程序如何检测?最合适的方法是:如果在帧中不再检测到手势,则编写一个else条件来处理备选情况。

       if (!gesture_detected)
       {
            // Do something
       }

0

曾经我也想过是否需要派生一些Leap Motion类来定义自定义类,就像其他API一样,结果发现不必要。以下是C++的一个简短示例,Leap Motion的本地语言,自定义手势定义,Lift手势将在您的世界中将所有动力学对象提起到空中。

手势定义需要2只可见手,两只手都打开平放,手掌向上并且移动速度比预定义(目前已弃用)的Leap Motion Swipe手势慢,因此在Leap Motion回调函数void GestureListener::onConnect(const Leap::Controller& controller)启动时启用Swipe手势时,不会混淆两个手势。

从示例中可以看出,手势定义对两只手的法线和速度施加了约束,因此它不会随机检测,但约束不会太多,因此仍然可以通过一些合理的努力执行。

// lift gesture: 2 hands open flat, both palms up and moving up slowly
void LeapMotion::liftGesture(int numberHands, std::vector<glm::vec3> palmNormals, std::vector<glm::vec3> palmVelocities) {

    if ((numberHands == 2) &&
        (palmNormals[0].x < 0.4f) && (palmNormals[1].x < 0.4f) &&
        (palmNormals[0].y > 0.9f) && (palmNormals[1].y > 0.9f) &&
        (palmNormals[0].z < 0.4f) && (palmNormals[1].z < 0.4f) &&
        (palmVelocities[0].z > 50.0f) && (palmVelocities[1].z > 50.0f) &&
        (palmVelocities[0].z < 300.0f) && (palmVelocities[1].z < 300.0f)) {

        m_gesture = LIFT;
        logFileStderr(VERBOSE, "\nLift gesture...\n");
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接