Week 07 ‐ Add Gesture Control and Virtual Camera Features - AkinduID/EyeRiz GitHub Wiki
Goals
- Replace cascade classifier method with MediaPipe Holistics.
- Add gesture control to lock and unlock faces
- Use virtual camera feature to send the video feed to other software
Hardware Components
- 720p Webcam
- Arduino Uno R3
- SG90 Servo Motor x2
- Servo pan and tilt bracket
Libraries and Models
- OpenCV
- MediaPipe Holistics
- MediaPipe Hand Detection Model
- pyvirtualcamera
Gesture Control
The MediaPipe library offers built-in functionality for hand gesture recognition, making it advantageous as it supports both face and hand gesture detection within a single library. Leveraging this feature, I implemented the ability to lock the face in the frame by detecting a closed palm (fist) gesture and to release the lock with an open palm gesture.
import mediapipe
# ................................................................................................................
# ................................................................................................................
mp_hands = mp.solutions.hands # Initialize MediaPipe Hands model
hand_detector = mp_hands.Hands(min_detection_confidence=0.5, min_tracking_confidence=0.5)
# ................................................................................................................
# ................................................................................................................
def detect_hand_gesture(hand_landmarks):
"""Detects if the hand is showing an open palm (lock) or fist (unlock)."""
if hand_landmarks:
thumb_tip = hand_landmarks.landmark[mp_hands.HandLandmark.THUMB_TIP].y
index_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP].y
middle_tip = hand_landmarks.landmark[mp_hands.HandLandmark.MIDDLE_FINGER_TIP].y
ring_tip = hand_landmarks.landmark[mp_hands.HandLandmark.RING_FINGER_TIP].y
pinky_tip = hand_landmarks.landmark[mp_hands.HandLandmark.PINKY_TIP].y
# Open palm gesture (lock)
if thumb_tip < index_tip and thumb_tip < middle_tip and thumb_tip < ring_tip and thumb_tip < pinky_tip:
return "lock"
# Closed fist gesture (unlock)
elif index_tip < thumb_tip and middle_tip < thumb_tip and ring_tip < thumb_tip and pinky_tip < thumb_tip:
return "unlock"
return None
# ................................................................................................................
# ................................................................................................................
def process_video():
# ................................................................................................................
# ................................................................................................................
hand_results = hand_detector.process(image_rgb)
# ................................................................................................................
# ................................................................................................................
if face_locked:
track_face(face_center_x, face_center_y)
# ................................................................................................................
# ................................................................................................................
if hand_results.multi_hand_landmarks:
for hand_landmarks in hand_results.multi_hand_landmarks:
mp_drawings.draw_landmarks(image_bgr, hand_landmarks, mp_hands.HAND_CONNECTIONS)
gesture = detect_hand_gesture(hand_landmarks)
if gesture == "lock":
face_locked = True
elif gesture == "unlock":
face_locked = False
# ................................................................................................................
# ................................................................................................................
process_video()
Virtual Camera
The pyvirtualcam library is used to create a virtual camera, to which frames captured by the Python script are sent. This setup requires a virtual camera driver; currently, the driver provided by OBS Studio is being utilized.
import cv2
import pyvirtualcam
import numpy as np
cap = cv2.VideoCapture(0)
cam = pyvirtualcam.Camera(width=int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), height=int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)), fps=30)
while True:
ret, frame = cap.read()
if not ret:
break
# Convert BGR to RGB
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Send the frame to the virtual camera
cam.send(frame_rgb)
cam.sleep_until_next_frame()
# Show the original frame for debugging (if needed)
cv2.imshow('Original Frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Conclusions
- MediaPipe improved the accuracy of face and hand gesture detection, enhancing application interaction.
- The pyvirtualcam library enabled real-time video broadcasting to other applications, facilitating effective face tracking.
Next Steps
- Improve servo movements further
- Improve gestures
- Implement a simple GUI