├── README.md ├── handtracking.py └── handtracking_mouse.py /README.md: -------------------------------------------------------------------------------- 1 | # HandTracking 2 | Holomat tutorial part 1 3 | 4 | # Hand Tracking Module 5 | 6 | ## Description 7 | This Python script utilizes MediaPipe and OpenCV to track hand movements in real-time using a webcam. It visualizes hand landmarks and their connections on the video feed, serving as a foundation for more complex applications such as gesture recognition or augmented reality interfaces. 8 | 9 | ## Installation 10 | Ensure Python and the necessary libraries are installed: 11 | ``` 12 | pip install opencv-python mediapipe numpy 13 | ``` 14 | ## Usage 15 | ``` 16 | python handtracking.py 17 | ``` 18 | 19 | ## Safety Note 20 | This script moves your mouse pointer and can simulate clicks. Ensure you have an alternate control method available. 21 | 22 | ## Requirements 23 | Python 3.6 or later 24 | OpenCV 4.0 or later 25 | MediaPipe 26 | NumPy 27 | PyAutoGUI 28 | Contributing 29 | Fork the repository and contribute by submitting a pull request. 30 | 31 | ## License 32 | Distributed under the MIT License. See LICENSE for more information. 33 | 34 | ## Contact 35 | Reach out with any feedback or support needs via GitHub or email. 36 | -------------------------------------------------------------------------------- /handtracking.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import mediapipe as mp 3 | 4 | 5 | # Initialize Mediapipe Hand solution 6 | mp_hands = mp.solutions.hands 7 | 8 | hands = mp_hands.Hands(static_image_mode=False, 9 | max_num_hands=2, 10 | min_detection_confidence=0.1, 11 | min_tracking_confidence=0.1) 12 | 13 | mp_drawing = mp.solutions.drawing_utils 14 | 15 | #open the camera 16 | cap = cv2.VideoCapture(1) 17 | 18 | 19 | # error check to make sure the camera is open 20 | if not cap.isOpened(): 21 | print("Error") 22 | exit() 23 | 24 | 25 | #Main loop 26 | while True: 27 | 28 | #capture frame by frame from the camera 29 | success, frame = cap.read() 30 | if not success: 31 | break 32 | 33 | # Flip the frame horizontally 34 | frame = cv2.flip(frame, 1) 35 | 36 | # Convert the frame color from BGR to RGB 37 | rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 38 | 39 | # Process the RGB frame with MediaPipe Hands 40 | results = hands.process(rgb_frame) 41 | 42 | if results.multi_hand_landmarks: 43 | for hand_landmarks in results.multi_hand_landmarks: 44 | # Draw landmarks 45 | mp_drawing.draw_landmarks(frame, hand_landmarks,mp_hands.HAND_CONNECTIONS) 46 | 47 | 48 | # Draw the hand annotations on the frame. 49 | if results.multi_hand_landmarks: 50 | for hand_landmarks in results.multi_hand_landmarks: 51 | #Draw landmarks 52 | mp_drawing.draw_landmarks(frame, hand_landmarks, mp_hands.HAND_CONNECTIONS) 53 | 54 | # Display the resulting frame 55 | cv2.imshow("Frame", frame) 56 | cv2.waitKey(1) 57 | 58 | 59 | cap.release() 60 | cv2.destroyAllWindows() 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /handtracking_mouse.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import mediapipe as mp 3 | import pyautogui as pag 4 | import numpy as np 5 | 6 | 7 | 8 | 9 | # Initialize Mediapipe Hand solution 10 | mp_hands = mp.solutions.hands 11 | 12 | hands = mp_hands.Hands(static_image_mode=False, 13 | max_num_hands=2, 14 | min_detection_confidence=0.1, 15 | min_tracking_confidence=0.1) 16 | 17 | mp_drawing = mp.solutions.drawing_utils 18 | 19 | #open the camera 20 | cap = cv2.VideoCapture(1) 21 | 22 | 23 | # error check to make sure the camera is open 24 | if not cap.isOpened(): 25 | print("Error") 26 | exit() 27 | 28 | 29 | # Set the screen resolution (width, height) 30 | screen_width, screen_height = pag.size() 31 | 32 | mouseDown = False 33 | 34 | #Main loop 35 | while True: 36 | 37 | #capture frame by frame from the camera 38 | success, frame = cap.read() 39 | if not success: 40 | break 41 | 42 | # Flip the frame horizontally 43 | frame = cv2.flip(frame, 1) 44 | 45 | # Convert the frame color from BGR to RGB 46 | rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 47 | 48 | # Process the RGB frame with MediaPipe Hands 49 | results = hands.process(rgb_frame) 50 | 51 | #frame resoulution 52 | frame_height, frame_width, _ = frame.shape 53 | 54 | if results.multi_hand_landmarks: 55 | for hand_landmarks in results.multi_hand_landmarks: 56 | # Draw landmarks 57 | mp_drawing.draw_landmarks(frame, hand_landmarks,mp_hands.HAND_CONNECTIONS) 58 | 59 | index_finger_tip = hand_landmarks.landmark[mp_hands.HandLandmark.INDEX_FINGER_TIP] 60 | thumb_tip = hand_landmarks.landmark[mp_hands.HandLandmark.THUMB_TIP] 61 | 62 | #get the midpoint between the thumb and index finger 63 | midpoint_x = (index_finger_tip.x + thumb_tip.x) /2 64 | midpoint_y = (index_finger_tip.y + thumb_tip.y) /2 65 | 66 | # Get the distance between the thumb and index finger 67 | distance = np.sqrt((index_finger_tip.x - thumb_tip.x)**2 + (index_finger_tip.y - thumb_tip.y)**2) 68 | 69 | if distance < 0.1 and mouseDown == False: 70 | #mouse down 71 | pag.mouseDown() 72 | mouseDown = True 73 | if distance > 0.3 and mouseDown == True: 74 | #mouse up 75 | pag.mouseUp() 76 | mouseDown = False 77 | 78 | if mouseDown: 79 | #draw a circle at the midpoint with radius 10 80 | cv2.circle(frame, (int(midpoint_x*frame_width), int(midpoint_y * frame_height)), 10, (0, 255,0), -1) 81 | 82 | else: 83 | #draw a circle at the midpoint with radius 10 84 | cv2.circle(frame, (int(midpoint_x*frame_width), int(midpoint_y * frame_height)), 10, (0, 255,0), 1) 85 | 86 | 87 | # Map the position to the screen resolution 88 | x_mapped = np.interp(midpoint_x, (0,1), (0, screen_width)) 89 | y_mapped = np.interp(midpoint_y, (0,1), (0, screen_height)) 90 | 91 | # Set the mouse position 92 | pag.moveTo(x_mapped, y_mapped, duration= 0.1) 93 | 94 | # Display the resulting frame 95 | cv2.imshow("Medipipe Hands", frame) 96 | cv2.waitKey(1) 97 | 98 | # When everything done, release the capture 99 | cap.release() 100 | cv2.destroyAllWindows() 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | --------------------------------------------------------------------------------