-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApp.py
More file actions
154 lines (118 loc) · 5.24 KB
/
App.py
File metadata and controls
154 lines (118 loc) · 5.24 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import tkinter as tk
from idlelib.browser import file_open
from logging import raiseExceptions
from modulefinder import Module
from tkinter.filedialog import Open
from tkinter.filedialog import asksaveasfilename
import cv2 as cv
from typing import Union, Any
__all__ = ["MachineVisionApp"]
class MainWindow(tk.Frame):
"""
MainWindow is a tkinter Frame that serves as the main interface for the application.
Methods:
open_image():
Opens a file dialog to upload an image in color mode.
Displays the selected image in a new OpenCV window.
open_image_gray():
Opens a file dialog to upload an image in grayscale mode.
Displays the selected image in a new OpenCV window.
"""
def __init__(self, parent, controller):
super().__init__(parent)
self.filename = None
self.master = controller
label = tk.Label(self, text="Main Page", font=("Segoe UI", 16))
label.pack(pady=10, padx=10)
open_image_gray = tk.Button(self, text="Upload Image", command=self.open_image)
open_image_gray.pack(pady=10, padx=10)
open_image_gray = tk.Button(self, text="Upload Image Gray", command=self.open_image_gray)
open_image_gray.pack(pady=10, padx=10)
def open_image(self):
file_types = [('Images', '*.jpg *.tif *.bmp *.png *.jpeg *.webp')]
dlg = Open(self, filetypes=file_types, title='Open Image')
self.filename = dlg.show()
if self.filename:
# Check if the "Image In" window exists
if cv.getWindowProperty('Image In', cv.WND_PROP_VISIBLE) >= 1:
cv.destroyWindow('Image In')
self.master.image = cv.imread(self.filename, cv.IMREAD_COLOR)
cv.imshow('Image In', self.master.image)
def open_image_gray(self):
file_types = [('Images', '*.jpg *.tif *.bmp *.png *.jpeg *.webp')]
dlg = Open(self, filetypes=file_types, title='Open Image Gray')
self.filename = dlg.show()
if self.filename:
# Check if the "Image In" window exists
if cv.getWindowProperty('Image In', cv.WND_PROP_VISIBLE) >= 1:
cv.destroyWindow('Image In')
self.master.image = cv.imread(self.filename, cv.IMREAD_GRAYSCALE)
cv.imshow('ImageIn', self.master.image)
class ErrorWindow(tk.Frame):
"""
ErrorWindow is a GUI component for displaying error messages using Tkinter.
Methods:
update_register():
Updates the error label's text to display the current list of errors
stored in the instance.
"""
def __init__(self, parent, error: str = "No error"):
super().__init__(parent)
self.error = []
self.error_text = tk.Label(self, text=error, font=("Segoe UI", 16))
self.error_text.pack(pady=10, padx=10)
def update_register(self):
self.error_text.config(text="\n".join(self.error))
class MachineVisionApp(tk.Tk):
"""
Machine Vision Main GUI Application, with included image transformation function
access through Menu.
"""
def __init__(self):
super().__init__()
# Class private variable
self.image = None
self.result_image = None
self.title("Machine Vision Application")
self.geometry("400x300")
# Create a container for the frames
container = tk.Frame(self)
container.pack(fill=tk.BOTH, expand=True)
# Main windows
self.main_window = MainWindow(container, self)
self.main_window.pack(fill=tk.BOTH, expand=True)
# menu
self.menu = tk.Menu(self)
self.config(menu=self.menu)
self.menus = {}
# error register
self.error_register = ErrorWindow(self)
def transformers(self, module: Union[Module, any], group: str = "Image Processing"):
try:
# check if the given module have __all__ attribute
getattr(module, '__all__')
# Create new menu group if it not exist yet
if group not in self.menus:
self.menus[group] = tk.Menu(self.menu, tearoff=0)
# Wrapper
def define_callback(tf_: callable):
def callback(image=self.image):
print(tf_.__name__)
self.result_image = tf_(self.image)
cv.imshow('Image out', self.result_image)
return callback
# Include function to the GUI Menu
for function in module.__all__:
transform_function = getattr(module, function)
self.menus[group].add_command(label=transform_function.__name__,
command=define_callback(transform_function))
self.menu.add_cascade(label=group, menu=self.menus[group])
except AttributeError:
# If module not have the attribute, we should se that module name in the error windows (Frame)
self.error_register.error.append(f"{module.__name__} not have attribute __all__, please define it!")
self.error_register.update_register()
self.error_register.tkraise()
if __name__ == "__main__":
# Manual test application
app = MachineVisionApp()
app.mainloop()