2017/05/10

[C/Cpp] LeapMotion with OpenCV

1. 先到官網下載SDK。https://developer.leapmotion.com/get-started
2. 安裝完之後先跑LeapMotionVisiualizer看看畫面。
3. 網路上有各種語言用的API: https://developer.leapmotion.com/documentation/cpp/api/Leap_Classes.html

因為要搭配OpenCV寫,所以先研究C語言的寫法。



下載安裝完SDK之後,建立一個專案檔,把LeapMotion相關的東西放進去專案,包括include、lib、dll,並且設定好連結環境。
1. 開啟LeapMotion畫面,抓到手指位置,辨識手勢
開始寫程式
  1. #include <Leap.h>
  2. #include <math.h>
  3. #include <opencv2/core/core.hpp>
  4. #include <opencv2/highgui/highgui.hpp>
  5. #include <opencv2/imgproc/imgproc.hpp>
  6. using namespace std;
  7.  
  8. Leap::Device cDevice;
  9. Leap::Controller cController;
  10. Leap::Frame cFrame;
  11. Leap::ImageList cImageList;
  12. Leap::Image cImageR;
  13.  
  14. Leap::HandList cHandList;
  15. Leap::Hand cHand;
  16.  
  17. Leap::FingerList cFingerList;
  18. Leap::Finger cFinger, cFinger2;
  19.  
  20. Leap::GestureList cGestureList;
  21. Leap::Gesture cGesture;
  22. Leap::SwipeGesture cSwipeGesture;
  23.  
  24. cv::Mat LeapMatR, drawMat;
  25.  
  26. int main()
  27. {
  28. cController.setPolicy(Leap::Controller::POLICY_IMAGES);
  29. cController.enableGesture(Leap::Gesture::TYPE_SWIPE);
  30. Sleep(1000);
  31.  
  32. while(true){
  33. cFrame = cController.frame();
  34. if (cFrame.isValid()){
  35. cImageList = cFrame.images();
  36.  
  37. // Get Left Raw Images
  38. cImageR = cImageList[0];
  39. LeapMatR.create(rows, cols, CV_8UC1);
  40. LeapMatR.data = (uchar*)cImageR.data();
  41. Sleep(50);
  42. if (LeapMatR.empty()){
  43. continue;
  44. }
  45. // get hand and fingers
  46. cHandList = cFrame.hands();
  47. HandNum = cHandList.count();
  48. cHand = cHandList[0];
  49. cHand2 = cHandList[1];
  50.  
  51. // first hand
  52. if(cHand.isValid()){
  53.  
  54. HandX = cHand.palmPosition().x;
  55. HandY = cHand.palmPosition().y;
  56. HandZ = cHand.palmPosition().z;
  57. HandX = ((HandX+200.0)/400.0)*640.0;
  58. HandZ = ((HandZ+200.0)/400.0)*480.0;
  59.  
  60. float pitch = cHand.direction().pitch();
  61. float yaw = cHand.direction().yaw();
  62. float roll = cHand.palmNormal().roll();
  63. //pitch, yaw, roll of hand, -1.0~1.0
  64. //printf("p:%.1f, y:%.1f, r:%.1f\n", pitch, yaw, roll);
  65. // gesture
  66. cGestureList = cFrame.gestures();
  67. cGesture = cGestureList[0];
  68. if (HandX > -100 && HandX < 2000 && HandY < 1300 && HandZ > 0 && HandZ < 600){
  69. if (cGesture.type() == Leap::Gesture::TYPE_SWIPE){
  70. cSwipeGesture = Leap::SwipeGesture(cGesture);
  71. bool isHorizontal = abs(cSwipeGesture.direction()[0]) > abs(cSwipeGesture.direction()[1]);
  72. if (isHorizontal){
  73. if (cSwipeGesture.direction()[0] > 0){
  74. Gesture_str = "right";
  75. }
  76. else {
  77. Gesture_str = "left";
  78. }
  79. printf("swipe,%s", &Gesture_str);
  80. Sleep(1000);
  81. }
  82. }
  83. else{
  84. // grab
  85. if (cHand.grabAngle() > 3){
  86. printf("grab\n");
  87. }
  88. else{
  89. printf("release\n");
  90. }
  91. }
  92. }
  93. // fingers
  94. for (int i = 0; i < 5; i++){
  95. cFinger = cHand.fingers()[i];
  96. FingerX[i] = cFinger.tipPosition().x;
  97. FingerY[i] = cFinger.tipPosition().y;
  98. FingerZ[i] = cFinger.tipPosition().z;
  99.  
  100. FingerX[i] = ((FingerX[i] + 200.0) / 400.0)*640.0;
  101. FingerZ[i] = ((FingerZ[i] + 200.0) / 400.0)*480.0;
  102. }
  103. }
  104. // second hand
  105. if (cHand2.isValid()){
  106. Hand2X = cHand2.palmPosition().x;
  107. Hand2Y = cHand2.palmPosition().y;
  108. Hand2Z = cHand2.palmPosition().z;
  109.  
  110. Hand2X = ((Hand2X + 200.0) / 400.0)*640.0;
  111. Hand2Z = ((Hand2Z + 200.0) / 400.0)*480.0;
  112.  
  113. if (Hand2X > -100 && Hand2X < 2000 && Hand2Y < 1300 && Hand2Z > 0 && Hand2Z < 600){
  114. // grab
  115. if (cHand2.grabAngle() > 3){
  116. printf("grab\n");
  117. }
  118. else{
  119. printf("release\n");
  120. }
  121. }
  122. // fingers
  123. for (int i = 0; i < 5; i++){
  124. cFinger2 = cHand2.fingers()[i];
  125. Finger2X[i] = cFinger2.tipPosition().x;
  126. Finger2Y[i] = cFinger2.tipPosition().y;
  127. Finger2Z[i] = cFinger2.tipPosition().z;
  128.  
  129. Finger2X[i] = ((Finger2X[i] + 200.0) / 400.0)*640.0;
  130. Finger2Z[i] = ((Finger2Z[i] + 200.0) / 400.0)*480.0;
  131. }
  132. }
  133. if(isShowWindow){
  134. cv::flip(LeapMatR, LeapMatR, 1);
  135. imshow("LeapImageR", LeapMatR);
  136. drawMat.create(600, 800, CV_8UC4);
  137. // draw first hands and fingers
  138. cv::Point Handcenter(HandX, HandZ);
  139. cv::circle(drawMat, Handcenter, 20, cv::Scalar(0, 0, 255), -1, 8, 0);
  140. for(int i=0; i<5 i="" if="" ingerx="">=0 && FingerZ[i]>=0){
  141. cv::Point FingerCenter(FingerX[i], FingerZ[i]);
  142. cv::circle(drawMat, FingerCenter, 10, cv::Scalar(0, 255, 0), -1, 8, 0);
  143. }
  144. }
  145. // draw second hands and fingers
  146. cv::Point Handcenter2(Hand2X, Hand2Z);
  147. cv::circle(drawMat, Handcenter2, 20, cv::Scalar(0, 0, 255), -1, 8, 0);
  148. for (int i = 0; i<5 i="" if="" inger2x="">= 0 && Finger2Z[i] >= 0){
  149. cv::Point FingerCenter(Finger2X[i], Finger2Z[i]);
  150. cv::circle(drawMat, FingerCenter, 10, cv::Scalar(0, 255, 0), -1, 8, 0);
  151. }
  152. }
  153. imshow("DrawInfo", drawMat);
  154. drawMat.release();
  155. cv::waitKey(20);
  156. }
  157. else{
  158. cv::destroyAllWindows();
  159. }
  160. }
  161. // ctrl+F3: show window
  162. if(GetAsyncKeyState(17) && GetAsyncKeyState(114)){
  163. printf("show window flag\n");
  164. isShowWindow = !isShowWindow;
  165. // Start time
  166. time(&start);
  167. fps = 0;
  168. count = 0;
  169. Sleep(200);
  170. }
  171. // ctrl+F5: close or open cmd window
  172. if (GetAsyncKeyState(17) && GetAsyncKeyState(116)){
  173. cmdFlag = !cmdFlag;
  174. ShowWindow(CmdhWnd, cmdFlag);
  175. Sleep(200);
  176. }
  177. // ctrl+F1:exit
  178. if (GetAsyncKeyState(17) && GetAsyncKeyState(112)){
  179. sprintf(sendChar, "E");
  180. int sendLen = strlen(sendChar);
  181. LSockApp.SendData(sendChar, sendLen);
  182. break;
  183. }
  184. }
  185. CloseServiceHandle(serviceHandle);
  186. CloseServiceHandle(serviceDbHandle);
  187. return 0;
  188. }
  189.  

結束寫程式




沒有留言:

張貼留言