{"id":147062,"date":"2024-03-28T14:20:34","date_gmt":"2024-03-28T14:20:34","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=147062"},"modified":"2024-03-28T14:40:21","modified_gmt":"2024-03-28T14:40:21","slug":"install-mediapipe-raspberry-pi","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/install-mediapipe-raspberry-pi\/","title":{"rendered":"Install MediaPipe on a Raspberry Pi &#8211; Example Gesture Recognition"},"content":{"rendered":"\n<p>This guide is an introduction to the <span class=\"rnthl rntliteral\">MediaPipe<\/span> Python library on a Raspberry Pi board. It covers installing MediaPipe using pip on a virtual environment and running a gesture recognition example. <\/p>\n\n\n\n<p>MediaPipe is a cross-platform pipeline framework to build custom machine learning (ML) solutions for streaming media (live video). The MediaPipe framework was open-sourced by Google and is currently available in early release.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Raspberry-Pi-Getting-Started-Media-Pipe.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Install MediaPipe on a Raspberry Pi - Example Gesture Recognition\" class=\"wp-image-148804\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Raspberry-Pi-Getting-Started-Media-Pipe.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Raspberry-Pi-Getting-Started-Media-Pipe.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Raspberry-Pi-Getting-Started-Media-Pipe.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Raspberry-Pi-Getting-Started-Media-Pipe.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<p>Before proceeding: <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You need a <a href=\"https:\/\/makeradvisor.com\/best-raspberry-pi-starter-kits\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Raspberry Pi board<\/a> and a <a href=\"https:\/\/makeradvisor.com\/tools\/usb-camera-logitech\/\" target=\"_blank\" rel=\"noopener\" title=\"\">USB Camera<\/a>.<\/li>\n\n\n\n<li>You should have a <a href=\"https:\/\/randomnerdtutorials.com\/installing-raspbian-lite-enabling-and-connecting-with-ssh\/#install-raspberry-pi-os\">Raspberry Pi running Raspberry Pi OS<\/a> (32-bit or 64-bit).<\/li>\n\n\n\n<li>You should be able to <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-remote-desktop-connection-rdp-windows\/\">establish a Remote Desktop Connection with your Raspberry Pi<\/a> &#8211; <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-remote-desktop-connection-rdp-mac-os\/\">click here for Mac OS instructions<\/a>.<\/li>\n\n\n\n<li>You should have <a href=\"https:\/\/randomnerdtutorials.com\/install-opencv-raspberry-pi\/\">OpenCV installed on your Raspberry Pi<\/a>.<\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/set-up-usb-camera-opencv-raspberry-pi\/\">Set Up USB Camera for OpenCV Projects with Raspberry Pi<\/a>.<\/li>\n<\/ul>\n\n\n\n<p>In our Raspberry Pi projects with a camera, we will be using a regular <a href=\"https:\/\/makeradvisor.com\/tools\/usb-camera-logitech\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Logitech USB camera<\/a>, like the one shown in the picture below.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"393\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/USB-Camera-Webcam-Raspberry-Pi-compatible.jpg?resize=750%2C393&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"USB Camera Webcam Raspberry Pi compatible\" class=\"wp-image-146968\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/USB-Camera-Webcam-Raspberry-Pi-compatible.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/USB-Camera-Webcam-Raspberry-Pi-compatible.jpg?resize=300%2C157&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">MediaPipe<\/h2>\n\n\n\n<p>MediaPipe is an open-source cross-platform framework for building pipelines to perform computer vision applications built on top of TensorFlow Lite. <\/p>\n\n\n\n<p>MediaPipe has abstracted away the complexities of making on-device ML customizable, production-ready, and accessible across platforms. Using MediaPipe, you can use a simple API that receives an input image and outputs a prediction result.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hand Gesture Example<\/h3>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"900\" height=\"407\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/MediaPipe-on-device-machine-learning-ml-api.png?resize=900%2C407&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"MediaPipe on-device machine learning ML API\" class=\"wp-image-147278\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/MediaPipe-on-device-machine-learning-ml-api.png?w=900&amp;quality=100&amp;strip=all&amp;ssl=1 900w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/MediaPipe-on-device-machine-learning-ml-api.png?resize=300%2C136&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/MediaPipe-on-device-machine-learning-ml-api.png?resize=768%2C347&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 900px) 100vw, 900px\" \/><\/figure><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>Input: image of a person doing the thumbs-up gesture<\/li>\n\n\n\n<li>MediaPipe does all the heavy work for you:\n<ul class=\"wp-block-list\">\n<li>Detects if there&#8217;s a hand in the image provided;<\/li>\n\n\n\n<li>Then, it detects the hand&#8217;s landmarks;<\/li>\n\n\n\n<li>Creates an embedding vector of the gestures.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Output: classifies the image based on the provided model (detects the thumbs-up gesture).<\/li>\n<\/ul>\n\n\n\n<p>In summary, here are the MediaPipe key features:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>On-device machine learning (ML) solution with simple-to-use abstractions.<\/li>\n\n\n\n<li>Lightweight ML models, all while preserving accuracy.<\/li>\n\n\n\n<li>Domain-specific processing including vision, text, and audio.<\/li>\n\n\n\n<li>Uses low-code APIs or no-code studio to customize, evaluate, prototype, and deploy.<\/li>\n\n\n\n<li>End-to-end optimization, including hardware acceleration, all while lightweight enough to run well on battery-powered devices.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"pip-virtual-environment\">Installing MediaPipe on Raspberry Pi with pip on Virtual Environment (Recommended)<\/h2>\n\n\n\n<p>Having a Remote Desktop Connection with your Raspberry Pi, update and upgrade your Raspberry Pi if any updates are available. Run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update &amp;&amp; sudo apt upgrade -y<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Create a Virtual Environment<\/h3>\n\n\n\n<p>We already <a href=\"https:\/\/randomnerdtutorials.com\/install-opencv-raspberry-pi\/\" title=\"\">installed the OpenCV library in a virtual environment in a previous guide<\/a>. We need to install the MediaPipe library in the same virtual environment.<\/p>\n\n\n\n<p>Enter the following command on a Terminal window to move to the <em>Projects <\/em>directory on the <em>Desktop<\/em>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/Desktop\/projects<\/code><\/pre>\n\n\n\n<p>Then, you can run the following command to check that the virtual environment is there.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ls -l<\/code><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"589\" height=\"162\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/python3-virtual-environment.png?resize=589%2C162&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"create python3 virtual environment for Raspberry Pi Projects\" class=\"wp-image-146637\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/python3-virtual-environment.png?w=589&amp;quality=100&amp;strip=all&amp;ssl=1 589w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/python3-virtual-environment.png?resize=300%2C83&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 589px) 100vw, 589px\" \/><\/figure><\/div>\n\n\n<p>Activate the virtual environment <em>projectsenv<\/em> that was previously created when installing OpenCV:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>source projectsenv\/bin\/activate<\/code><\/pre>\n\n\n\n<p>Your prompt should change to indicate that you are now in the virtual environment.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"637\" height=\"114\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/python3-activate-virtual-environment.png?resize=637%2C114&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Python 3 activate Virtual Environment\" class=\"wp-image-146634\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/python3-activate-virtual-environment.png?w=637&amp;quality=100&amp;strip=all&amp;ssl=1 637w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/python3-activate-virtual-environment.png?resize=300%2C54&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 637px) 100vw, 637px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">Installing the MediaPipe Library<\/h3>\n\n\n\n<p>Now that we are in our virtual environment, we can install the MediaPipe library. Run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pip3 install mediapipe<\/code><\/pre>\n\n\n\n<p>After a few seconds, the library will be installed (ignore any yellow warnings about deprecated packages).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1029\" height=\"592\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/installing-MediaPipe-on-Raspberry-Pi-pip3-virtual-environment.png?resize=1029%2C592&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Installing MediaPipe on Raspberry Pi pip3 virtual environment\" class=\"wp-image-147068\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/installing-MediaPipe-on-Raspberry-Pi-pip3-virtual-environment.png?w=1029&amp;quality=100&amp;strip=all&amp;ssl=1 1029w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/installing-MediaPipe-on-Raspberry-Pi-pip3-virtual-environment.png?resize=300%2C173&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/installing-MediaPipe-on-Raspberry-Pi-pip3-virtual-environment.png?resize=1024%2C589&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/installing-MediaPipe-on-Raspberry-Pi-pip3-virtual-environment.png?resize=768%2C442&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1029px) 100vw, 1029px\" \/><\/figure><\/div>\n\n\n<p>You have everything ready to start writing your Python code and testing the gesture recognition example.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">MediaPipe Example &#8211; Gesture Recognition with Raspberry Pi<\/h2>\n\n\n\n<p>Having MediaPipe installed, we&#8217;ll be running a sample code that does gesture recognition. This script recognizes hand gestures in an image or video format. The default model can recognize seven different gestures in one or two hands:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Thumb up \ud83d\udc4d<\/li>\n\n\n\n<li>Thumb down \ud83d\udc4e<\/li>\n\n\n\n<li>Victory hand \u270c\ufe0f<\/li>\n\n\n\n<li>Index pointing up \u261d\ufe0f<\/li>\n\n\n\n<li>Raised fist \u270a<\/li>\n\n\n\n<li>Open palm \u270b<\/li>\n\n\n\n<li>Love-You gesture \ud83e\udd1f<\/li>\n<\/ul>\n\n\n\n<p>This particular model was created by Google and it went through their rigorous ML Fairness standards and is production-ready.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Gesture Recognition &#8211; Python Script<\/h3>\n\n\n\n<p>Clone the GitHub repository to your Raspberry Pi with the <em>git <\/em>command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/RuiSantosdotme\/mediapipe.git<\/code><\/pre>\n\n\n\n<p>Change to the <em>mediapipe\/raspberry_pi_gesture_recognizer<\/em> directory<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd mediapipe\/raspberry_pi_gesture_recognizer<\/code><\/pre>\n\n\n\n<p>Use the <em>ls<\/em> command to see if you find the files illustrated in the screenshot below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ls<\/code><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"835\" height=\"184\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Check-MediaPipe-Gesture-recognition-example-script.png?resize=835%2C184&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Check MediaPipe Gesture recognition example script\" class=\"wp-image-147283\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Check-MediaPipe-Gesture-recognition-example-script.png?w=835&amp;quality=100&amp;strip=all&amp;ssl=1 835w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Check-MediaPipe-Gesture-recognition-example-script.png?resize=300%2C66&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Check-MediaPipe-Gesture-recognition-example-script.png?resize=768%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 835px) 100vw, 835px\" \/><\/figure><\/div>\n\n\n<p>Finally, enter the command to install any missing requirements:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sh setup.sh<\/code><\/pre>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Complete project details at https:\/\/RandomNerdTutorials.com\/install-mediapipe-raspberry-pi\/\n\n# Copyright 2023 The MediaPipe Authors. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the &quot;License&quot;); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n# http:\/\/www.apache.org\/licenses\/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\n# Main scripts to run gesture recognition.\n\nimport argparse\nimport sys\nimport time\n\nimport cv2\nimport mediapipe as mp\n\nfrom mediapipe.tasks import python\nfrom mediapipe.tasks.python import vision\nfrom mediapipe.framework.formats import landmark_pb2\nmp_hands = mp.solutions.hands\nmp_drawing = mp.solutions.drawing_utils\nmp_drawing_styles = mp.solutions.drawing_styles\n\n\n# Global variables to calculate FPS\nCOUNTER, FPS = 0, 0\nSTART_TIME = time.time()\n\n\ndef run(model: str, num_hands: int,\n        min_hand_detection_confidence: float,\n        min_hand_presence_confidence: float, min_tracking_confidence: float,\n        camera_id: int, width: int, height: int) -&gt; None:\n  &quot;&quot;&quot;Continuously run inference on images acquired from the camera.\n\n  Args:\n      model: Name of the gesture recognition model bundle.\n      num_hands: Max number of hands can be detected by the recognizer.\n      min_hand_detection_confidence: The minimum confidence score for hand\n        detection to be considered successful.\n      min_hand_presence_confidence: The minimum confidence score of hand\n        presence score in the hand landmark detection.\n      min_tracking_confidence: The minimum confidence score for the hand\n        tracking to be considered successful.\n      camera_id: The camera id to be passed to OpenCV.\n      width: The width of the frame captured from the camera.\n      height: The height of the frame captured from the camera.\n  &quot;&quot;&quot;\n\n  # Start capturing video input from the camera\n  cap = cv2.VideoCapture(camera_id)\n  cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)\n  cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)\n\n  # Visualization parameters\n  row_size = 50  # pixels\n  left_margin = 24  # pixels\n  text_color = (0, 0, 0)  # black\n  font_size = 1\n  font_thickness = 1\n  fps_avg_frame_count = 10\n\n  # Label box parameters\n  label_text_color = (255, 255, 255)  # white\n  label_font_size = 1\n  label_thickness = 2\n\n  recognition_frame = None\n  recognition_result_list = []\n\n  def save_result(result: vision.GestureRecognizerResult,\n                  unused_output_image: mp.Image, timestamp_ms: int):\n      global FPS, COUNTER, START_TIME\n\n      # Calculate the FPS\n      if COUNTER % fps_avg_frame_count == 0:\n          FPS = fps_avg_frame_count \/ (time.time() - START_TIME)\n          START_TIME = time.time()\n\n      recognition_result_list.append(result)\n      COUNTER += 1\n\n  # Initialize the gesture recognizer model\n  base_options = python.BaseOptions(model_asset_path=model)\n  options = vision.GestureRecognizerOptions(base_options=base_options,\n                                          running_mode=vision.RunningMode.LIVE_STREAM,\n                                          num_hands=num_hands,\n                                          min_hand_detection_confidence=min_hand_detection_confidence,\n                                          min_hand_presence_confidence=min_hand_presence_confidence,\n                                          min_tracking_confidence=min_tracking_confidence,\n                                          result_callback=save_result)\n  recognizer = vision.GestureRecognizer.create_from_options(options)\n\n  # Continuously capture images from the camera and run inference\n  while cap.isOpened():\n    success, image = cap.read()\n    if not success:\n      sys.exit(\n          'ERROR: Unable to read from webcam. Please verify your webcam settings.'\n      )\n\n    image = cv2.flip(image, 1)\n\n    # Convert the image from BGR to RGB as required by the TFLite model.\n    rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=rgb_image)\n\n    # Run gesture recognizer using the model.\n    recognizer.recognize_async(mp_image, time.time_ns() \/\/ 1_000_000)\n\n    # Show the FPS\n    fps_text = 'FPS = {:.1f}'.format(FPS)\n    text_location = (left_margin, row_size)\n    current_frame = image\n    cv2.putText(current_frame, fps_text, text_location, cv2.FONT_HERSHEY_DUPLEX,\n                font_size, text_color, font_thickness, cv2.LINE_AA)\n\n    if recognition_result_list:\n      # Draw landmarks and write the text for each hand.\n      for hand_index, hand_landmarks in enumerate(\n          recognition_result_list[0].hand_landmarks):\n        # Calculate the bounding box of the hand\n        x_min = min([landmark.x for landmark in hand_landmarks])\n        y_min = min([landmark.y for landmark in hand_landmarks])\n        y_max = max([landmark.y for landmark in hand_landmarks])\n\n        # Convert normalized coordinates to pixel values\n        frame_height, frame_width = current_frame.shape[:2]\n        x_min_px = int(x_min * frame_width)\n        y_min_px = int(y_min * frame_height)\n        y_max_px = int(y_max * frame_height)\n\n        # Get gesture classification results\n        if recognition_result_list[0].gestures:\n          gesture = recognition_result_list[0].gestures[hand_index]\n          category_name = gesture[0].category_name\n          score = round(gesture[0].score, 2)\n          result_text = f'{category_name} ({score})'\n\n          # Compute text size\n          text_size = \\\n          cv2.getTextSize(result_text, cv2.FONT_HERSHEY_DUPLEX, label_font_size,\n                          label_thickness)[0]\n          text_width, text_height = text_size\n\n          # Calculate text position (above the hand)\n          text_x = x_min_px\n          text_y = y_min_px - 10  # Adjust this value as needed\n\n          # Make sure the text is within the frame boundaries\n          if text_y &lt; 0:\n            text_y = y_max_px + text_height\n\n          # Draw the text\n          cv2.putText(current_frame, result_text, (text_x, text_y),\n                      cv2.FONT_HERSHEY_DUPLEX, label_font_size,\n                      label_text_color, label_thickness, cv2.LINE_AA)\n\n        # Draw hand landmarks on the frame\n        hand_landmarks_proto = landmark_pb2.NormalizedLandmarkList()\n        hand_landmarks_proto.landmark.extend([\n          landmark_pb2.NormalizedLandmark(x=landmark.x, y=landmark.y,\n                                          z=landmark.z) for landmark in\n          hand_landmarks\n        ])\n        mp_drawing.draw_landmarks(\n          current_frame,\n          hand_landmarks_proto,\n          mp_hands.HAND_CONNECTIONS,\n          mp_drawing_styles.get_default_hand_landmarks_style(),\n          mp_drawing_styles.get_default_hand_connections_style())\n\n      recognition_frame = current_frame\n      recognition_result_list.clear()\n\n    if recognition_frame is not None:\n        cv2.imshow('gesture_recognition', recognition_frame)\n\n    # Stop the program if the ESC key is pressed.\n    if cv2.waitKey(1) == 27:\n        break\n\n  recognizer.close()\n  cap.release()\n  cv2.destroyAllWindows()\n\n\ndef main():\n  parser = argparse.ArgumentParser(\n      formatter_class=argparse.ArgumentDefaultsHelpFormatter)\n  parser.add_argument(\n      '--model',\n      help='Name of gesture recognition model.',\n      required=False,\n      default='gesture_recognizer.task')\n  parser.add_argument(\n      '--numHands',\n      help='Max number of hands that can be detected by the recognizer.',\n      required=False,\n      default=1)\n  parser.add_argument(\n      '--minHandDetectionConfidence',\n      help='The minimum confidence score for hand detection to be considered '\n           'successful.',\n      required=False,\n      default=0.5)\n  parser.add_argument(\n      '--minHandPresenceConfidence',\n      help='The minimum confidence score of hand presence score in the hand '\n           'landmark detection.',\n      required=False,\n      default=0.5)\n  parser.add_argument(\n      '--minTrackingConfidence',\n      help='The minimum confidence score for the hand tracking to be '\n           'considered successful.',\n      required=False,\n      default=0.5)\n  # Finding the camera ID can be very reliant on platform-dependent methods.\n  # One common approach is to use the fact that camera IDs are usually indexed sequentially by the OS, starting from 0.\n  # Here, we use OpenCV and create a VideoCapture object for each potential ID with 'cap = cv2.VideoCapture(i)'.\n  # If 'cap' is None or not 'cap.isOpened()', it indicates the camera ID is not available.\n  parser.add_argument(\n      '--cameraId', help='Id of camera.', required=False, default=0)\n  parser.add_argument(\n      '--frameWidth',\n      help='Width of frame to capture from camera.',\n      required=False,\n      default=640)\n  parser.add_argument(\n      '--frameHeight',\n      help='Height of frame to capture from camera.',\n      required=False,\n      default=480)\n  args = parser.parse_args()\n\n  run(args.model, int(args.numHands), args.minHandDetectionConfidence,\n      args.minHandPresenceConfidence, args.minTrackingConfidence,\n      int(args.cameraId), args.frameWidth, args.frameHeight)\n\n\nif __name__ == '__main__':\n  main()\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/mediapipe\/raw\/main\/raspberry_pi_gesture_recognizer\/recognize.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Demonstration Gesture Recognition<\/h3>\n\n\n\n<p>Having your Virtual Environment activated, run the next command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>python recognize.py --cameraId 0 --model gesture_recognizer.task --numHands 2<\/code><\/pre>\n\n\n\n<p>You must enter the correct camera id number for your USB camera, in my case, it&#8217;s 0, but you might need to change it. You can find more information about the supported parameters in the <a href=\"https:\/\/github.com\/RuiSantosdotme\/mediapipe\/tree\/main\/raspberry_pi_gesture_recognizer#run-the-example\" target=\"_blank\" rel=\"noopener\" title=\"\">documentation<\/a>.<\/p>\n\n\n\n<p>With the example running, make different gestures in front of the camera. It will detect and identify the gestures (from the list of gestures we&#8217;ve seen previously). It can detect gestures in one hand or two hands simultaneously.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-2 is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-two-hands.jpg?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"647\" height=\"575\" data-id=\"148793\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-two-hands.jpg?resize=647%2C575&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Testing Mediapipe Two Hands\" class=\"wp-image-148793\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-two-hands.jpg?w=647&amp;quality=100&amp;strip=all&amp;ssl=1 647w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-two-hands.jpg?resize=300%2C267&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 647px) 100vw, 647px\" \/><\/a><figcaption class=\"wp-element-caption\">Testing Mediapipe Two Hands<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-open-palm.jpg?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"646\" height=\"574\" data-id=\"148788\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-open-palm.jpg?resize=646%2C574&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Testing Mediapipe Open Hands Gesture\" class=\"wp-image-148788\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-open-palm.jpg?w=646&amp;quality=100&amp;strip=all&amp;ssl=1 646w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-open-palm.jpg?resize=300%2C267&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 646px) 100vw, 646px\" \/><\/a><figcaption class=\"wp-element-caption\">Testing Mediapipe Open Hands Gesture<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-i-love-you.jpg?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"647\" height=\"575\" data-id=\"148789\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-i-love-you.jpg?resize=647%2C575&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Testing Mediapipe I Love You Gesture\" class=\"wp-image-148789\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-i-love-you.jpg?w=647&amp;quality=100&amp;strip=all&amp;ssl=1 647w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-i-love-you.jpg?resize=300%2C267&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 647px) 100vw, 647px\" \/><\/a><figcaption class=\"wp-element-caption\">Testing Mediapipe I Love You Gesture<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-thumbs-up.jpg?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"647\" height=\"575\" data-id=\"148790\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-thumbs-up.jpg?resize=647%2C575&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Testing Mediapipe Thumb Up Gesture\" class=\"wp-image-148790\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-thumbs-up.jpg?w=647&amp;quality=100&amp;strip=all&amp;ssl=1 647w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-thumbs-up.jpg?resize=300%2C267&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 647px) 100vw, 647px\" \/><\/a><figcaption class=\"wp-element-caption\">Testing Mediapipe Thumb Up Gesture<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-thumbs-down.jpg?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"646\" height=\"575\" data-id=\"148791\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-thumbs-down.jpg?resize=646%2C575&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Testing Mediapipe Thumb Down Gesture\" class=\"wp-image-148791\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-thumbs-down.jpg?w=646&amp;quality=100&amp;strip=all&amp;ssl=1 646w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-thumbs-down.jpg?resize=300%2C267&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 646px) 100vw, 646px\" \/><\/a><figcaption class=\"wp-element-caption\">Testing Mediapipe Thumb Down Gesture<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-victory.jpg?quality=100&#038;strip=all&#038;ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"646\" height=\"575\" data-id=\"148792\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-victory.jpg?resize=646%2C575&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Testing Mediapipe Victory Gesture\" class=\"wp-image-148792\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-victory.jpg?w=646&amp;quality=100&amp;strip=all&amp;ssl=1 646w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/testing-mediapipe-victory.jpg?resize=300%2C267&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 646px) 100vw, 646px\" \/><\/a><figcaption class=\"wp-element-caption\">Testing Mediapipe Victory Gesture<\/figcaption><\/figure>\n<\/figure>\n\n\n\n<p>You can also watch the following video demonstration:<\/p>\n\n\n<div style=\"text-align:center\"><iframe src=\"https:\/\/player.vimeo.com\/video\/928407316?color=ff9933&title=1&byline=0&portrait=0\" width=\"720\" height=\"405\" frameborder=\"0\" webkitallowfullscreen mozallowfullscreen allowfullscreen><\/iframe><\/div><\/br>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>This tutorial was a quick getting-started guide to MediaPipe with the Raspberry Pi. MediaPipe is an easy-to-use framework that allows you to build machine-learning projects. <\/p>\n\n\n\n<p>In this guide, we tested the hand gesture recognition example. MediaPipe also has other interesting examples like counting the number of raised fingers on your hand. This can be especially useful in automation projects because it allows you to control something with gestures. For example, turn a specific Raspberry Pi GPIO on when you have one finger raised and turn it off when you have two raised fingers. The possibilities are endless.<\/p>\n\n\n\n<p>We hope you&#8217;ve found this tutorial interesting.<\/p>\n\n\n\n<p>If there&#8217;s enough interest from our readers in this kind of subject, we intend to create more machine-learning projects using MediaPipe.<\/p>\n\n\n\n<p>If you would like to learn more about the Raspberry Pi, check out our tutorials:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-raspberry-pi\/\" title=\"\">All our Raspberry Pi Tutorials and Guides<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This guide is an introduction to the MediaPipe Python library on a Raspberry Pi board. It covers installing MediaPipe using pip on a virtual environment and running a gesture recognition &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Install MediaPipe on a Raspberry Pi &#8211; Example Gesture Recognition\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/install-mediapipe-raspberry-pi\/#more-147062\" aria-label=\"Read more about Install MediaPipe on a Raspberry Pi &#8211; Example Gesture Recognition\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":1,"featured_media":148804,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[301,264,190,268],"tags":[],"class_list":["post-147062","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-0-raspberrypi","category-project","category-raspberry-pi","category-raspberry-pi-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/Raspberry-Pi-Getting-Started-Media-Pipe.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/147062","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=147062"}],"version-history":[{"count":14,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/147062\/revisions"}],"predecessor-version":[{"id":151324,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/147062\/revisions\/151324"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/148804"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=147062"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=147062"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=147062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}