Project

General

Profile

Files » ver2_comment_classCommands.py

Chia-Chi TSAI, 10/24/2024 01:47 PM

 
1
import cv2 as cv
2
import numpy as np
3
import tkinter as tk
4
from tkinter import filedialog, messagebox
5
import os
6
from PIL import Image, ImageTk
7

    
8
class SharedData:
9
    def __init__(self):
10
        self.left_image = None
11
        self.right_image = None
12
        self.overlap_region = 0
13

    
14
class ImageIO:
15
    def __init__(self, shared_data):
16
        self.shared_data = shared_data
17

    
18
    def load_image(self, path):
19
        return cv.imread(path, cv.IMREAD_COLOR)
20

    
21
    def write_image(self, img, fileName="image.png"):
22
        if cv.imwrite(fileName, img):
23
            print(f"File {fileName} Written Successfully")
24
        else:
25
            print("File writing failed")
26

    
27
    def show_image(self, img, title="Image Title", canvas=None):
28
        img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
29
        img_pil = Image.fromarray(img_rgb)
30
        img_tk = ImageTk.PhotoImage(img_pil)
31
        canvas.create_image(0, 0, anchor=tk.NW, image=img_tk)
32
        canvas.image = img_tk
33

    
34
class Commands:
35
    ## \brief A class to handle various commands related to image processing.
36
    #
37
    # The Commands class provides methods to load, display, and set overlap regions
38
    # for images using a graphical user interface (GUI) and shared data. It integrates
39
    # with an ImageIO class to handle image input and output operations.
40
    #
41
    # \author Your Name
42
    # \version 1.0
43
    # \date 2024-10-19
44

    
45
    def __init__(self, gui, shared_data):
46
        ## \brief Initializes the Commands instance.
47
        #
48
        # Sets up the GUI interface and shared data. It also initializes
49
        # an ImageIO instance for handling image operations.
50
        #
51
        # \param gui The GUI instance used for displaying images and getting user input.
52
        # \param shared_data The shared data structure that stores images and other state information.
53
        self.gui = gui
54
        self.shared_data = shared_data
55
        self.io = ImageIO(shared_data)
56

    
57
    def load_left_image(self):
58
        ## \brief Loads the left image from a file.
59
        #
60
        # Opens a file dialog for the user to select a left image file. If a valid file path
61
        # is provided, the left image is loaded into the shared data. A message is printed
62
        # to confirm the loading process.
63
        #
64
        # \warning This method does not check the file format or image content.
65
        filepath = filedialog.askopenfilename(title="Select Left Image")
66
        if filepath:
67
            self.shared_data.left_image = self.io.load_image(filepath)
68
            print("Left image loaded.")
69

    
70
    def load_right_image(self):
71
        ## \brief Loads the right image from a file.
72
        #
73
        # Opens a file dialog for the user to select a right image file. If a valid file path
74
        # is provided, the right image is loaded into the shared data. A message is printed
75
        # to confirm the loading process.
76
        #
77
        # \warning This method does not check the file format or image content.
78
        filepath = filedialog.askopenfilename(title="Select Right Image")
79
        if filepath:
80
            self.shared_data.right_image = self.io.load_image(filepath)
81
            print("Right image loaded.")
82

    
83
    def show_left_image(self):
84
        ## \brief Displays the left image on the GUI.
85
        #
86
        # If the left image is available in the shared data, it is shown on the GUI canvas.
87
        # Otherwise, an error message is displayed to the user.
88
        #
89
        # \exception Shows a message box error if no left image is loaded.
90
        if self.shared_data.left_image is not None:
91
            self.io.show_image(self.shared_data.left_image, canvas=self.gui.canvas)
92
            print("Left image displayed.")
93
        else:
94
            messagebox.showerror("Error", "No left image loaded!")
95

    
96
    def show_right_image(self):
97
        ## \brief Displays the right image on the GUI.
98
        #
99
        # If the right image is available in the shared data, it is shown on the GUI canvas.
100
        # Otherwise, an error message is displayed to the user.
101
        #
102
        # \exception Shows a message box error if no right image is loaded.
103
        if self.shared_data.right_image is not None:
104
            self.io.show_image(self.shared_data.right_image, canvas=self.gui.canvas)
105
            print("Right image displayed.")
106
        else:
107
            messagebox.showerror("Error", "No right image loaded!")
108

    
109
    def set_overlap_region(self):
110
        ## \brief Sets the overlap region for image processing.
111
        #
112
        # Retrieves the overlap region value from the GUI input and updates the shared data
113
        # accordingly. A message is printed to confirm the overlap region setting.
114
        #
115
        # \note This method assumes that the GUI input is a valid overlap region value.
116
        self.shared_data.overlap_region = self.gui.overlap.get()
117
        print(f"Overlap region set to {self.shared_data.overlap_region}")
118

    
119

    
120
class GUI:
121
    def __init__(self, master):
122
        self.master = master
123
        self.master.title("Image Projector")
124
        self.canvas = tk.Canvas(self.master, bg="black")
125
        self.canvas.pack(fill=tk.BOTH, expand=True)
126
        self.shared_data = SharedData()
127
        self.commands = Commands(self, self.shared_data)
128
        self.control_window()
129

    
130
    def control_window(self):
131
        self.control_window = tk.Toplevel(self.master)
132
        self.control_window.title("Controls")
133
        self.overlap = tk.IntVar()
134
        self.label = tk.Label(self.control_window, text='Overlap region Width', font=('calibre', 10, 'bold'))
135
        self.overlapBox = tk.Entry(self.control_window, textvariable=self.overlap)
136
        self.label.pack()
137
        self.overlapBox.pack()
138

    
139
        self.set_overlap_button = tk.Button(self.control_window, text="Set Overlap Region", command=self.commands.set_overlap_region)
140
        self.set_overlap_button.pack()
141

    
142
        self.button_load_left = tk.Button(self.control_window, text="Load Left Image", command=self.commands.load_left_image)
143
        self.button_load_left.pack()
144

    
145
        self.button_load_right = tk.Button(self.control_window, text="Load Right Image", command=self.commands.load_right_image)
146
        self.button_load_right.pack()
147

    
148
        self.button_show_left = tk.Button(self.control_window, text="Show Left Image", command=self.commands.show_left_image)
149
        self.button_show_left.pack()
150

    
151
        self.button_show_right = tk.Button(self.control_window, text="Show Right Image", command=self.commands.show_right_image)
152
        self.button_show_right.pack()
153

    
154
if __name__ == "__main__":
155
    root = tk.Tk()
156
    root.geometry("1280x800")
157
    app = GUI(root)
158
    root.mainloop()
(10-10/49)