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>
結束寫程式
沒有留言:
張貼留言