Kinect for windows v2 姿势识别工具之 开发 Visual Gesture Builder 匹配程序(c++版本)

转载至:https://www.parful.com/blog/article/110

在开始学习这篇教程前,你首先需要了解如何利用VGB工具制作一个后缀名为 .gba 或 .gbd 的姿势数据库文件。如果没有此基础,请按顺序阅读:

开发你自己的第一个 Kinect Gestrue 匹配程序

你需要在你的vs项目中设置好 包含目录 及 库目录,包含目录为 Kinect 安装目录下的 inc 目录,库目录在 Kinect 安装目录下的 Lib 文件夹中(包含 x64 x86,请选择你需要的版本)。

包含头文件及引入库

 
  1. #include "Kinect.h"
  2. #include "Kinect.VisualGestureBuilder.h"
  3.  
  4. #pragma comment(lib,"Kinect20.lib")
  5. #pragma comment(lib,"Kinect20.VisualGestureBuilder.lib")

打开Kinect传感器

 
  1. IKinectSensor* pSensor = nullptr;
  2. if (GetDefaultKinectSensor(&pSensor) != S_OK)
  3. {
  4. return 1;
  5. }
  6. pSensor->Open();

读取 gesture 数据库

 
  1. wstring gestureDatabasePath = L"Seat.gbd";
  2. IVisualGestureBuilderDatabase* pGestureDatabase = nullptr;
  3. if (CreateVisualGestureBuilderDatabaseInstanceFromFile(gestureDatabasePath.c_str(), &pGestureDatabase)!=S_OK)
  4. {
  5. wcout << "Can not read the database, Please check if it exit!" << endl;
  6. return 1;
  7. }

获取 gesture 数据库中 gesture 数量 及 gesture 信息

 
  1. UINT numGesture = 0;
  2. //Get how many gestures in database
  3. pGestureDatabase->get_AvailableGesturesCount(&numGesture);
  4. wcout << "Total gesture count:" << numGesture << endl;
  5. //Get the list of gestures
  6. IGesture** gestureList = new IGesture*[numGesture];
  7. pGestureDatabase->get_AvailableGestures(numGesture, gestureList);
  8. //GestureType enum
  9. GestureType gestureType;
  10. wchar_t gestureName[300];
  11. for (int index = 0; index < numGesture; ++index)
  12. {
  13. if (gestureList[index]->get_GestureType(&gestureType) == S_OK)
  14. {
  15. if (gestureType == GestureType::GestureType_Discrete)
  16. {
  17. //Get discrete gesture name
  18. gestureList[index]->get_Name(300, gestureName);
  19. wcout << "discrete_gesture_" << index << "_name:" << gestureName << endl;
  20. }
  21. else if (gestureType == GestureType::GestureType_Continuous)
  22. {
  23. //Get continuous gesture name
  24. gestureList[index]->get_Name(300, gestureName);
  25. wcout << "continuous_gesture_" << index << "_name" << gestureName << endl;
  26. }
  27. }
  28. }

创建gesture数据流及读取器

一个数据流对应一个流的读取器,体感最大可以同时检测到6个body数据(numBody=6).为了实现同时检测多人的姿势,所以此处创建6个gesture流与6个gesture流的读取器

 
  1. IVisualGestureBuilderFrameSource** gestureSources = new IVisualGestureBuilderFrameSource*[numBody];
  2. IVisualGestureBuilderFrameReader** gestureReaders = new IVisualGestureBuilderFrameReader*[numBody];
  3.  
  4. for (int bodyIndex = 0; bodyIndex < numBody; ++bodyIndex)
  5. {
  6. CreateVisualGestureBuilderFrameSource(pSensor, bodyIndex, &gestureSources[bodyIndex]);
  7. gestureSources[bodyIndex]->AddGestures(numGesture, gestureList);
  8. gestureSources[bodyIndex]->OpenReader(&gestureReaders[bodyIndex]);
  9. }

