Create a Finger Counter Using Python, OpenCV & Mediapipe

Screenshot of a code editor with a hand showing four fingers, the number 4 displayed at the top corner, and the text 'Finger Counter using Python and OpenCV.'

Introduction

In this tutorial, weā€™ll guide you through creating a simple yet powerful finger counter using Python, OpenCV, and Mediapipe. This project detects the number of fingers you raise in front of your webcam, making use of hand detection technology.

The key libraries in this project are:

  • OpenCV: A popular computer vision library for image and video processing.
  • Mediapipe: Developed by Google, this library provides hand-tracking capabilities in real-time.

Our main goal in this project is to count the number of fingers raised and display the count on the video feed. This project will help you understand how to integrate hand detection and finger counting using Python.

Letā€™s dive in and see how to set up this exciting project!

Requirements and Installation

Before we jump into coding, make sure you have the necessary libraries installed. Youā€™ll need:

  • Python (version 3.6 or above)
  • OpenCV: This is for video capturing and image processing.
  • Mediapipe: For detecting and tracking the hand.
pip install opencv-python
pip install mediapipe

These commands will install the required dependencies. Now youā€™re ready to start coding!

The Source Code

Letā€™s break down the code into small parts, making it easier to follow for beginners.

Importing the Libraries

import cv2
import mediapipe as mp

Here, we import OpenCV (cv2) for video capturing and Mediapipe for hand detection.

Setting Up Hand Detection

mp_hands = mp.solutions.hands
hands = mp_hands.Hands(static_image_mode=False, max_num_hands=2, min_detection_confidence=0.5, min_tracking_confidence=0.5)
mp_draw = mp.solutions.drawing_utils

In this part, we initialize the Mediapipe hand detector and configure its parameters. The Hands function helps us detect and track hands.

Finding Hands in Each Video Frame

def find_hands(img, draw=True):
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    results = hands.process(img_rgb)
    if results.multi_hand_landmarks:
        for hand_landmarks in results.multi_hand_landmarks:
            if draw:
                mp_draw.draw_landmarks(img, hand_landmarks, mp_hands.HAND_CONNECTIONS)
    return img, results

This function converts each frame to RGB, detects hands, and draws landmarks on them. It returns the frame with the detected hands.

Getting the Position of Fingers

def find_position(img, results, hand_no=0, draw=True):
    lm_list = []
    if results.multi_hand_landmarks:
        my_hand = results.multi_hand_landmarks[hand_no]
        for id, lm in enumerate(my_hand.landmark):
            h, w, c = img.shape
            cx, cy = int(lm.x * w), int(lm.y * h)
            lm_list.append([id, cx, cy])
            if draw:
                cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)
    return lm_list

This function returns the landmark positions of fingers. It tracks the location of specific points on the hand that will be used for counting fingers.

Counting Fingers

This is where the finger counting happens. We compare the positions of specific landmarks to determine whether each finger is up or down. The total count is displayed on the video feed.

    # Define the tip landmarks for each finger (thumb, index, middle, ring, pinky)
    finger_tips = [4, 8, 12, 16, 20]

    # Main loop to capture video frames and detect fingers
    while True:
        success, frame = video_capture.read()

        # Detect hands in the frame and get landmark positions
        frame, results = find_hands(frame)
        landmarks = find_position(frame, results, draw=False)

        if len(landmarks) != 0:
            fingers_status = []

            # Detect thumb: compare x-coordinates for open/closed status
            if landmarks[finger_tips[0]][1] > landmarks[finger_tips[0] - 1][1]:
                fingers_status.append(1)
            else:
                fingers_status.append(0)

            # Detect the rest of the fingers: compare y-coordinates for open/closed status
            for finger in range(1, 5):
                if landmarks[finger_tips[finger]][2] < landmarks[finger_tips[finger] - 2][2]:
                    fingers_status.append(1)
                else:
                    fingers_status.append(0)

            # Count the number of fingers that are up
            total_fingers_up = fingers_status.count(1)

            # Display the result on the video frame
            cv2.rectangle(frame, (10, 10), (100, 70), (0, 0, 255), cv2.FILLED)
            cv2.putText(frame, str(total_fingers_up), (34, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 4)

Running the Program

video_capture = cv2.VideoCapture(0)

while True:
    success, frame = video_capture.read()
    frame, results = find_hands(frame)
    landmarks = find_position(frame, results, draw=False)
    # (Finger counting logic here)
    
    # Show the video frame
    cv2.imshow("Finger Counter", frame)
    
    # Exit if 'q' is pressed
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

video_capture.release()
cv2.destroyAllWindows()

Finally, we capture video from the webcam, detect the hand, count fingers, and display the results live. The program runs in a loop and can be terminated by pressing ā€˜qā€™.

The Output

Screenshot of a code editor with a hand showing no fingers, the number 0 displayed at the top corner
Screenshot of a code editor with a hand showing two fingers, the number 2 displayed at the top corner
Screenshot of a code editor with a hand showing four fingers, the number 4 displayed at the top corner
Screenshot of a code editor with a hand showing three fingers, the number 3 displayed at the top corner

Summary

In this project, we created a finger counter using Python, OpenCV, and Mediapipe, a practical example of combining computer vision and machine learning to track and count fingers in real-time.

We started by setting up the environment, installing the necessary libraries, and understanding the code step by step. We used OpenCV for capturing video and displaying results, and Mediapipe for detecting hand landmarks.

For any query related to this project, reach out to me at contact@pyseek.com.

If interested, explore more fascinating Python projects here. Below are a few examples to spark your interest:

Happy Counting!

Share your love
Subhankar Rakshit
Subhankar Rakshit

Hey there! Iā€™m Subhankar Rakshit, the brains behind PySeek. Iā€™m a Post Graduate in Computer Science. PySeek is where I channel my love for Python programming and share it with the world through engaging and informative blogs.

Articles:Ā 194