-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
115 lines (86 loc) · 3.7 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import tkinter as tk
import os
import PIL.Image, PIL.ImageTk
import cv2 as cv
import camera
import model
class App:
def __init__(self):
self.canvas = None
self.btn_toggleauto = None
self.btn_class_one = None
self.btn_class_two = None
self.btn_train = None
self.btn_reset = None
self.counter_label = None
self.photo = None
self.model = model.Model()
self.camera = camera.Camera()
self.window = tk.Tk()
self.window.title = "Biceps Curl Counter"
self.counters = [1, 1]
self.rep_counter = 0
self.extended = False
self.contracted = False
self.last_prediction = 0
self.counting_enabled = False
self.init_gui()
self.delay = 15
self.update()
self.window.attributes("-topmost", True)
self.window.mainloop()
def init_gui(self):
self.canvas = tk.Canvas(self.window, width=self.camera.width, height=self.camera.height)
self.canvas.pack()
self.btn_toggleauto = tk.Button(self.window, text="Toggle counting", width=50, command=self.counting_toggle)
self.btn_toggleauto.pack(anchor=tk.CENTER, expand=True)
self.btn_class_one = tk.Button(self.window, text="Extended", width=50, command=lambda: self.save_for_class(1))
self.btn_class_one.pack(anchor=tk.CENTER, expand=True)
self.btn_class_two = tk.Button(self.window, text="Contracted", width=50, command=lambda: self.save_for_class(2))
self.btn_class_two.pack(anchor=tk.CENTER, expand=True)
self.btn_train = tk.Button(self.window, text="Train model", width=50,
command=lambda: self.model.train_model(self.counters))
self.btn_train.pack(anchor=tk.CENTER, expand=True)
self.btn_reset = tk.Button(self.window, text="Reset", width=50, command=self.reset)
self.btn_reset.pack(anchor=tk.CENTER, expand=True)
self.counter_label = tk.Label(self.window, text=f"{self.rep_counter}")
self.counter_label.config(font=("Arial", 24))
self.counter_label.pack(anchor=tk.CENTER, expand=True)
def update(self):
if self.counting_enabled:
self.predict()
if self.extended and self.contracted:
self.extended, self.contracted = False, False
self.rep_counter += 1
self.counter_label.config(text=f"{self.rep_counter}")
ret, frame = self.camera.get_frame()
if ret:
self.photo = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame))
self.canvas.create_image(0, 0, image=self.photo, anchor=tk.W)
self.window.after(self.delay, self.update)
def predict(self):
frame = self.camera.get_frame()
prediction = self.model.predict(frame)
if prediction != self.last_prediction:
if prediction == 1:
self.extended = True
self.last_prediction = 1
if prediction == 2:
self.contracted = True
self.last_prediction = 2
def counting_toggle(self):
self.counting_enabled = not self.counting_enabled
def save_for_class(self, class_number: int):
ret, frame = self.camera.get_frame()
if not os.path.exists("1"):
os.mkdir("1")
if not os.path.exists("2"):
os.mkdir("2")
img_path = f"{class_number}/frame{self.counters[class_number - 1]}.jpg"
cv.imwrite(img_path, cv.cvtColor(frame, cv.COLOR_RGB2GRAY))
img = PIL.Image.open(img_path)
img.thumbnail((150, 150), PIL.Image.ANTIALIAS)
img.save(img_path)
self.counters[class_number - 1] += 1
def reset(self):
self.rep_counter = 0