进入跟踪到人体骨架信息时的逻辑

 
  1. IBodyFrame* pFrame = nullptr;
  2. //Gets the latest frame.
  3. if (pFrameReader->AcquireLatestFrame(&pFrame) == S_OK)
  4. {
  5. //for each frame, update the body data
  6. if (pFrame->GetAndRefreshBodyData(numBody, bodies) == S_OK)
  7. {
  8. for (int bodyIndex = 0; bodyIndex < numBody; ++bodyIndex)
  9. {
  10. BOOLEAN tracked = false;
  11. IBody* pBody = bodies[bodyIndex];
  12. //has tracked body
  13. if (pBody->get_IsTracked(&tracked) == S_OK&&tracked)
  14. {
  15. //Process body
  16. }
  17. }
  18. }
  19. pFrame->Release();
  20. }

绑定gesture数据流所跟踪的骨架id

 
  1. UINT64 trackingId = 0;
  2. if (pBody->get_TrackingId(&trackingId) == S_OK)
  3. {
  4. UINT64 gestureId = 0;
  5. if (gestureSources[bodyIndex]->get_TrackingId(&gestureId) == S_OK)
  6. {
  7. if (gestureId != trackingId)
  8. {
  9. //Bind tracking ID
  10. gestureSources[bodyIndex]->put_TrackingId(trackingId);
  11. wcout << "Gesture Source " << bodyIndex << " start to track user " << trackingId << endl;
  12. }
  13. }
  14. }

获取gesture数据库与体感实时body数据的匹配结果

最后获取到的结果有两种可能,IDiscreteGestureResult(离散型姿势结果) 与 IContinuousGestureResult(连续型姿势结果)。

  • IDicreteGestureResult可获取的结果为一个 BOOLEAN 变量,当离散型姿势匹配成功时,伴有一个值为 float 的 confidence(值为 0-1)。
  • IContinuousGestureResult可获取的结果是一个 float 变量,值为 0-1 代表该连续动作的进度值,这个值是一直存在的。
 
  1. IVisualGestureBuilderFrame* pGestureFrame = nullptr;
  2. //Get latest frame
  3. if (gestureReaders[bodyIndex]->CalculateAndAcquireLatestFrame(&pGestureFrame) == S_OK)
  4. {
  5. BOOLEAN bGestureTracked = false;
  6. if (pGestureFrame->get_IsTrackingIdValid(&bGestureTracked) == S_OK&&bGestureTracked)
  7. {
  8. for (UINT gestureIndex = 0; gestureIndex < numGesture; ++gestureIndex)
  9. {
  10. GestureType gestureType;
  11. gestureList[gestureIndex]->get_GestureType(&gestureType);
  12.  
  13. wchar_t gestureName[260];
  14. gestureList[gestureIndex]->get_Name(260, gestureName);
  15. //Discrete gesture
  16. if (gestureType == GestureType::GestureType_Discrete)
  17. {
  18. IDiscreteGestureResult* pGestureResult = nullptr;
  19. if (pGestureFrame->get_DiscreteGestureResult(gestureList[gestureIndex], &pGestureResult) == S_OK)
  20. {
  21. BOOLEAN detected = false;
  22. if (pGestureResult->get_Detected(&detected) == S_OK&&detected)
  23. {
  24. float confidence = 0.0f;
  25. pGestureResult->get_Confidence(&confidence);
  26. wcout <<gestureName<<"-Confidence:" << confidence<<endl;
  27. pGestureResult->Release();
  28. }
  29. }
  30. } //Continuous gesture
  31. else if (gestureType == GestureType::GestureType_Continuous)
  32. {
  33. IContinuousGestureResult* pGestureResult = nullptr;
  34. if (pGestureFrame->get_ContinuousGestureResult(gestureList[gestureIndex], &pGestureResult) == S_OK)
  35. {
  36. float progress = 0.0f;
  37. if (pGestureResult->get_Progress(&progress) == S_OK)
  38. {
  39. wcout << gestureName << "-progress:" << progress << endl;
  40. }
  41. pGestureResult->Release();
  42. }
  43. }
  44. }
  45. }
  46. pGestureFrame->Release();
  47. }
  48. 完整代码下载请移步原文处:https://www.parful.com/blog/article/110

猜你喜欢

转载自blog.csdn.net/ZDT_zdh/article/details/90473976
今日推荐