CCCPaste

wiggle.py

#!/usr/bin/python3
'''
wiggle.py you wave your face around the camera, to control your mouse. 
this program is intened to be used with "dasher"
https://github.com/dasher-project/
though its interoperation is not integrated yet

Dasher is an on screen typing tool where you use a mouse to navigate 
a sea of letters. where you point the mose determines what you type. 
as sentences form predictive text appears more frequently. 
'''
import cv2
import dlib
import numpy as np
import os
import pyautogui
pyautogui.FAILSAFE=0
# Initialize the dlib facial landmark predictor
predictor_path = "shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(predictor_path)

# Initialize the dlib face detector
detector = dlib.get_frontal_face_detector()

# Start the webcam
cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    if not ret:
        break

    # Convert the frame to grayscale
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Detect faces in the frame
    faces = detector(gray)

    for face in faces:
        # Detect facial landmarks
        landmarks = predictor(gray, face)
        
        # Extract landmarks for the left and right eyes, and the nose tip
        left_eye = np.array([(landmarks.part(i).x, landmarks.part(i).y) for i in range(36, 42)])
        right_eye = np.array([(landmarks.part(i).x, landmarks.part(i).y) for i in range(42, 48)])
        nose_tip = np.array([(landmarks.part(i).x, landmarks.part(i).y) for i in range(30, 31)])
        
        # Calculate the average position of the eyes and nose tip
        avg_eye_pos = np.mean(np.concatenate((left_eye, right_eye)), axis=0)
        avg_nose_pos = np.mean(nose_tip, axis=0)
       
        # Calculate the direction of gaze
        #gaze_direction = avg_eye_pos - avg_nose_pos
        gaze_direction = avg_nose_pos - avg_eye_pos

        # Scale the gaze direction to control the mouse movement
        mouse_move_x = int(gaze_direction[0] * 5)
       # mouse_move_x = int(nose_tip[0])
        mouse_move_y = int(gaze_direction[0] * 5)
       # mouse_move_y = int(nose_tip[1])

        # Move the mouse cursor
        current_x, current_y = pyautogui.position()
        new_x = max(0, min(current_x + mouse_move_x, pyautogui.size().width - 1))
        new_y = max(0, min(current_y + mouse_move_y, pyautogui.size().height - 1))
        pyautogui.moveTo(new_x, new_y)

    cv2.imshow('Gaze Tracking', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()