├── HandTrackingModule.py
├── Readme.md
├── fingers
├── 0.jpg
├── 1.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
└── 5.jpg
├── img
└── result.gif
├── libraries.bat
├── main.py
└── requirements.txt
/HandTrackingModule.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import mediapipe as mp
3 | import time
4 | import math
5 |
6 | class handDetector():
7 | def __init__(self, mode=False, maxHands=2, modelComplexity=1, detectionCon=0.5, trackCon=0.5):
8 | self.mode = mode
9 | self.maxHands = maxHands
10 | self.modelComplexity = modelComplexity
11 | self.detectionCon = detectionCon
12 | self.trackCon = trackCon
13 |
14 | self.mpHands = mp.solutions.hands
15 | self.hands = self.mpHands.Hands(self.mode, self.maxHands, self.modelComplexity, self.detectionCon, self.trackCon)
16 | self.mpDraw = mp.solutions.drawing_utils
17 | self.tipIds = [4, 8, 12, 16, 20]
18 |
19 | def findHands(self, img, draw=True):
20 | imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
21 | self.results = self.hands.process(imgRGB)
22 | #print(results.multi_hand_landmarks)
23 |
24 | if self.results.multi_hand_landmarks:
25 | for handLms in self.results.multi_hand_landmarks:
26 | if draw:
27 | self.mpDraw.draw_landmarks(img, handLms, self.mpHands.HAND_CONNECTIONS)
28 | return img
29 |
30 | def findPosition(self, img, handNo=0, draw=True):
31 | xList = []
32 | yList = []
33 | bbox = []
34 | self.lmList = []
35 | if self.results.multi_hand_landmarks:
36 | myHand = self.results.multi_hand_landmarks[handNo]
37 | for id, lm in enumerate(myHand.landmark):
38 | #print(id, lm)
39 | h, w, c = img.shape
40 | cx, cy = int(lm.x*w), int(lm.y*h)
41 | xList.append(cx)
42 | yList.append(cy)
43 | #print(id, cx, cy)
44 | self.lmList.append([id, cx, cy])
45 | if draw:
46 | cv2.circle(img, (cx, cy), 5, (255,0,255), cv2.FILLED)
47 | xmin, xmax = min(xList), max(xList)
48 | ymin, ymax = min(yList), max(yList)
49 | bbox = xmin, ymin, xmax, ymax
50 |
51 | if draw:
52 | cv2.rectangle(img, (bbox[0]-20, bbox[1]-20), (bbox[2]+20, bbox[3]+20), (0, 255, 0), 2)
53 | return self.lmList, bbox
54 |
55 | def findDistance(self, p1, p2, img, draw=True):
56 | x1, y1 = self.lmList[p1][1], self.lmList[p1][2]
57 | x2, y2 = self.lmList[p2][1], self.lmList[p2][2]
58 | cx, cy = (x1+x2)//2, (y1+y2)//2
59 |
60 | if draw:
61 | cv2.circle(img, (x1,y1), 15, (255,0,255), cv2.FILLED)
62 | cv2.circle(img, (x2,y2), 15, (255,0,255), cv2.FILLED)
63 | cv2.line(img, (x1,y1), (x2,y2), (255,0,255), 3)
64 | cv2.circle(img, (cx,cy), 15, (255,0,255), cv2.FILLED)
65 |
66 | length = math.hypot(x2-x1, y2-y1)
67 | return length, img, [x1, y1, x2, y2, cx, cy]
68 |
69 | def fingersUp(self):
70 | fingers = []
71 |
72 | # Thumb
73 | if self.lmList[self.tipIds[0]][1] < self.lmList[self.tipIds[0]-1][1]:
74 | fingers.append(1)
75 | else:
76 | fingers.append(0)
77 |
78 | # 4 Fingers
79 | for id in range(1,5):
80 | if self.lmList[self.tipIds[id]][2] < self.lmList[self.tipIds[id]-2][2]:
81 | fingers.append(1)
82 | else:
83 | fingers.append(0)
84 | return fingers
85 |
86 | def main():
87 | pTime = 0
88 | cTime = 0
89 | cap = cv2.VideoCapture(0)
90 | detector = handDetector()
91 | while True:
92 | success, img = cap.read()
93 | img = detector.findHands(img)
94 | lmList = detector.findPosition(img)
95 | if len(lmList) != 0:
96 | print(lmList[1])
97 |
98 | cTime = time.time()
99 | fps = 1. / (cTime - pTime)
100 | pTime = cTime
101 |
102 | cv2.putText(img, str(int(fps)), (10,70), cv2.FONT_HERSHEY_PLAIN, 3, (255,0,255), 3)
103 |
104 | cv2.imshow("Image", img)
105 | cv2.waitKey(1)
106 |
107 |
108 | if __name__ == "__main__":
109 | main()
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Finger Counter
2 | In this project I am going to learn how to count fingers.
3 | I first look into hand tracking and then I will use the hand landmarks to count of the fingers.
4 |
5 | ## Features
6 | * Can track your hand in real-time
7 | * Can show the number of fingers raised
8 |
9 | ## How to install
10 | 1. Clone this repository on your computer
11 | `https://github.com/paveldat/finger_counter.git`
12 | 2. Install all the requirements
13 | `run libraries.bat` or
14 | `pip install -r requirements.txt`
15 | 3. Run the program
16 | `python main.py`
17 |
18 | ## Help
19 | You might face issue with webcam not showing and you get errors.
20 | To solve it just change the value in this line (for example to `1`).
21 | `cap = cv2.VideoCapture(0)`
22 | Increment this number until you see your webcam.
23 |
24 | ## Hand Landmarks
25 |
26 |
27 | ## Result
28 |
29 |
--------------------------------------------------------------------------------
/fingers/0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paveldat/finger_counter/6892bd1f66c247dababbf51d437bcd44e19055d9/fingers/0.jpg
--------------------------------------------------------------------------------
/fingers/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paveldat/finger_counter/6892bd1f66c247dababbf51d437bcd44e19055d9/fingers/1.jpg
--------------------------------------------------------------------------------
/fingers/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paveldat/finger_counter/6892bd1f66c247dababbf51d437bcd44e19055d9/fingers/2.jpg
--------------------------------------------------------------------------------
/fingers/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paveldat/finger_counter/6892bd1f66c247dababbf51d437bcd44e19055d9/fingers/3.jpg
--------------------------------------------------------------------------------
/fingers/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paveldat/finger_counter/6892bd1f66c247dababbf51d437bcd44e19055d9/fingers/4.jpg
--------------------------------------------------------------------------------
/fingers/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paveldat/finger_counter/6892bd1f66c247dababbf51d437bcd44e19055d9/fingers/5.jpg
--------------------------------------------------------------------------------
/img/result.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paveldat/finger_counter/6892bd1f66c247dababbf51d437bcd44e19055d9/img/result.gif
--------------------------------------------------------------------------------
/libraries.bat:
--------------------------------------------------------------------------------
1 | pip install mediapipe
2 | pip install opencv-python
3 | pip install math
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import cv2
2 | import time
3 | import os
4 |
5 | import HandTrackingModule as htm
6 |
7 | wCam, hCam = 640, 480
8 |
9 | cap = cv2.VideoCapture(0)
10 | cap.set(3, wCam)
11 | cap.set(4, hCam)
12 |
13 | folderPath = "fingers" # name of the folder, where there are images of fingers
14 | fingerList = os.listdir(folderPath) # list of image titles in 'fingers' folder
15 | overlayList = []
16 | for imgPath in fingerList:
17 | image = cv2.imread(f'{folderPath}/{imgPath}')
18 | overlayList.append(image)
19 |
20 | pTime = 0
21 |
22 | detector = htm.handDetector(detectionCon=0.75)
23 | totalFingers = 0
24 |
25 | while True:
26 | sucess, img = cap.read()
27 | img = cv2.flip(img, 1)
28 |
29 | img = detector.findHands(img)
30 | lmList, bbox = detector.findPosition(img, draw=False)
31 |
32 | if lmList:
33 | fingersUp = detector.fingersUp()
34 | totalFingers = fingersUp.count(1)
35 |
36 | h, w, c = overlayList[totalFingers].shape
37 | img[0:h, 0:w] = overlayList[totalFingers]
38 |
39 | cTime = time.time()
40 | fps = 1/ (cTime-pTime)
41 | pTime = cTime
42 |
43 | cv2.putText(img, f'FPS: {int(fps)}', (400, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)
44 | cv2.rectangle(img, (20, 225), (170, 425), (0, 255, 0), cv2.FILLED)
45 | cv2.putText(img, str(totalFingers), (45, 375), cv2.FONT_HERSHEY_PLAIN, 10, (255, 0, 0), 25)
46 |
47 | cv2.imshow("Image", img)
48 | cv2.waitKey(1)
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | opencv-python
2 | mediapipe
3 | math
--------------------------------------------------------------------------------