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:
s460930 2021-01-07 22:13:39 +01:00
parent 1fc537a36c
commit bdf51e9f16
6 changed files with 69 additions and 82 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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.