SMART-62 - split project view into two frames: top with canvas and (for now) fingers state, bottom with back button and video capturing
This commit is contained in:
parent
1fc537a36c
commit
bdf51e9f16
@ -12,7 +12,7 @@ class SmartPicasso(tk.Tk):
|
|||||||
tk.Tk.__init__(self, *args, **kwargs)
|
tk.Tk.__init__(self, *args, **kwargs)
|
||||||
container = tk.Frame(self)
|
container = tk.Frame(self)
|
||||||
self.title('SmartPicasso')
|
self.title('SmartPicasso')
|
||||||
self.geometry('610x460')
|
self.geometry('800x600')
|
||||||
|
|
||||||
container.pack(side="top", fill="both", expand=True)
|
container.pack(side="top", fill="both", expand=True)
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
FONT = ("Verdana", 12)
|
FONT = ("Verdana", 12)
|
||||||
|
FONT_SM = ("Verdana", 10)
|
||||||
FONT_B = ("Verdana", 12, 'bold')
|
FONT_B = ("Verdana", 12, 'bold')
|
||||||
FONT_LARGE = ("Verdana", 20)
|
FONT_LARGE = ("Verdana", 20)
|
||||||
|
|
||||||
|
@ -35,13 +35,15 @@ class MyVideoCapture:
|
|||||||
self.mp_drawing.draw_landmarks(
|
self.mp_drawing.draw_landmarks(
|
||||||
image, hand_landmarks, self.mp_hands.HAND_CONNECTIONS)
|
image, hand_landmarks, self.mp_hands.HAND_CONNECTIONS)
|
||||||
# if cv2.waitKey(33) == ord('s'):
|
# if cv2.waitKey(33) == ord('s'):
|
||||||
fingers = {'index': '', 'middle': '', 'ring': '', 'pinky': ''}
|
fingers = {'index': (), 'middle': (), 'ring': (), 'pinky': ()}
|
||||||
if results.multi_hand_landmarks:
|
if results.multi_hand_landmarks:
|
||||||
for hand_landmarks in results.multi_hand_landmarks:
|
for hand_landmarks in results.multi_hand_landmarks:
|
||||||
fingers['index'] = sgest.check_index_finger(hand_landmarks)
|
fingers['index'] = sgest.check_index_finger(hand_landmarks)
|
||||||
fingers['middle'] = sgest.check_middle_finger(hand_landmarks)
|
fingers['middle'] = sgest.check_middle_finger(hand_landmarks)
|
||||||
fingers['ring'] = sgest.check_ring_finger(hand_landmarks)
|
fingers['ring'] = sgest.check_ring_finger(hand_landmarks)
|
||||||
fingers['pinky'] = sgest.check_pinky_finger(hand_landmarks)
|
fingers['pinky'] = sgest.check_pinky_finger(hand_landmarks)
|
||||||
|
else:
|
||||||
|
fingers = None
|
||||||
return fingers, image, success
|
return fingers, image, success
|
||||||
|
|
||||||
# Release the video source when the object is destroyed
|
# Release the video source when the object is destroyed
|
||||||
|
@ -1,78 +1,41 @@
|
|||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
|
|
||||||
def calculate_distance(ax, ay, bx, by):
|
def calculate_distance(ax, ay, bx, by):
|
||||||
distance = sqrt(((bx - ax) ** 2 + (by - ay) ** 2))
|
distance = sqrt(((bx - ax) ** 2 + (by - ay) ** 2))
|
||||||
return distance
|
return distance
|
||||||
|
|
||||||
def check_index_finger(hand_landmarks):
|
|
||||||
ax = hand_landmarks.landmark[8].x
|
|
||||||
ay = hand_landmarks.landmark[8].y
|
|
||||||
bx = hand_landmarks.landmark[5].x
|
|
||||||
by = hand_landmarks.landmark[5].y
|
|
||||||
distance_8_5 = calculate_distance(ax, ay, bx, by)
|
|
||||||
ax = hand_landmarks.landmark[5].x
|
|
||||||
ay = hand_landmarks.landmark[5].y
|
|
||||||
bx = hand_landmarks.landmark[0].x
|
|
||||||
by = hand_landmarks.landmark[0].y
|
|
||||||
distance_5_0 = calculate_distance(ax, ay, bx, by)
|
|
||||||
|
|
||||||
if (distance_5_0 < distance_8_5 + 0.1):
|
def check_index_finger(hand_landmarks):
|
||||||
result = "wskazujacy_wyprostowany"
|
return check_finger(hand_landmarks, 8, 5, 'wskazujacy')
|
||||||
else:
|
|
||||||
result = "wskazujacy_niewyprostowany"
|
|
||||||
return (result, hand_landmarks.landmark[8].x, hand_landmarks.landmark[8].y)
|
|
||||||
|
|
||||||
def check_middle_finger(hand_landmarks):
|
def check_middle_finger(hand_landmarks):
|
||||||
ax = hand_landmarks.landmark[12].x
|
return check_finger(hand_landmarks, 12, 9, 'srodkowy')
|
||||||
ay = hand_landmarks.landmark[12].y
|
|
||||||
bx = hand_landmarks.landmark[9].x
|
|
||||||
by = hand_landmarks.landmark[9].y
|
|
||||||
distance_12_9 = calculate_distance(ax, ay, bx, by)
|
|
||||||
ax = hand_landmarks.landmark[9].x
|
|
||||||
ay = hand_landmarks.landmark[9].y
|
|
||||||
bx = hand_landmarks.landmark[0].x
|
|
||||||
by = hand_landmarks.landmark[0].y
|
|
||||||
distance_9_0 = calculate_distance(ax, ay, bx, by)
|
|
||||||
|
|
||||||
if (distance_9_0 < distance_12_9 + 0.1):
|
|
||||||
result = "srodkowy_wyprostowany"
|
|
||||||
else:
|
|
||||||
result = "srodkowy_niewyprostowany"
|
|
||||||
return (result, hand_landmarks.landmark[12].x, hand_landmarks.landmark[12].y)
|
|
||||||
|
|
||||||
def check_ring_finger(hand_landmarks):
|
def check_ring_finger(hand_landmarks):
|
||||||
ax = hand_landmarks.landmark[16].x
|
return check_finger(hand_landmarks, 16, 13, 'serdeczny')
|
||||||
ay = hand_landmarks.landmark[16].y
|
|
||||||
bx = hand_landmarks.landmark[13].x
|
|
||||||
by = hand_landmarks.landmark[13].y
|
|
||||||
distance_16_13 = calculate_distance(ax, ay, bx, by)
|
|
||||||
ax = hand_landmarks.landmark[13].x
|
|
||||||
ay = hand_landmarks.landmark[13].y
|
|
||||||
bx = hand_landmarks.landmark[0].x
|
|
||||||
by = hand_landmarks.landmark[0].y
|
|
||||||
distance_13_0 = calculate_distance(ax, ay, bx, by)
|
|
||||||
|
|
||||||
if (distance_13_0 < distance_16_13 + 0.1):
|
|
||||||
result = "serdeczny_wyprostowany"
|
|
||||||
else:
|
|
||||||
result = "serdeczny_niewyprostowany"
|
|
||||||
return (result, hand_landmarks.landmark[16].x, hand_landmarks.landmark[16].y)
|
|
||||||
|
|
||||||
def check_pinky_finger(hand_landmarks):
|
def check_pinky_finger(hand_landmarks):
|
||||||
ax = hand_landmarks.landmark[20].x
|
return check_finger(hand_landmarks, 20, 17, 'maly')
|
||||||
ay = hand_landmarks.landmark[20].y
|
|
||||||
bx = hand_landmarks.landmark[17].x
|
|
||||||
by = hand_landmarks.landmark[17].y
|
def check_finger(hand_landmarks, top_idx, bottom_idx, name):
|
||||||
distance_20_17 = calculate_distance(ax, ay, bx, by)
|
ax = hand_landmarks.landmark[top_idx].x
|
||||||
ax = hand_landmarks.landmark[17].x
|
ay = hand_landmarks.landmark[top_idx].y
|
||||||
ay = hand_landmarks.landmark[17].y
|
bx = hand_landmarks.landmark[bottom_idx].x
|
||||||
|
by = hand_landmarks.landmark[bottom_idx].y
|
||||||
|
distance_top_bottom = calculate_distance(ax, ay, bx, by)
|
||||||
|
ax = hand_landmarks.landmark[bottom_idx].x
|
||||||
|
ay = hand_landmarks.landmark[bottom_idx].y
|
||||||
bx = hand_landmarks.landmark[0].x
|
bx = hand_landmarks.landmark[0].x
|
||||||
by = hand_landmarks.landmark[0].y
|
by = hand_landmarks.landmark[0].y
|
||||||
distance_17_0 = calculate_distance(ax, ay, bx, by)
|
distance_bottom_start = calculate_distance(ax, ay, bx, by)
|
||||||
|
|
||||||
if (distance_17_0 < distance_20_17 + 0.1):
|
if distance_bottom_start < distance_top_bottom + 0.1:
|
||||||
result = "maly_wyprostowany"
|
result = name + '_wyprostowany'
|
||||||
else:
|
else:
|
||||||
result = "maly_niewyprostowany"
|
result = name + '_niewyprostowany'
|
||||||
return (result, hand_landmarks.landmark[20].x, hand_landmarks.landmark[20].y)
|
return result, hand_landmarks.landmark[top_idx].x, hand_landmarks.landmark[top_idx].y
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import PIL.Image
|
|||||||
import PIL.ImageTk
|
import PIL.ImageTk
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
|
|
||||||
from constants import PROJECT_VIEW_NAME, FONT, PROJECTS_VIEW_NAME
|
from constants import PROJECT_VIEW_NAME, FONT_SM, FONT, PROJECTS_VIEW_NAME
|
||||||
from gestures.gesture_recognition import MyVideoCapture
|
from gestures.gesture_recognition import MyVideoCapture
|
||||||
from views.abstract_view import AbstractView
|
from views.abstract_view import AbstractView
|
||||||
|
|
||||||
@ -16,12 +16,15 @@ class ProjectView(tk.Frame, AbstractView):
|
|||||||
self.main_view_controller = main_view_controller
|
self.main_view_controller = main_view_controller
|
||||||
self.delay = 20
|
self.delay = 20
|
||||||
self.vid = None
|
self.vid = None
|
||||||
|
self.vid_canvas = None
|
||||||
self.canvas = None
|
self.canvas = None
|
||||||
self.index_label = None
|
self.index_label = None
|
||||||
self.middle_label = None
|
self.middle_label = None
|
||||||
self.ring_label = None
|
self.ring_label = None
|
||||||
self.pinky_label = None
|
self.pinky_label = None
|
||||||
self.back_button = None
|
self.back_button = None
|
||||||
|
self.bottom_frame = None
|
||||||
|
self.top_frame = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_view_name() -> str:
|
def get_view_name() -> str:
|
||||||
@ -30,20 +33,34 @@ class ProjectView(tk.Frame, AbstractView):
|
|||||||
def start(self):
|
def start(self):
|
||||||
self.vid = MyVideoCapture()
|
self.vid = MyVideoCapture()
|
||||||
|
|
||||||
self.canvas = tk.Canvas(self, width=self.vid.width, height=self.vid.height)
|
self.top_frame = tk.Frame(self, relief=tk.RAISED, borderwidth=0)
|
||||||
self.canvas.pack()
|
self.top_frame.pack(fill=tk.BOTH, side=tk.TOP)
|
||||||
|
self.top_frame.columnconfigure(0, weight=2)
|
||||||
|
self.top_frame.columnconfigure(1, weight=1)
|
||||||
|
print(self.top_frame['width'])
|
||||||
|
print(self.top_frame['height'])
|
||||||
|
self.canvas = tk.Canvas(self.top_frame, width=465, height=415, bg="blue")
|
||||||
|
coord = 10, 50, 240, 210
|
||||||
|
self.canvas.create_arc(coord, start=0, extent=150, fill="red")
|
||||||
|
self.canvas.grid(row=0, column=0, sticky=tk.W, rowspan=4)
|
||||||
|
self.index_label = tk.Label(self.top_frame, font=FONT_SM)
|
||||||
|
self.index_label.grid(row=0, column=1)
|
||||||
|
self.middle_label = tk.Label(self.top_frame, font=FONT_SM)
|
||||||
|
self.middle_label.grid(row=1, column=1)
|
||||||
|
self.ring_label = tk.Label(self.top_frame, font=FONT_SM)
|
||||||
|
self.ring_label.grid(row=2, column=1)
|
||||||
|
self.pinky_label = tk.Label(self.top_frame, font=FONT_SM)
|
||||||
|
self.pinky_label.grid(row=3, column=1)
|
||||||
|
|
||||||
self.index_label = tk.Label(self, font=FONT)
|
self.bottom_frame = tk.Frame(self, relief=tk.RAISED, borderwidth=1)
|
||||||
self.index_label.pack(anchor=tk.CENTER, expand=True)
|
self.bottom_frame.pack(fill=tk.BOTH, side=tk.BOTTOM)
|
||||||
self.middle_label = tk.Label(self, font=FONT)
|
self.bottom_frame.columnconfigure(0, weight=1)
|
||||||
self.middle_label.pack(anchor=tk.CENTER, expand=True)
|
self.bottom_frame.columnconfigure(1, weight=1)
|
||||||
self.ring_label = tk.Label(self, font=FONT)
|
self.back_button = tk.Button(self.bottom_frame, text="Back", font=FONT,
|
||||||
self.ring_label.pack(anchor=tk.CENTER, expand=True)
|
command=lambda: self.back_to_projects_view())
|
||||||
self.pinky_label = tk.Label(self, font=FONT)
|
self.back_button.grid(row=0, column=0, sticky=tk.SW)
|
||||||
self.pinky_label.pack(anchor=tk.CENTER, expand=True)
|
self.vid_canvas = tk.Canvas(self.bottom_frame, width=self.vid.width, height=self.vid.height)
|
||||||
|
self.vid_canvas.grid(row=0, column=1, sticky=tk.E)
|
||||||
self.back_button = tk.Button(self, text="Back", font=FONT, command=lambda: self.back_to_projects_view())
|
|
||||||
self.back_button.pack()
|
|
||||||
|
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
@ -51,25 +68,29 @@ class ProjectView(tk.Frame, AbstractView):
|
|||||||
# Get a frame from the video source
|
# Get a frame from the video source
|
||||||
if self.vid is not None:
|
if self.vid is not None:
|
||||||
fingers, frame, success = self.vid.get_frame()
|
fingers, frame, success = self.vid.get_frame()
|
||||||
self.index_label['text'] = fingers['index']
|
if fingers is not None:
|
||||||
self.middle_label['text'] = fingers['middle']
|
self.index_label['text'] = fingers['index'][0]
|
||||||
self.ring_label['text'] = fingers['ring']
|
self.middle_label['text'] = fingers['middle'][0]
|
||||||
self.pinky_label['text'] = fingers['pinky']
|
self.ring_label['text'] = fingers['ring'][0]
|
||||||
|
self.pinky_label['text'] = fingers['pinky'][0]
|
||||||
|
|
||||||
if success:
|
if success:
|
||||||
self.photo = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame))
|
self.photo = PIL.ImageTk.PhotoImage(image=PIL.Image.fromarray(frame))
|
||||||
self.canvas.create_image(0, 0, image=self.photo, anchor=tk.NW)
|
self.vid_canvas.create_image(0, 0, image=self.photo, anchor=tk.NW)
|
||||||
|
|
||||||
self.window.after(self.delay, self.update)
|
self.window.after(self.delay, self.update)
|
||||||
|
|
||||||
def back_to_projects_view(self):
|
def back_to_projects_view(self):
|
||||||
self.main_view_controller.show_frame(PROJECTS_VIEW_NAME)
|
self.main_view_controller.show_frame(PROJECTS_VIEW_NAME)
|
||||||
self.vid.release()
|
self.vid.release()
|
||||||
self.destroy_components()
|
self.destroy_widgets()
|
||||||
|
|
||||||
def destroy_components(self):
|
def destroy_widgets(self):
|
||||||
self.vid = None
|
self.vid = None
|
||||||
|
self.top_frame.destroy()
|
||||||
self.canvas.destroy()
|
self.canvas.destroy()
|
||||||
|
self.bottom_frame.destroy()
|
||||||
|
self.vid_canvas.destroy()
|
||||||
self.index_label.destroy()
|
self.index_label.destroy()
|
||||||
self.middle_label.destroy()
|
self.middle_label.destroy()
|
||||||
self.ring_label.destroy()
|
self.ring_label.destroy()
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user