import cv2
import mediapipe as mp
import serial
import time
# Set up the serial communication with Arduino
myPort = serial.Serial('COM3', 9600) # Replace 'COM3' with your Arduino's port
time.sleep(2) # Wait for 2 seconds for the communication to establish
# Initialize MediaPipe Hands
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(max_num_hands=1)
mp_drawing = mp.solutions.drawing_utils
# Set up the webcam
cap = cv2.VideoCapture(0)
def count_fingers(hand_landmarks):
landmarks = hand_landmarks.landmark
finger_count = 0
# Thumb
if landmarks[mp_hands.HandLandmark.THUMB_TIP].x > landmarks[mp_hands.HandLandmark.THUMB_IP].x: # Check horizontal position for thumb
finger_count += 1
# Index finger
if landmarks[mp_hands.HandLandmark.INDEX_FINGER_TIP].y < landmarks[mp_hands.HandLandmark.INDEX_FINGER_PIP].y:
finger_count += 1
# Middle finger
if landmarks[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].y < landmarks[mp_hands.HandLandmark.MIDDLE_FINGER_PIP].y:
finger_count += 1
# Ring finger
if landmarks[mp_hands.HandLandmark.RING_FINGER_TIP].y < landmarks[mp_hands.HandLandmark.RING_FINGER_PIP].y:
finger_count += 1
# Pinky
if landmarks[mp_hands.HandLandmark.PINKY_TIP].y < landmarks[mp_hands.HandLandmark.PINKY_PIP].y:
finger_count += 1
return finger_count
while True:
success, image = cap.read()
if not success:
break
# Convert the BGR image to RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# Process the image and find hands
results = hands.process(image)
# Convert the image back to BGR for rendering
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
finger_count = 0
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_drawing.draw_landmarks(image, hand_landmarks, mp_hands.HAND_CONNECTIONS)
# Count fingers
finger_count = count_fingers(hand_landmarks)
# Add finger count display on the screen
cv2.putText(image, f'Fingers: {finger_count}', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
# Display the image with the hand landmarks and finger count
cv2.imshow('Hand Detection', image)
# Send the finger count to Arduino
# Ensure we send a valid integer between 0 and 5
finger_count = min(max(finger_count, 0), 5)
myPort.write(str(finger_count).encode())
# Debugging prints
print(f"Fingers detected: {finger_count}")
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Clean up
cap.release()
cv2.destroyAllWindows()
myPort.close()
Arduino Code:
#include <Servo.h>
int ledPins[] = {8, 9, 10, 11, 12};
void setup() {
Serial.begin(9600);
for (int i = 0; i < 5; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
if (Serial.available()) {
int fingerCount = Serial.parseInt();
Serial.print("Received: ");
Serial.println(fingerCount); // Print received count for debugging
for (int i = 0; i < 5; i++) {
if (i < fingerCount) {
digitalWrite(ledPins[i], HIGH);
} else {
digitalWrite(ledPins[i], LOW);
}
}
}
}