2. 安裝完之後先跑LeapMotionVisiualizer看看畫面。
3. 網路上有各種語言用的API: https://developer.leapmotion.com/documentation/cpp/api/Leap_Classes.html
因為要搭配OpenCV寫,所以先研究C語言的寫法。
下載安裝完SDK之後,建立一個專案檔,把LeapMotion相關的東西放進去專案,包括include、lib、dll,並且設定好連結環境。
1. 開啟LeapMotion畫面,抓到手指位置,辨識手勢
開始寫程式
#include <Leap.h> #include <math.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace std; Leap::Device cDevice; Leap::Controller cController; Leap::Frame cFrame; Leap::ImageList cImageList; Leap::Image cImageR; Leap::HandList cHandList; Leap::Hand cHand; Leap::FingerList cFingerList; Leap::Finger cFinger, cFinger2; Leap::GestureList cGestureList; Leap::Gesture cGesture; Leap::SwipeGesture cSwipeGesture; cv::Mat LeapMatR, drawMat; int main() { cController.setPolicy(Leap::Controller::POLICY_IMAGES); cController.enableGesture(Leap::Gesture::TYPE_SWIPE); Sleep(1000); while(true){ cFrame = cController.frame(); if (cFrame.isValid()){ cImageList = cFrame.images(); // Get Left Raw Images cImageR = cImageList[0]; LeapMatR.create(rows, cols, CV_8UC1); LeapMatR.data = (uchar*)cImageR.data(); Sleep(50); if (LeapMatR.empty()){ continue; } // get hand and fingers cHandList = cFrame.hands(); HandNum = cHandList.count(); cHand = cHandList[0]; cHand2 = cHandList[1]; // first hand if(cHand.isValid()){ HandX = cHand.palmPosition().x; HandY = cHand.palmPosition().y; HandZ = cHand.palmPosition().z; HandX = ((HandX+200.0)/400.0)*640.0; HandZ = ((HandZ+200.0)/400.0)*480.0; float pitch = cHand.direction().pitch(); float yaw = cHand.direction().yaw(); float roll = cHand.palmNormal().roll(); //pitch, yaw, roll of hand, -1.0~1.0 //printf("p:%.1f, y:%.1f, r:%.1f\n", pitch, yaw, roll); // gesture cGestureList = cFrame.gestures(); cGesture = cGestureList[0]; if (HandX > -100 && HandX < 2000 && HandY < 1300 && HandZ > 0 && HandZ < 600){ if (cGesture.type() == Leap::Gesture::TYPE_SWIPE){ cSwipeGesture = Leap::SwipeGesture(cGesture); bool isHorizontal = abs(cSwipeGesture.direction()[0]) > abs(cSwipeGesture.direction()[1]); if (isHorizontal){ if (cSwipeGesture.direction()[0] > 0){ Gesture_str = "right"; } else { Gesture_str = "left"; } printf("swipe,%s", &Gesture_str); Sleep(1000); } } else{ // grab if (cHand.grabAngle() > 3){ printf("grab\n"); } else{ printf("release\n"); } } } // fingers for (int i = 0; i < 5; i++){ cFinger = cHand.fingers()[i]; FingerX[i] = cFinger.tipPosition().x; FingerY[i] = cFinger.tipPosition().y; FingerZ[i] = cFinger.tipPosition().z; FingerX[i] = ((FingerX[i] + 200.0) / 400.0)*640.0; FingerZ[i] = ((FingerZ[i] + 200.0) / 400.0)*480.0; } } // second hand if (cHand2.isValid()){ Hand2X = cHand2.palmPosition().x; Hand2Y = cHand2.palmPosition().y; Hand2Z = cHand2.palmPosition().z; Hand2X = ((Hand2X + 200.0) / 400.0)*640.0; Hand2Z = ((Hand2Z + 200.0) / 400.0)*480.0; if (Hand2X > -100 && Hand2X < 2000 && Hand2Y < 1300 && Hand2Z > 0 && Hand2Z < 600){ // grab if (cHand2.grabAngle() > 3){ printf("grab\n"); } else{ printf("release\n"); } } // fingers for (int i = 0; i < 5; i++){ cFinger2 = cHand2.fingers()[i]; Finger2X[i] = cFinger2.tipPosition().x; Finger2Y[i] = cFinger2.tipPosition().y; Finger2Z[i] = cFinger2.tipPosition().z; Finger2X[i] = ((Finger2X[i] + 200.0) / 400.0)*640.0; Finger2Z[i] = ((Finger2Z[i] + 200.0) / 400.0)*480.0; } } if(isShowWindow){ cv::flip(LeapMatR, LeapMatR, 1); imshow("LeapImageR", LeapMatR); drawMat.create(600, 800, CV_8UC4); // draw first hands and fingers cv::Point Handcenter(HandX, HandZ); cv::circle(drawMat, Handcenter, 20, cv::Scalar(0, 0, 255), -1, 8, 0); for(int i=0; i<5 i="" if="" ingerx="">=0 && FingerZ[i]>=0){ cv::Point FingerCenter(FingerX[i], FingerZ[i]); cv::circle(drawMat, FingerCenter, 10, cv::Scalar(0, 255, 0), -1, 8, 0); } } // draw second hands and fingers cv::Point Handcenter2(Hand2X, Hand2Z); cv::circle(drawMat, Handcenter2, 20, cv::Scalar(0, 0, 255), -1, 8, 0); for (int i = 0; i<5 i="" if="" inger2x="">= 0 && Finger2Z[i] >= 0){ cv::Point FingerCenter(Finger2X[i], Finger2Z[i]); cv::circle(drawMat, FingerCenter, 10, cv::Scalar(0, 255, 0), -1, 8, 0); } } imshow("DrawInfo", drawMat); drawMat.release(); cv::waitKey(20); } else{ cv::destroyAllWindows(); } } // ctrl+F3: show window if(GetAsyncKeyState(17) && GetAsyncKeyState(114)){ printf("show window flag\n"); isShowWindow = !isShowWindow; // Start time time(&start); fps = 0; count = 0; Sleep(200); } // ctrl+F5: close or open cmd window if (GetAsyncKeyState(17) && GetAsyncKeyState(116)){ cmdFlag = !cmdFlag; ShowWindow(CmdhWnd, cmdFlag); Sleep(200); } // ctrl+F1:exit if (GetAsyncKeyState(17) && GetAsyncKeyState(112)){ sprintf(sendChar, "E"); int sendLen = strlen(sendChar); LSockApp.SendData(sendChar, sendLen); break; } } CloseServiceHandle(serviceHandle); CloseServiceHandle(serviceDbHandle); return 0; } 5>5>
結束寫程式
沒有留言:
張貼留言