├── .gitignore ├── README.md ├── main-mobile-cam.py ├── main-pc-cam.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .venv -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hand controller: control cars 🚗 using hands, in Games 2 | 3 | This project uses the Python OpenCV module to detect hand gestures and control a car in GTA 5. By using computer vision techniques, the program captures the movements of the user's hand and translates them into corresponding actions in the game. This allows the user to drive the car, change directions, and perform other actions simply by moving their hand in front of the camera. 4 | 5 | checkout the Instagram reel from here: [link](https://www.instagram.com/reel/C6a2JnWypLX/?utm_source=ig_web_copy_link&igsh=MzRlODBiNWFlZA==) 6 | 7 | ## Installation 8 | 9 | Run the following command: 10 | ```sh 11 | pip install -r requirements.txt 12 | ``` 13 | 14 | ## Usage 15 | 16 | #### Using PC camera: 17 | - Run `main-pc-cam.py` 18 | 19 | #### Using Mobile camera: 20 | - Download IP Webcam App in your mobile and put the IP in the `url` variable in code 21 | - then simply run `main-mobile-cam.py` 22 | 23 | And put your hand in front of the Camera to control the CARRR! 🚗 24 | 25 | ## Contributing 26 | 27 | Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. 28 | 29 | 1. Fork the Project 30 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 31 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 32 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 33 | 5. Open a Pull Request 34 | 35 | ## License 36 | 37 | This project is licensed under the Apache License 2.0. -------------------------------------------------------------------------------- /main-mobile-cam.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import mediapipe as mp 3 | 4 | from pynput.keyboard import Controller 5 | 6 | mp_hands = mp.solutions.hands.Hands() 7 | keyboard = Controller() 8 | 9 | url = 'http:///video' 10 | cp = cv2.VideoCapture(url) 11 | x1, x2, y1, y2 =0, 0, 0, 0 12 | 13 | while(True): 14 | 15 | _, image = cp.read() 16 | 17 | image_height, image_width, image_depth = image.shape 18 | image = cv2.flip(image, 1) 19 | rgb_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 20 | output_hands = mp_hands.process(rgb_img) 21 | all_hands = output_hands.multi_hand_landmarks 22 | 23 | if all_hands: 24 | hand = all_hands[0] 25 | one_hand_landmark = hand.landmark 26 | 27 | for id, lm in enumerate(one_hand_landmark): 28 | x = int(lm.x * image_width) 29 | y = int(lm.y * image_height) 30 | 31 | if id == 12: 32 | x1 = x 33 | y1 = y 34 | 35 | if id == 0: 36 | x2 = x 37 | y2 = y 38 | 39 | distX = 0 40 | distX = x1 - x2 41 | distY = 0 42 | distY =y1 - y2 43 | 44 | if distY > -140 and distY !=0: 45 | # press S 46 | keyboard.release('d') 47 | keyboard.release('a') 48 | keyboard.release('w') 49 | keyboard.press('s') 50 | print("S") 51 | 52 | if distY < -200 and distY != 0: 53 | keyboard.release('s') 54 | keyboard.release('d') 55 | keyboard.release('a') 56 | keyboard.press('w') 57 | print("W") 58 | 59 | if (distX < -100 and distX != 0): 60 | keyboard.release('s') 61 | keyboard.release('d') 62 | keyboard.press('w') 63 | keyboard.press('a') 64 | print('A') 65 | 66 | if (distX > 55 and distX != 0): 67 | keyboard.release('a') 68 | keyboard.release('s') 69 | keyboard.press('w') 70 | keyboard.press('d') 71 | print('D') 72 | 73 | else: 74 | print('none') 75 | keyboard.release('d') 76 | keyboard.release('a') 77 | keyboard.release('w') 78 | keyboard.release('s') 79 | 80 | # if image is not None: 81 | # cv2.imshow("Frame", image) 82 | q = cv2.waitKey(1) 83 | if q==ord("q"): 84 | break 85 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /main-pc-cam.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import mediapipe as mp 3 | 4 | from pynput.keyboard import Controller 5 | 6 | mp_hands = mp.solutions.hands.Hands() 7 | keyboard = Controller() 8 | 9 | cp = cv2.VideoCapture(0) 10 | x1, x2, y1, y2 =0, 0, 0, 0 11 | 12 | while(True): 13 | 14 | _, image = cp.read() 15 | 16 | image_height, image_width, image_depth = image.shape 17 | image = cv2.flip(image, 1) 18 | rgb_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 19 | output_hands = mp_hands.process(rgb_img) 20 | all_hands = output_hands.multi_hand_landmarks 21 | 22 | if all_hands: 23 | hand = all_hands[0] 24 | one_hand_landmark = hand.landmark 25 | 26 | for id, lm in enumerate(one_hand_landmark): 27 | x = int(lm.x * image_width) 28 | y = int(lm.y * image_height) 29 | 30 | if id == 12: 31 | x1 = x 32 | y1 = y 33 | 34 | if id == 0: 35 | x2 = x 36 | y2 = y 37 | 38 | distX = 0 39 | distX = x1 - x2 40 | distY = 0 41 | distY =y1 - y2 42 | 43 | if distY > -140 and distY !=0: 44 | # press S 45 | keyboard.release('d') 46 | keyboard.release('a') 47 | keyboard.release('w') 48 | keyboard.press('s') 49 | print("S") 50 | 51 | if distY < -200 and distY != 0: 52 | keyboard.release('s') 53 | keyboard.release('d') 54 | keyboard.release('a') 55 | keyboard.press('w') 56 | print("W") 57 | 58 | if (distX < -100 and distX != 0): 59 | keyboard.release('s') 60 | keyboard.release('d') 61 | keyboard.press('w') 62 | keyboard.press('a') 63 | print('A') 64 | 65 | if (distX > 55 and distX != 0): 66 | keyboard.release('a') 67 | keyboard.release('s') 68 | keyboard.press('w') 69 | keyboard.press('d') 70 | print('D') 71 | 72 | else: 73 | print('none') 74 | keyboard.release('d') 75 | keyboard.release('a') 76 | keyboard.release('w') 77 | keyboard.release('s') 78 | 79 | # if image is not None: 80 | # cv2.imshow("Frame", image) 81 | q = cv2.waitKey(1) 82 | if q==ord("q"): 83 | break 84 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | absl-py==2.1.0 2 | attrs==23.2.0 3 | cffi==1.16.0 4 | contourpy==1.2.1 5 | cycler==0.12.1 6 | flatbuffers==24.3.25 7 | fonttools==4.51.0 8 | jax==0.4.26 9 | kiwisolver==1.4.5 10 | matplotlib==3.8.4 11 | mediapipe==0.10.11 12 | ml-dtypes==0.4.0 13 | numpy==1.26.4 14 | opencv-contrib-python==4.9.0.80 15 | opencv-python==4.9.0.80 16 | opt-einsum==3.3.0 17 | packaging==24.0 18 | pillow==10.3.0 19 | protobuf==3.20.3 20 | pycparser==2.22 21 | pynput==1.7.6 22 | pyparsing==3.1.2 23 | python-dateutil==2.9.0.post0 24 | scipy==1.13.0 25 | six==1.16.0 26 | sounddevice==0.4.6 27 | --------------------------------------------------------------------------------