87 lines
3.8 KiB
Python
87 lines
3.8 KiB
Python
# code inspiration from https://www.geekering.com/categories/computer-vision/marcellacavalcanti/hand-tracking-and-finger-counting-in-python-with-mediapipe/ because i dont know how to use mediapipe
|
|
|
|
import cv2
|
|
import mediapipe as mp
|
|
import time
|
|
|
|
mp_drawing = mp.solutions.drawing_utils
|
|
mp_drawing_styles = mp.solutions.drawing_styles
|
|
mp_hands = mp.solutions.hands
|
|
|
|
def count_fingers(stable_duration=2):
|
|
previous_finger_count = -1 # Initialize to an invalid count
|
|
stable_start_time = None # To track when the count became stable
|
|
cap = cv2.VideoCapture(0)
|
|
with mp_hands.Hands(
|
|
model_complexity=0,
|
|
min_detection_confidence=0.5,
|
|
min_tracking_confidence=0.5) as hands:
|
|
|
|
while cap.isOpened():
|
|
success, image = cap.read()
|
|
if not success:
|
|
print("Ignoring empty camera frame.")
|
|
continue
|
|
|
|
image.flags.writeable = False
|
|
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
|
results = hands.process(image)
|
|
|
|
image.flags.writeable = True
|
|
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
|
|
|
|
fingerCount = 0 # Reset fingerCount for each frame
|
|
|
|
if results.multi_hand_landmarks:
|
|
for hand_landmarks in results.multi_hand_landmarks:
|
|
handIndex = results.multi_hand_landmarks.index(hand_landmarks)
|
|
handLabel = results.multi_handedness[handIndex].classification[0].label
|
|
|
|
handLandmarks = []
|
|
for landmarks in hand_landmarks.landmark:
|
|
handLandmarks.append([landmarks.x, landmarks.y])
|
|
|
|
# Count fingers
|
|
if handLabel == "Left" and handLandmarks[4][0] > handLandmarks[3][0]:
|
|
fingerCount += 1
|
|
elif handLabel == "Right" and handLandmarks[4][0] < handLandmarks[3][0]:
|
|
fingerCount += 1
|
|
|
|
if handLandmarks[8][1] < handLandmarks[6][1]: # Index finger
|
|
fingerCount += 1
|
|
if handLandmarks[12][1] < handLandmarks[10][1]: # Middle finger
|
|
fingerCount += 1
|
|
if handLandmarks[16][1] < handLandmarks[14][1]: # Ring finger
|
|
fingerCount += 1
|
|
if handLandmarks[20][1] < handLandmarks[18][1]: # Pinky
|
|
fingerCount += 1
|
|
|
|
# Draw hand landmarks
|
|
mp_drawing.draw_landmarks(
|
|
image,
|
|
hand_landmarks,
|
|
mp_hands.HAND_CONNECTIONS,
|
|
mp_drawing_styles.get_default_hand_landmarks_style(),
|
|
mp_drawing_styles.get_default_hand_connections_style())
|
|
|
|
# Display finger count
|
|
cv2.putText(image, str(fingerCount), (50, 450), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 0, 0), 10)
|
|
#Display image
|
|
cv2.imshow('Finger Count', image)
|
|
|
|
# Check if the finger count is stable
|
|
if fingerCount == previous_finger_count and fingerCount != 0:
|
|
if stable_start_time is None:
|
|
stable_start_time = time.time() # Start the timer
|
|
elif time.time() - stable_start_time >= stable_duration and fingerCount != 0:
|
|
cap.release()
|
|
cv2.destroyAllWindows()
|
|
return fingerCount # Return the stable finger count
|
|
else:
|
|
stable_start_time = None # Reset the timer if the count changes
|
|
|
|
previous_finger_count = fingerCount # Update the previous count
|
|
if cv2.waitKey(5) & 0xFF == 27:
|
|
break
|
|
|
|
return None # Return None if the loop ends without a stable count
|