├── README.md ├── Dino Browser ├── HandTrackingMin.py ├── HandTrackingModule.py └── mainDino.py ├── singleHand.py └── multiHand.py /README.md: -------------------------------------------------------------------------------- 1 | # gesture-range-control 2 | 3 | **Python packages required:** 4 | * cvzone 1.5.0 5 | * mediapipe 0.8.7.1 6 | * pyfirmata 1.1.0 7 | 8 | **Arduino Configuration** 9 | - Open IDE Arduino 10 | - Select File -> Example -> Firmata -> StandardFirmata 11 | - Select Tools -> Board -> Arduino/Genuino Uno 12 | - Select Tools -> Port -> *choose your port COM* 13 | - Upload 14 | 15 | -------------------------------------------------------------------------------- /Dino Browser/HandTrackingMin.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import mediapipe as mp 3 | import time 4 | 5 | cap = cv2.VideoCapture(0) 6 | 7 | mpHands = mp.solutions.hands 8 | hands = mpHands.Hands() 9 | mpDraw = mp.solutions.drawing_utils 10 | 11 | pTime = 0 12 | cTime = 0 13 | 14 | while True: 15 | success, img = cap.read() 16 | imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 17 | results = hands.process(imgRGB) 18 | print(results.multi_hand_landmarks) 19 | 20 | if results.multi_hand_landmarks: 21 | for handLms in results.multi_hand_landmarks: 22 | for id, lm in enumerate(handLms.landmark): 23 | # print(id, lm) 24 | h, w, c = img.shape 25 | cx, cy = int(lm.x * w), int(lm.y * h) 26 | print(id, cx, cy) 27 | # if id == 4: 28 | cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED) 29 | 30 | mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS) 31 | 32 | cTime = time.time() 33 | fps = 1 / (cTime - pTime) 34 | pTime = cTime 35 | 36 | cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, 37 | (255, 0, 255), 3) 38 | 39 | cv2.imshow("Image", img) 40 | cv2.waitKey(1) -------------------------------------------------------------------------------- /singleHand.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | from cvzone.HandTrackingModule import HandDetector 3 | import numpy as np 4 | import pyfirmata 5 | 6 | cap = cv2.VideoCapture(0) 7 | cap.set(3, 1280) 8 | cap.set(4, 720) 9 | 10 | detector = HandDetector(detectionCon=0.8, maxHands=1) 11 | 12 | minHand, maxHand = 20, 250 13 | minBar, maxBar = 400, 150 14 | minAngle, maxAngle = 0, 180 15 | 16 | port = "COM7" 17 | board = pyfirmata.Arduino(port) 18 | servoPin = board.get_pin('d:5:s') # pin 5 Arduino 19 | 20 | 21 | while True: 22 | success, img = cap.read() 23 | hands, img = detector.findHands(img) 24 | 25 | if hands: 26 | thumbTip = hands[0]["lmList"][4] 27 | indexTip = hands[0]["lmList"][8] 28 | 29 | length, _, _ = detector.findDistance(indexTip, thumbTip, img) 30 | # print(int(length)) 31 | servoVal = np.interp(length, [minHand, maxHand], [minAngle, maxAngle]) 32 | # print(int(servoVal)) 33 | 34 | cv2.rectangle(img, (100,100), (360, 30), (255, 0, 0), cv2.FILLED) 35 | cv2.putText(img, f'Length: {int(length)}', (130, 70), cv2.FONT_HERSHEY_PLAIN, 2, 36 | (0, 255, 255), 3) 37 | 38 | cv2.rectangle(img, (500, 100), (760, 30), (0, 255, 255), cv2.FILLED) 39 | cv2.putText(img, f'Servo: {int(servoVal)}', (530, 70), cv2.FONT_HERSHEY_PLAIN, 2, 40 | (255, 0, 0), 3) 41 | 42 | bar = np.interp(length, [minHand, maxHand], [minBar, maxBar]) 43 | cv2.rectangle(img, (1180, 150), (1215, 400), (255, 0, 0), 3) 44 | cv2.rectangle(img, (1180, int(bar)), (1215, 400), (0, 255, 0), cv2.FILLED) 45 | 46 | servoPin.write(servoVal) 47 | 48 | cv2.imshow("Image", img) 49 | cv2.waitKey(1) 50 | -------------------------------------------------------------------------------- /Dino Browser/HandTrackingModule.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import mediapipe as mp 3 | import time 4 | 5 | 6 | class handDetector(): 7 | def __init__(self, mode=False, maxHands=2, detectionCon=0.5, trackCon=0.5): 8 | self.mode = mode 9 | self.maxHands = maxHands 10 | self.detectionCon = detectionCon 11 | self.trackCon = trackCon 12 | 13 | self.mpHands = mp.solutions.hands 14 | self.hands = self.mpHands.Hands(self.mode, self.maxHands, 15 | self.detectionCon, self.trackCon) 16 | self.mpDraw = mp.solutions.drawing_utils 17 | 18 | def findHands(self, img, draw=True): 19 | imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 20 | self.results = self.hands.process(imgRGB) 21 | # print(results.multi_hand_landmarks) 22 | 23 | if self.results.multi_hand_landmarks: 24 | for handLms in self.results.multi_hand_landmarks: 25 | if draw: 26 | self.mpDraw.draw_landmarks(img, handLms, 27 | self.mpHands.HAND_CONNECTIONS) 28 | return img 29 | 30 | def findPosition(self, img, handNo=0, draw=True): 31 | 32 | lmList = [] 33 | if self.results.multi_hand_landmarks: 34 | myHand = self.results.multi_hand_landmarks[handNo] 35 | for id, lm in enumerate(myHand.landmark): 36 | # print(id, lm) 37 | h, w, c = img.shape 38 | cx, cy = int(lm.x * w), int(lm.y * h) 39 | # print(id, cx, cy) 40 | lmList.append([id, cx, cy]) 41 | if draw: 42 | cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED) 43 | 44 | return lmList 45 | 46 | 47 | def main(): 48 | pTime = 0 49 | cTime = 0 50 | cap = cv2.VideoCapture(1) 51 | detector = handDetector() 52 | while True: 53 | success, img = cap.read() 54 | img = detector.findHands(img) 55 | lmList = detector.findPosition(img) 56 | if len(lmList) != 0: 57 | print(lmList[4]) 58 | 59 | cTime = time.time() 60 | fps = 1 / (cTime - pTime) 61 | pTime = cTime 62 | 63 | cv2.putText(img, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, 64 | (255, 0, 255), 3) 65 | 66 | cv2.imshow("Image", img) 67 | cv2.waitKey(1) 68 | 69 | 70 | if __name__ == "__main__": 71 | main() -------------------------------------------------------------------------------- /Dino Browser/mainDino.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import time 3 | import numpy as np 4 | import HandTrackingModule as htm 5 | import math 6 | import pyautogui 7 | ################################ 8 | wCam, hCam = 1280, 720 9 | ################################ 10 | 11 | 12 | cap = cv2.VideoCapture(0) 13 | cap.set(3, wCam) 14 | cap.set(4, hCam) 15 | pTime = 0 16 | 17 | status = "Normal" 18 | 19 | detector = htm.handDetector(detectionCon=0.7) 20 | 21 | minAngle = 0 22 | maxAngle = 255 23 | angle = 0 24 | angleBar = 400 25 | angleDeg = 0 26 | minHand = 50 # 50 27 | maxHand = 300 # 300 28 | while True: 29 | success, img = cap.read() 30 | img = detector.findHands(img) 31 | lmList = detector.findPosition(img, draw=False) 32 | if len(lmList) != 0: 33 | # print(lmList[4], lmList[8]) 34 | 35 | x1, y1 = lmList[4][1], lmList[4][2] 36 | x2, y2 = lmList[8][1], lmList[8][2] 37 | cx, cy = (x1 + x2) // 2, (y1 + y2) // 2 38 | 39 | cv2.circle(img, (x1, y1), 15, (0, 0, 255), cv2.FILLED) 40 | cv2.circle(img, (x2, y2), 15, (0, 0, 255), cv2.FILLED) 41 | cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 3) 42 | cv2.circle(img, (cx, cy), 15, (0, 0, 255), cv2.FILLED) 43 | 44 | length = math.hypot(x2 - x1, y2 - y1) 45 | # print(length) 46 | 47 | # Hand range 50 - 300 48 | 49 | angle = np.interp(length, [minHand, maxHand], [minAngle, maxAngle]) 50 | angleBar = np.interp(length, [minHand, maxHand], [400, 150]) 51 | angleDeg = np.interp(length, [minHand, maxHand], [0, 255]) # degree angle 0 - 180 52 | 53 | key = cv2.waitKey(1) & 0xff 54 | 55 | if length < 50: 56 | cv2.circle(img, (cx, cy), 15, (0, 255, 0), cv2.FILLED) 57 | 58 | if angleDeg < 50: 59 | status = "Down" 60 | pyautogui.keyDown('down') 61 | elif angleDeg >= 50 and angleDeg <= 200: 62 | status = "Run" 63 | else: 64 | status = "Jump" 65 | pyautogui.keyDown('up') 66 | 67 | cv2.putText(img, status, (40, 100), cv2.FONT_HERSHEY_COMPLEX, 68 | 2, (0, 255, 0), 3) 69 | 70 | 71 | # cv2.rectangle(img, (50, 150), (85, 400), (255, 0, 0), 3) 72 | # cv2.rectangle(img, (50, int(angleBar)), (85, 400), (255, 0, 0), cv2.FILLED) 73 | # cv2.putText(img, f'{int(angleDeg)}', (40, 90), cv2.FONT_HERSHEY_COMPLEX, 74 | # 2, (0, 9, 255), 3) 75 | 76 | # cTime = time.time() 77 | # fps = 1 / (cTime - pTime) 78 | # pTime = cTime 79 | # cv2.putText(img, f'FPS: {int(fps)}', (40, 50), cv2.FONT_HERSHEY_COMPLEX, 80 | # 1, (255, 0, 0), 3) 81 | 82 | cv2.imshow("Img", img) 83 | cv2.waitKey(1) -------------------------------------------------------------------------------- /multiHand.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | from cvzone.HandTrackingModule import HandDetector 3 | import numpy as np 4 | import pyfirmata 5 | import random 6 | 7 | cap = cv2.VideoCapture(0) 8 | cap.set(3, 1280) 9 | cap.set(4, 720) 10 | 11 | detector = HandDetector(detectionCon=0.8, maxHands=2) 12 | 13 | # port = "COM7" 14 | # board = pyfirmata.Arduino(port) 15 | # servo_pinX = board.get_pin('d:5:s') #pin 5 Arduino 16 | # servo_pinY = board.get_pin('d:6:s') #pin 6 Arduino 17 | 18 | posCircle = [] 19 | posCircleTarget = [] 20 | 21 | minHand, maxHand = 20, 220 22 | minDeg, maxDeg = 0, 180 23 | minBar, maxBar = 400, 150 24 | xbox, ybox = 400, 500 25 | wbox, hbox = 450, 450 26 | x_rand = random.randint(xbox + 25, xbox + wbox - 25) 27 | y_rand = random.randint(ybox - hbox + 25, ybox - 25) 28 | score = 0 29 | edgeBox = False 30 | 31 | while True: 32 | success, img = cap.read() 33 | hands = detector.findHands(img, draw = False) 34 | 35 | 36 | if hands: 37 | 38 | hand_l = hands[0] 39 | lmList_l = hand_l["lmList"] # List of 21 Landmark points 40 | length_l, info_l, img = detector.findDistance(lmList_l[8], lmList_l[4], img) 41 | 42 | 43 | # Hand 2 (Right) 44 | if len(hands) == 2: 45 | hand_r = hands[1] 46 | lmList_r = hand_r["lmList"] # List of 21 Landmark points 47 | length_r, info_r, img = detector.findDistance(lmList_r[8], lmList_r[4], img) # with draw 48 | 49 | 50 | xl = lmList_l[8][0] 51 | yl = lmList_l[8][1] 52 | xr = lmList_r[8][0] 53 | yr = lmList_r[8][1] 54 | 55 | # left x | right y 56 | circleX = np.interp(length_l, [minHand, maxHand], [xbox+25, xbox+wbox-25]) 57 | circleY = np.interp(length_r, [minHand, maxHand], [ybox-25, ybox-hbox+25]) 58 | 59 | servoX = np.interp(length_l, [minHand, maxHand], [minDeg, maxDeg]) 60 | servoY = np.interp(length_r, [minHand, maxHand], [maxDeg, minDeg]) 61 | 62 | barX = np.interp(length_l, [minHand, maxHand], [minBar, maxBar]) 63 | barY = np.interp(length_r, [minHand, maxHand], [minBar, maxBar]) 64 | 65 | # circle player 66 | posCircle = [int(circleX), int(circleY)] 67 | cv2.circle(img, posCircle, 25, (0, 0, 255), cv2.FILLED ) 68 | 69 | if xbox+25 < posCircle[0] < xbox+wbox-25 and ybox-hbox+25 < posCircle[1] < hbox+25: 70 | colBox = [255, 0, 0] 71 | if edgeBox == False: 72 | edgeBox = not edgeBox 73 | else: 74 | colBox = [0, 0, 255] 75 | if edgeBox: 76 | score = 0 77 | edgeBox = not edgeBox 78 | 79 | 80 | # box area 81 | cv2.rectangle(img, (xbox, ybox+50), (xbox+wbox, ybox-hbox), colBox, 3) 82 | cv2.rectangle(img, (xbox, ybox), (xbox+wbox, ybox+50), colBox, cv2.FILLED) 83 | cv2.putText(img, f'Score : {score}', (xbox+80, ybox+40), cv2.FONT_HERSHEY_PLAIN, 3, (255, 255, 255), 3) 84 | 85 | #circle target 86 | if x_rand-35 < posCircle[0] < x_rand+35 and y_rand-35 < posCircle[1] < y_rand+35 : 87 | x_rand = random.randint(xbox + 25, xbox + wbox - 25) 88 | y_rand = random.randint(ybox - hbox + 25, ybox - 25) 89 | score += 5 90 | cv2.circle(img, (x_rand, y_rand), 25, (0, 255, 255), cv2.FILLED) 91 | 92 | #bar 93 | cv2.rectangle(img, (1180, 150), (1215, 400), (255, 0, 0), 3) 94 | cv2.rectangle(img, (1180, int(barX)), (1215, 400), (0, 255, 0), cv2.FILLED) 95 | 96 | cv2.rectangle(img, (50, 150), (85, 400), (255, 0, 0), 3) 97 | cv2.rectangle(img, (50, int(barY)), (85, 400), (0, 255, 0), cv2.FILLED) 98 | 99 | #servo control 100 | # servo_pinX.write(servoX) 101 | # servo_pinY.write(servoY) 102 | 103 | cv2.imshow("Image", img) 104 | cv2.waitKey(1) 105 | 106 | --------------------------------------------------------------------------------