10 #ifdef SL_BUILD_WITH_MEDIAPIPE 
   14 #    define CHECK_MP_RESULT(result) \ 
   17             const char* error = mp_get_last_error(); \ 
   18             std::cerr << error << std::endl; \ 
   19             mp_free_error(error); \ 
   20             SL_EXIT_MSG("Exiting due to MediaPipe error"); \
 
   23 typedef std::vector<std::pair<mp_hand_landmark, mp_hand_landmark>> ConnectionList;
 
   26 static const ConnectionList CONNECTIONS = {
 
   27   {mp_hand_landmark_wrist, mp_hand_landmark_thumb_cmc},
 
   28   {mp_hand_landmark_thumb_cmc, mp_hand_landmark_thumb_mcp},
 
   29   {mp_hand_landmark_thumb_mcp, mp_hand_landmark_thumb_ip},
 
   30   {mp_hand_landmark_thumb_ip, mp_hand_landmark_thumb_tip},
 
   31   {mp_hand_landmark_wrist, mp_hand_landmark_index_finger_mcp},
 
   32   {mp_hand_landmark_index_finger_mcp, mp_hand_landmark_index_finger_pip},
 
   33   {mp_hand_landmark_index_finger_pip, mp_hand_landmark_index_finger_dip},
 
   34   {mp_hand_landmark_index_finger_dip, mp_hand_landmark_index_finger_tip},
 
   35   {mp_hand_landmark_index_finger_mcp, mp_hand_landmark_middle_finger_mcp},
 
   36   {mp_hand_landmark_middle_finger_mcp, mp_hand_landmark_middle_finger_pip},
 
   37   {mp_hand_landmark_middle_finger_pip, mp_hand_landmark_middle_finger_dip},
 
   38   {mp_hand_landmark_middle_finger_dip, mp_hand_landmark_middle_finger_tip},
 
   39   {mp_hand_landmark_middle_finger_mcp, mp_hand_landmark_ring_finger_mcp},
 
   40   {mp_hand_landmark_ring_finger_mcp, mp_hand_landmark_ring_finger_pip},
 
   41   {mp_hand_landmark_ring_finger_pip, mp_hand_landmark_ring_finger_dip},
 
   42   {mp_hand_landmark_ring_finger_dip, mp_hand_landmark_ring_finger_tip},
 
   43   {mp_hand_landmark_ring_finger_mcp, mp_hand_landmark_pinky_mcp},
 
   44   {mp_hand_landmark_wrist, mp_hand_landmark_pinky_mcp},
 
   45   {mp_hand_landmark_pinky_mcp, mp_hand_landmark_pinky_pip},
 
   46   {mp_hand_landmark_pinky_pip, mp_hand_landmark_pinky_dip},
 
   47   {mp_hand_landmark_pinky_dip, mp_hand_landmark_pinky_tip}};
 
   49 CVTrackedMediaPipeHands::CVTrackedMediaPipeHands(
SLstring dataPath)
 
   51     mp_set_resource_dir(dataPath.c_str());
 
   53     SLstring graphPath = dataPath + 
"mediapipe/modules/hand_landmark/hand_landmark_tracking_cpu.binarypb";
 
   54     auto*    builder   = mp_create_instance_builder(graphPath.c_str(), 
"image");
 
   63     mp_add_side_packet(builder,
 
   65                        mp_create_packet_bool(
true));
 
   69     mp_add_side_packet(builder,
 
   71                        mp_create_packet_int(2));
 
   77     mp_add_side_packet(builder,
 
   79                        mp_create_packet_int(1));
 
   83     mp_add_option_float(builder,
 
   84                         "palmdetectioncpu__TensorsToDetectionsCalculator",
 
   90     mp_add_option_double(builder,
 
   91                          "handlandmarkcpu__ThresholdingCalculator",
 
   96     _instance = mp_create_instance(builder);
 
   97     CHECK_MP_RESULT(_instance)
 
  100     _landmarksPoller = mp_create_poller(_instance,
 
  101                                         "multi_hand_landmarks");
 
  102     CHECK_MP_RESULT(_landmarksPoller)
 
  105     CHECK_MP_RESULT(mp_start(_instance))
 
  117 CVTrackedMediaPipeHands::~CVTrackedMediaPipeHands()
 
  119     mp_destroy_poller(_landmarksPoller);
 
  120     CHECK_MP_RESULT(mp_destroy_instance(_instance))
 
  123 bool CVTrackedMediaPipeHands::track(
CVMat          imageGray,
 
  127     processImageInMediaPipe(imageBgr);
 
  129     if (mp_get_queue_size(_landmarksPoller) > 0)
 
  131         auto* landmarksPacket = mp_poll_packet(_landmarksPoller);
 
  132         auto* landmarks       = mp_get_norm_multi_face_landmarks(landmarksPacket);
 
  134         drawResults(landmarks, imageBgr);
 
  136         mp_destroy_multi_face_landmarks(landmarks);
 
  137         mp_destroy_packet(landmarksPacket);
 
  143 void CVTrackedMediaPipeHands::processImageInMediaPipe(
CVMat imageBgr)
 
  145     cv::cvtColor(imageBgr, _imageRgb, cv::COLOR_BGR2RGB);
 
  148     inImage.data      = _imageRgb.data;
 
  149     inImage.width     = _imageRgb.cols;
 
  150     inImage.height    = _imageRgb.rows;
 
  151     inImage.format    = mp_image_format_srgb;
 
  152     mp_packet* packet = mp_create_packet_image(inImage);
 
  155     CHECK_MP_RESULT(mp_process(_instance, packet))
 
  158     CHECK_MP_RESULT(mp_wait_until_idle(_instance))
 
  162 void CVTrackedMediaPipeHands::drawResults(mp_multi_face_landmark_list* landmarks,
 
  165     for (
int i = 0; i < landmarks->length; i++)
 
  167         auto& hand = landmarks->elements[i];
 
  169         for (
auto& connection : CONNECTIONS)
 
  171             auto  p1 = hand.elements[connection.first];
 
  172             auto  p2 = hand.elements[connection.second];
 
  173             float x1 = (float)imageBgr.cols * p1.x;
 
  174             float y1 = (
float)imageBgr.rows * p1.y;
 
  175             float x2 = (float)imageBgr.cols * p2.x;
 
  176             float y2 = (
float)imageBgr.rows * p2.y;
 
  185         for (
int j = 0; j < hand.length; j++)
 
  187             auto  p      = hand.elements[j];
 
  188             float x      = (float)imageBgr.cols * p.x;
 
  189             float y      = (
float)imageBgr.rows * p.y;
 
  190             float radius = std::max(3.0f + 25.0f * -p.z, 1.0f);
 
Live video camera calibration class with OpenCV an OpenCV calibration.