diff --git a/scripts/GUI_debug.py b/scripts/GUI_debug.py deleted file mode 100644 index b72ef61c0da3b9e89e0c05ee8e62768d3a0dead5..0000000000000000000000000000000000000000 --- a/scripts/GUI_debug.py +++ /dev/null @@ -1,379 +0,0 @@ -import tkinter as tk -from tkinter import ttk, messagebox -import tkinter.filedialog -import subprocess -import sys -import os -from PIL import Image, ImageTk - -class ModuleDebugGUI: - def __init__(self): - self.window = tk.Tk() - self.window.title("Pipeline Debug Tool") - self.window.geometry("800x600") - - # Initialize paths - self.SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) - self.ROOT_DIR = os.path.dirname(self.SCRIPT_DIR) - - # Input/output paths - self.input_file_path = None - self.shifted_image_path = os.path.join(self.SCRIPT_DIR, "shifted_t.png") - - # Initialize directories and file paths - self.setup_directories() - - # Read config - self.config = {} - self.read_config() - - # Create notebook for tabs - self.notebook = ttk.Notebook(self.window) - self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) - - # Create tabs - self.setup_config_tab() - self.setup_shifter_tab() - - def setup_directories(self): - self.directories = { - 'scriptDir': self.SCRIPT_DIR, - 'rootDir': self.ROOT_DIR, - 'monoDepthDir': os.path.join(self.ROOT_DIR, "scripts", "360monodepthexecution"), - 'outputDir': os.path.join(self.ROOT_DIR, "edgenet-360", "Output"), - 'materialRecogDir': os.path.join(self.ROOT_DIR, "Dynamic-Backward-Attention-Transformer"), - 'edgeNetDir': os.path.join(self.ROOT_DIR, "edgenet-360") - } - - self.file_paths = { - 'checkpointFile': os.path.join( - self.directories['materialRecogDir'], - "checkpoints/dpglt_mode95/accuracy/epoch=126-valid_acc_epoch=0.87.ckpt" - ), - 'shiftedImage': os.path.join(self.SCRIPT_DIR, "shifted_t.png"), - 'monoDepthImage': os.path.join( - self.directories['monoDepthDir'], - "rgb.jpg" - ) - } - - def read_config(self): - config_path = os.path.join(self.SCRIPT_DIR, "config.ini") - try: - with open(config_path, 'r') as f: - for line in f: - if '=' in line: - key, value = line.strip().split('=', 1) - self.config[key.strip()] = value.strip() - except FileNotFoundError: - messagebox.showerror("Error", "config.ini not found!") - return False - return True - - def setup_config_tab(self): - config_tab = ttk.Frame(self.notebook) - self.notebook.add(config_tab, text='Configuration Check') - - # Config section - config_frame = ttk.LabelFrame(config_tab, text="Config Values", padding="5") - config_frame.pack(fill=tk.X, pady=5, padx=5) - - self.config_text = tk.Text(config_frame, height=6, wrap=tk.WORD) - self.config_text.pack(fill=tk.X) - - # Directory paths section - dir_frame = ttk.LabelFrame(config_tab, text="Directory Paths", padding="5") - dir_frame.pack(fill=tk.X, pady=5, padx=5) - - self.dir_text = tk.Text(dir_frame, height=8, wrap=tk.WORD) - self.dir_text.pack(fill=tk.X) - - # File paths section - file_frame = ttk.LabelFrame(config_tab, text="File Paths", padding="5") - file_frame.pack(fill=tk.X, pady=5, padx=5) - - self.file_text = tk.Text(file_frame, height=5, wrap=tk.WORD) - self.file_text.pack(fill=tk.X) - - # Path verification section - verify_frame = ttk.LabelFrame(config_tab, text="Path Verification", padding="5") - verify_frame.pack(fill=tk.X, pady=5, padx=5) - - self.verify_text = tk.Text(verify_frame, height=8, wrap=tk.WORD) - self.verify_text.pack(fill=tk.X) - - # Buttons - button_frame = ttk.Frame(config_tab) - button_frame.pack(fill=tk.X, pady=5, padx=5) - - ttk.Button( - button_frame, - text="Refresh Config", - command=self.refresh_all - ).pack(side=tk.LEFT, padx=5) - - ttk.Button( - button_frame, - text="Verify Paths", - command=self.verify_paths - ).pack(side=tk.LEFT, padx=5) - - ttk.Button( - button_frame, - text="Save Debug Info", - command=self.save_debug_info - ).pack(side=tk.RIGHT, padx=5) - - # Initial display - self.refresh_all() - - def setup_shifter_tab(self): - shifter_tab = ttk.Frame(self.notebook) - self.notebook.add(shifter_tab, text='Image Shifter') - - # Split into left and right frames - left_frame = ttk.Frame(shifter_tab) - left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) - - right_frame = ttk.Frame(shifter_tab) - right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5) - - # Control section (left frame) - control_frame = ttk.LabelFrame(left_frame, text="Controls", padding="5") - control_frame.pack(fill=tk.X, pady=5) - - # Input file selection - input_frame = ttk.Frame(control_frame) - input_frame.pack(fill=tk.X, pady=5) - - self.input_label = ttk.Label(input_frame, text="No input file selected") - self.input_label.pack(side=tk.LEFT, padx=5) - - ttk.Button( - input_frame, - text="Select Input File", - command=self.select_input_file - ).pack(side=tk.RIGHT, padx=5) - - # Output file display - output_frame = ttk.Frame(control_frame) - output_frame.pack(fill=tk.X, pady=5) - - ttk.Label(output_frame, text="Output will be saved as:").pack(side=tk.LEFT, padx=5) - self.output_label = ttk.Label(output_frame, text=os.path.basename(self.shifted_image_path)) - self.output_label.pack(side=tk.LEFT, padx=5) - - # Environment info - env_frame = ttk.Frame(control_frame) - env_frame.pack(fill=tk.X, pady=5) - - ttk.Label(env_frame, text="Using conda environment:").pack(side=tk.LEFT, padx=5) - self.env_label = ttk.Label(env_frame, text=self.config.get('materialEnv', 'Not found')) - self.env_label.pack(side=tk.LEFT, padx=5) - - # Control buttons - button_frame = ttk.Frame(control_frame) - button_frame.pack(fill=tk.X, pady=5) - - ttk.Button( - button_frame, - text="Run Image Shifter", - command=self.run_shifter - ).pack(side=tk.RIGHT, padx=5) - - ttk.Button( - button_frame, - text="Clear Status", - command=self.clear_status - ).pack(side=tk.RIGHT, padx=5) - - # Image preview section (right frame) - preview_frame = ttk.LabelFrame(right_frame, text="Image Preview", padding="5") - preview_frame.pack(fill=tk.BOTH, expand=True) - - # Input image preview - input_preview_frame = ttk.LabelFrame(preview_frame, text="Input Image") - input_preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) - - self.input_preview = ttk.Label(input_preview_frame) - self.input_preview.pack(padx=5, pady=5) - - # Output image preview - output_preview_frame = ttk.LabelFrame(preview_frame, text="Shifted Image") - output_preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) - - self.output_preview = ttk.Label(output_preview_frame) - self.output_preview.pack(padx=5, pady=5) - - # Status section at the bottom of left frame - status_frame = ttk.LabelFrame(left_frame, text="Status", padding="5") - status_frame.pack(fill=tk.BOTH, expand=True, pady=5) - - # Add scrollbar to status - status_scroll = ttk.Scrollbar(status_frame) - status_scroll.pack(side=tk.RIGHT, fill=tk.Y) - - self.status_text = tk.Text(status_frame, height=10, wrap=tk.WORD, yscrollcommand=status_scroll.set) - self.status_text.pack(fill=tk.BOTH, expand=True) - status_scroll.config(command=self.status_text.yview) - - # Add these new methods to handle image preview - def update_image_preview(self): - preview_size = (300, 300) # Adjust size as needed - - # Update input image preview if exists - if self.input_file_path and os.path.exists(self.input_file_path): - try: - input_img = Image.open(self.input_file_path) - input_img.thumbnail(preview_size) - input_photo = ImageTk.PhotoImage(input_img) - self.input_preview.configure(image=input_photo) - self.input_preview.image = input_photo # Keep a reference - except Exception as e: - self.update_status(f"Failed to load input image preview: {str(e)}") - - # Update output image preview if exists - if os.path.exists(self.shifted_image_path): - try: - output_img = Image.open(self.shifted_image_path) - output_img.thumbnail(preview_size) - output_photo = ImageTk.PhotoImage(output_img) - self.output_preview.configure(image=output_photo) - self.output_preview.image = output_photo # Keep a reference - except Exception as e: - self.update_status(f"Failed to load output image preview: {str(e)}") - - def refresh_all(self): - self.refresh_config_display() - self.refresh_directory_display() - self.refresh_file_display() - self.verify_paths() - - def refresh_config_display(self): - self.config_text.delete(1.0, tk.END) - for key, value in self.config.items(): - self.config_text.insert(tk.END, f"{key} = {value}\n") - - def refresh_directory_display(self): - self.dir_text.delete(1.0, tk.END) - for key, path in self.directories.items(): - self.dir_text.insert(tk.END, f"{key}: {path}\n") - - def refresh_file_display(self): - self.file_text.delete(1.0, tk.END) - for key, path in self.file_paths.items(): - self.file_text.insert(tk.END, f"{key}: {path}\n") - - def verify_paths(self): - self.verify_text.delete(1.0, tk.END) - - # Verify directories - self.verify_text.insert(tk.END, "Directory Verification:\n") - for key, path in self.directories.items(): - exists = os.path.exists(path) - status = "✓ exists" if exists else "✗ missing" - color = "green" if exists else "red" - self.verify_text.insert(tk.END, f"{key}: {status}\n", color) - - self.verify_text.insert(tk.END, "\nFile Verification:\n") - for key, path in self.file_paths.items(): - exists = os.path.exists(path) - status = "✓ exists" if exists else "✗ missing" - color = "green" if exists else "red" - self.verify_text.insert(tk.END, f"{key}: {status}\n", color) - - # Add tags for colors - self.verify_text.tag_config("green", foreground="green") - self.verify_text.tag_config("red", foreground="red") - - def select_input_file(self): - self.input_file_path = tkinter.filedialog.askopenfilename( - filetypes=[("Image files", "*.png *.jpg *.jpeg")] - ) - if self.input_file_path: - self.input_file_path = os.path.normpath(self.input_file_path) - self.input_label.config(text=os.path.basename(self.input_file_path)) - self.update_status(f"Selected input file: {self.input_file_path}") - self.update_image_preview() - - def update_status(self, message): - self.status_text.insert(tk.END, f"{message}\n") - self.status_text.see(tk.END) - - def clear_status(self): - self.status_text.delete(1.0, tk.END) - - def save_debug_info(self): - debug_info = "=== Pipeline Debug Information ===\n\n" - - debug_info += "=== Config Values ===\n" - for key, value in self.config.items(): - debug_info += f"{key} = {value}\n" - - debug_info += "\n=== Directory Paths ===\n" - for key, path in self.directories.items(): - exists = os.path.exists(path) - status = "exists" if exists else "missing" - debug_info += f"{key}: {path} ({status})\n" - - debug_info += "\n=== File Paths ===\n" - for key, path in self.file_paths.items(): - exists = os.path.exists(path) - status = "exists" if exists else "missing" - debug_info += f"{key}: {path} ({status})\n" - - try: - with open("pipeline_debug_info.txt", "w") as f: - f.write(debug_info) - messagebox.showinfo("Success", "Debug information saved to pipeline_debug_info.txt") - except Exception as e: - messagebox.showerror("Error", f"Failed to save debug info: {str(e)}") - - def run_shifter(self): - if not self.input_file_path: - messagebox.showwarning("Warning", "Please select an input file first") - return - - self.update_status("\nRunning image shifter...") - - try: - # Construct the command - cmd = f'''call "{self.config["condaDir"]}\\condabin\\activate.bat" {self.config["materialEnv"]} && python "{os.path.join(self.SCRIPT_DIR, "shifter.py")}" "{self.input_file_path}" "{self.shifted_image_path}" && call "{self.config["condaDir"]}\\condabin\\deactivate.bat"''' - - # Run the command - self.update_status(f"Executing command:\n{cmd}\n") - - process = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=True, - text=True - ) - stdout, stderr = process.communicate() - - if process.returncode == 0: - self.update_status("Image shifter completed successfully") - if stdout: - self.update_status("Output:\n" + stdout) - - if os.path.exists(self.shifted_image_path): - self.update_status(f"Shifted image saved to: {self.shifted_image_path}") - self.update_image_preview() # Update the preview after successful completion - else: - self.update_status("Warning: Output file not found!") - else: - self.update_status("Image shifter failed with error:\n" + stderr) - messagebox.showerror("Error", f"Command failed:\n\n{stderr}") - - except Exception as e: - error_msg = f"Failed to run image shifter: {str(e)}" - self.update_status(error_msg) - messagebox.showerror("Error", error_msg) - - def run(self): - self.window.mainloop() - -if __name__ == "__main__": - app = ModuleDebugGUI() - app.run() \ No newline at end of file diff --git a/scripts/debug_tool/GUI_debug.py b/scripts/debug_tool/GUI_debug.py new file mode 100644 index 0000000000000000000000000000000000000000..0a68948d196819a145052340f5955f9d7fb728a7 --- /dev/null +++ b/scripts/debug_tool/GUI_debug.py @@ -0,0 +1,38 @@ +import tkinter as tk +from tkinter import ttk +import os + +from tabs.config_tab import ConfigTab +from tabs.shifter_tab import ShifterTab +from tabs.depth_tab import DepthTab +from utils.config_reader import ConfigReader + +class ModuleDebugGUI: + def __init__(self): + self.window = tk.Tk() + self.window.title("Pipeline Debug Tool") + self.window.geometry("800x600") + + # Initialize paths + self.DEBUG_DIR = os.path.dirname(os.path.abspath(__file__)) # debug_tool directory + self.SCRIPT_DIR = os.path.dirname(self.DEBUG_DIR) # scripts directory + self.ROOT_DIR = os.path.dirname(self.SCRIPT_DIR) + + # Read configuration + self.config_reader = ConfigReader(self.DEBUG_DIR, self.ROOT_DIR) + + # Create notebook for tabs + self.notebook = ttk.Notebook(self.window) + self.notebook.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) + + # Initialize tabs + self.config_tab = ConfigTab(self.notebook, self.config_reader) + self.shifter_tab = ShifterTab(self.notebook, self.config_reader) + self.depth_tab = DepthTab(self.notebook, self.config_reader) + + def run(self): + self.window.mainloop() + +if __name__ == "__main__": + app = ModuleDebugGUI() + app.run() \ No newline at end of file diff --git a/scripts/debug_tool/__init__.py b/scripts/debug_tool/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/debug_tool/tabs/__init__.py b/scripts/debug_tool/tabs/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/debug_tool/tabs/config_tab.py b/scripts/debug_tool/tabs/config_tab.py new file mode 100644 index 0000000000000000000000000000000000000000..22c6008cec4976c996c85962ca49a6469c883405 --- /dev/null +++ b/scripts/debug_tool/tabs/config_tab.py @@ -0,0 +1,142 @@ +import tkinter as tk +from tkinter import ttk, messagebox +import os + +class ConfigTab: + def __init__(self, notebook, config_reader): + self.tab = ttk.Frame(notebook) + notebook.add(self.tab, text='Configuration Check') + + self.config_reader = config_reader + self.setup_ui() + + def setup_ui(self): + # Main container with padding + main_frame = ttk.Frame(self.tab, padding="10") + main_frame.pack(fill=tk.BOTH, expand=True) + + # Config section + config_frame = ttk.LabelFrame(main_frame, text="Config Values", padding="5") + config_frame.pack(fill=tk.X, pady=5) + + self.config_text = tk.Text(config_frame, height=6, wrap=tk.WORD) + self.config_text.pack(fill=tk.X) + + # Directory paths section + dir_frame = ttk.LabelFrame(main_frame, text="Directory Paths", padding="5") + dir_frame.pack(fill=tk.X, pady=5) + + self.dir_text = tk.Text(dir_frame, height=8, wrap=tk.WORD) + self.dir_text.pack(fill=tk.X) + + # File paths section + file_frame = ttk.LabelFrame(main_frame, text="File Paths", padding="5") + file_frame.pack(fill=tk.X, pady=5) + + self.file_text = tk.Text(file_frame, height=5, wrap=tk.WORD) + self.file_text.pack(fill=tk.X) + + # Path verification section + verify_frame = ttk.LabelFrame(main_frame, text="Path Verification", padding="5") + verify_frame.pack(fill=tk.X, pady=5) + + self.verify_text = tk.Text(verify_frame, height=8, wrap=tk.WORD) + self.verify_text.pack(fill=tk.X) + + # Buttons + button_frame = ttk.Frame(main_frame) + button_frame.pack(fill=tk.X, pady=5) + + ttk.Button( + button_frame, + text="Refresh Config", + command=self.refresh_all + ).pack(side=tk.LEFT, padx=5) + + ttk.Button( + button_frame, + text="Verify Paths", + command=self.verify_paths + ).pack(side=tk.LEFT, padx=5) + + ttk.Button( + button_frame, + text="Save Debug Info", + command=self.save_debug_info + ).pack(side=tk.RIGHT, padx=5) + + # Initial display + self.refresh_all() + + def refresh_all(self): + self.refresh_config_display() + self.refresh_directory_display() + self.refresh_file_display() + self.verify_paths() + + def refresh_config_display(self): + self.config_text.delete(1.0, tk.END) + for key, value in self.config_reader.config.items(): + self.config_text.insert(tk.END, f"{key} = {value}\n") + + def refresh_directory_display(self): + self.dir_text.delete(1.0, tk.END) + for key, path in self.config_reader.directories.items(): + self.dir_text.insert(tk.END, f"{key}: {path}\n") + + def refresh_file_display(self): + self.file_text.delete(1.0, tk.END) + for key, path in self.config_reader.file_paths.items(): + self.file_text.insert(tk.END, f"{key}: {path}\n") + + def verify_paths(self): + self.verify_text.delete(1.0, tk.END) + + # Verify directories + self.verify_text.insert(tk.END, "Directory Verification:\n") + for key, path in self.config_reader.directories.items(): + exists = os.path.exists(path) + status = "✓ exists" if exists else "✗ missing" + color = "green" if exists else "red" + self.verify_text.insert(tk.END, f"{key}: {status}\n", color) + + self.verify_text.insert(tk.END, "\nFile Verification:\n") + for key, path in self.config_reader.file_paths.items(): + exists = os.path.exists(path) + status = "✓ exists" if exists else "✗ missing" + color = "green" if exists else "red" + self.verify_text.insert(tk.END, f"{key}: {status}\n", color) + + # Add tags for colors + self.verify_text.tag_config("green", foreground="green") + self.verify_text.tag_config("red", foreground="red") + + def save_debug_info(self): + debug_info = "=== Pipeline Debug Information ===\n\n" + + debug_info += "=== Config Values ===\n" + for key, value in self.config_reader.config.items(): + debug_info += f"{key} = {value}\n" + + debug_info += "\n=== Directory Paths ===\n" + for key, path in self.config_reader.directories.items(): + exists = os.path.exists(path) + status = "exists" if exists else "missing" + debug_info += f"{key}: {path} ({status})\n" + + debug_info += "\n=== File Paths ===\n" + for key, path in self.config_reader.file_paths.items(): + exists = os.path.exists(path) + status = "exists" if exists else "missing" + debug_info += f"{key}: {path} ({status})\n" + + # Save to debug tool directory + try: + debug_path = os.path.join(self.config_reader.directories['debugDir'], + "pipeline_debug_info.txt") + with open(debug_path, "w") as f: + f.write(debug_info) + messagebox.showinfo("Success", + f"Debug information saved to:\n{debug_path}") + except Exception as e: + messagebox.showerror("Error", f"Failed to save debug info: {str(e)}") \ No newline at end of file diff --git a/scripts/debug_tool/tabs/depth_tab.py b/scripts/debug_tool/tabs/depth_tab.py new file mode 100644 index 0000000000000000000000000000000000000000..62b81b2d065fe4343bc3069e33e39ea1af5a0108 --- /dev/null +++ b/scripts/debug_tool/tabs/depth_tab.py @@ -0,0 +1,290 @@ +import tkinter as tk +from tkinter import ttk, messagebox, filedialog +import os +from PIL import Image, ImageTk +import subprocess +import shutil + +class DepthTab: + def __init__(self, notebook, config_reader): + self.tab = ttk.Frame(notebook) + notebook.add(self.tab, text='Depth Estimation') + + self.config_reader = config_reader + self.depth_input_path = None + + # Update paths + self.copy_dest_path = os.path.join( + self.config_reader.directories['monoDepthDir'], + 'rgb.jpg' + ) + self.depth_output_path = os.path.join( + self.config_reader.directories['edgeNetDir'], + 'Data', + 'Input', + 'depth_e.png' + ) + self.input_dir = os.path.join( + self.config_reader.directories['edgeNetDir'], + 'Data', + 'Input' + ) + + self.setup_ui() + + def setup_ui(self): + # Split into left and right frames + left_frame = ttk.Frame(self.tab) + left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) + + right_frame = ttk.Frame(self.tab) + right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5) + + self.setup_control_panel(left_frame) + self.setup_preview_panel(right_frame) + + def setup_control_panel(self, parent): + # Control section + control_frame = ttk.LabelFrame(parent, text="Controls", padding="5") + control_frame.pack(fill=tk.X, pady=5) + + # Input file selection + input_frame = ttk.Frame(control_frame) + input_frame.pack(fill=tk.X, pady=5) + + ttk.Label(input_frame, text="Input file:").pack(side=tk.LEFT, padx=5) + self.input_label = ttk.Label(input_frame, text="No file selected") + self.input_label.pack(side=tk.LEFT, padx=5) + + # Copy destination display + copy_frame = ttk.Frame(control_frame) + copy_frame.pack(fill=tk.X, pady=5) + + ttk.Label(copy_frame, text="Will be copied to:").pack(side=tk.LEFT, padx=5) + self.copy_dest_label = ttk.Label(copy_frame, text=self.copy_dest_path) + self.copy_dest_label.pack(side=tk.LEFT, padx=5) + + # Output path display + output_frame = ttk.Frame(control_frame) + output_frame.pack(fill=tk.X, pady=5) + + ttk.Label(output_frame, text="Depth map will be saved to:").pack(side=tk.LEFT, padx=5) + self.output_label = ttk.Label(output_frame, text=self.depth_output_path) + self.output_label.pack(side=tk.LEFT, padx=5) + + # Control buttons + button_frame = ttk.Frame(control_frame) + button_frame.pack(fill=tk.X, pady=5) + + ttk.Button( + button_frame, + text="Select Input", + command=self.select_depth_input + ).pack(side=tk.LEFT, padx=5) + + ttk.Button( + button_frame, + text="Clean Input Directory", + command=self.clean_input_directory + ).pack(side=tk.LEFT, padx=5) + + ttk.Button( + button_frame, + text="Copy File", + command=self.copy_for_depth + ).pack(side=tk.LEFT, padx=5) + + self.run_depth_btn = ttk.Button( + button_frame, + text="Run Depth Estimation", + command=self.run_depth_estimation, + state='disabled' # Initially disabled until file is copied + ) + self.run_depth_btn.pack(side=tk.LEFT, padx=5) + + ttk.Button( + button_frame, + text="Clear Status", + command=self.clear_status + ).pack(side=tk.RIGHT, padx=5) + + # Status section + status_frame = ttk.LabelFrame(parent, text="Status", padding="5") + status_frame.pack(fill=tk.BOTH, expand=True, pady=5) + + # Add scrollbar to status + status_scroll = ttk.Scrollbar(status_frame) + status_scroll.pack(side=tk.RIGHT, fill=tk.Y) + + self.status_text = tk.Text( + status_frame, + height=10, + wrap=tk.WORD, + yscrollcommand=status_scroll.set + ) + self.status_text.pack(fill=tk.BOTH, expand=True) + status_scroll.config(command=self.status_text.yview) + + def setup_preview_panel(self, parent): + preview_frame = ttk.LabelFrame(parent, text="Image Preview", padding="5") + preview_frame.pack(fill=tk.BOTH, expand=True) + + # Input image preview + input_preview_frame = ttk.LabelFrame(preview_frame, text="RGB Image") + input_preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) + + self.input_preview = ttk.Label(input_preview_frame) + self.input_preview.pack(padx=5, pady=5) + + # Output depth preview + output_preview_frame = ttk.LabelFrame(preview_frame, text="Depth Map") + output_preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) + + self.output_preview = ttk.Label(output_preview_frame) + self.output_preview.pack(padx=5, pady=5) + + def clean_input_directory(self): + """Clean the edgenet input directory of any existing files""" + try: + if not os.path.exists(self.input_dir): + os.makedirs(self.input_dir) + self.update_status(f"Created input directory: {self.input_dir}") + return + + # List all files in the directory + files = os.listdir(self.input_dir) + if not files: + self.update_status("Input directory is already empty") + return + + # Remove each file + for file in files: + file_path = os.path.join(self.input_dir, file) + try: + if os.path.isfile(file_path): + os.remove(file_path) + elif os.path.isdir(file_path): + shutil.rmtree(file_path) + except Exception as e: + self.update_status(f"Error removing {file}: {str(e)}") + + self.update_status("Input directory cleaned successfully") + + # Clear the output preview as the depth map is now removed + self.output_preview.configure(image='') + + except Exception as e: + error_msg = f"Failed to clean input directory: {str(e)}" + self.update_status(error_msg) + messagebox.showerror("Error", error_msg) + + def select_depth_input(self): + filepath = filedialog.askopenfilename( + filetypes=[("Image files", "*.png *.jpg *.jpeg")] + ) + if filepath: + self.depth_input_path = os.path.normpath(filepath) + self.input_label.config(text=os.path.basename(filepath)) + self.update_status(f"Selected input file: {filepath}") + self.update_depth_preview() + + # Reset button state + self.run_depth_btn.config(state='disabled') + + def update_status(self, message): + self.status_text.insert(tk.END, f"{message}\n") + self.status_text.see(tk.END) + + def clear_status(self): + self.status_text.delete(1.0, tk.END) + + def copy_for_depth(self): + if not self.depth_input_path: + messagebox.showwarning("Warning", "Please select an input file first") + return + + try: + # Create directories if they don't exist + os.makedirs(self.config_reader.directories['monoDepthDir'], exist_ok=True) + os.makedirs(self.input_dir, exist_ok=True) + + # Copy file + shutil.copy2(self.depth_input_path, self.copy_dest_path) + + # Also copy to edgenet input directory as rgb.png + rgb_copy_path = os.path.join(self.input_dir, 'rgb.png') + shutil.copy2(self.depth_input_path, rgb_copy_path) + + self.update_status(f"Successfully copied file to:\n{self.copy_dest_path}\n{rgb_copy_path}") + self.run_depth_btn.config(state='normal') # Enable depth estimation button + + except Exception as e: + error_msg = f"Failed to copy file: {str(e)}" + self.update_status(error_msg) + messagebox.showerror("Error", error_msg) + + def run_depth_estimation(self): + try: + self.update_status("Running depth estimation...") + + # Change to mono depth directory + original_dir = os.getcwd() + os.chdir(self.config_reader.directories['monoDepthDir']) + + # Run PowerShell script + process = subprocess.Popen( + ["powershell.exe", "-File", "masterscript.ps1"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True + ) + + stdout, stderr = process.communicate() + + # Change back to original directory + os.chdir(original_dir) + + if process.returncode == 0: + self.update_status("Depth estimation completed successfully") + if stdout: + self.update_status("Output:\n" + stdout) + + # Check for depth map in the correct location + if os.path.exists(self.depth_output_path): + self.update_status(f"Depth map generated at: {self.depth_output_path}") + self.update_depth_preview() + else: + self.update_status("Warning: Depth map not found at expected location") + else: + self.update_status("Depth estimation failed with error:\n" + stderr) + messagebox.showerror("Error", f"Command failed:\n\n{stderr}") + + except Exception as e: + error_msg = f"Failed to run depth estimation: {str(e)}" + self.update_status(error_msg) + messagebox.showerror("Error", error_msg) + + def update_depth_preview(self): + preview_size = (300, 300) # Adjust size as needed + + # Update input preview + if self.depth_input_path and os.path.exists(self.depth_input_path): + try: + input_img = Image.open(self.depth_input_path) + input_img.thumbnail(preview_size) + input_photo = ImageTk.PhotoImage(input_img) + self.input_preview.configure(image=input_photo) + self.input_preview.image = input_photo + except Exception as e: + self.update_status(f"Failed to load input preview: {str(e)}") + + # Update depth map preview if exists + if os.path.exists(self.depth_output_path): + try: + depth_img = Image.open(self.depth_output_path) + depth_img.thumbnail(preview_size) + depth_photo = ImageTk.PhotoImage(depth_img) + self.output_preview.configure(image=depth_photo) + self.output_preview.image = depth_photo + except Exception as e: + self.update_status(f"Failed to load depth map preview: {str(e)}") \ No newline at end of file diff --git a/scripts/debug_tool/tabs/shifter_tab.py b/scripts/debug_tool/tabs/shifter_tab.py new file mode 100644 index 0000000000000000000000000000000000000000..0ec621d0560f5c460f7b7934c097845c0c52b757 --- /dev/null +++ b/scripts/debug_tool/tabs/shifter_tab.py @@ -0,0 +1,226 @@ +import tkinter as tk +from tkinter import ttk, messagebox, filedialog +import os +from PIL import Image, ImageTk +import subprocess + +class ShifterTab: + def __init__(self, notebook, config_reader): + self.tab = ttk.Frame(notebook) + notebook.add(self.tab, text='Image Shifter') + + self.config_reader = config_reader + self.input_file_path = None + self.shifted_image_path = os.path.join( + self.config_reader.directories['scriptDir'], + "shifted_t.png" + ) + + self.setup_ui() + + def setup_ui(self): + # Split into left and right frames + left_frame = ttk.Frame(self.tab) + left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5) + + right_frame = ttk.Frame(self.tab) + right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5) + + self.setup_control_panel(left_frame) + self.setup_preview_panel(right_frame) + + def setup_control_panel(self, parent): + # Control section + control_frame = ttk.LabelFrame(parent, text="Controls", padding="5") + control_frame.pack(fill=tk.X, pady=5) + + # Input file selection + input_frame = ttk.Frame(control_frame) + input_frame.pack(fill=tk.X, pady=5) + + ttk.Label(input_frame, text="Input file:").pack(side=tk.LEFT, padx=5) + self.input_label = ttk.Label(input_frame, text="No file selected") + self.input_label.pack(side=tk.LEFT, padx=5) + + ttk.Button( + input_frame, + text="Select Input File", + command=self.select_input_file + ).pack(side=tk.RIGHT, padx=5) + + # Output file display + output_frame = ttk.Frame(control_frame) + output_frame.pack(fill=tk.X, pady=5) + + ttk.Label(output_frame, text="Output will be saved as:").pack(side=tk.LEFT, padx=5) + self.output_label = ttk.Label( + output_frame, + text=self.shifted_image_path + ) + self.output_label.pack(side=tk.LEFT, padx=5) + + # Environment info + env_frame = ttk.Frame(control_frame) + env_frame.pack(fill=tk.X, pady=5) + + ttk.Label(env_frame, text="Using conda environment:").pack(side=tk.LEFT, padx=5) + self.env_label = ttk.Label( + env_frame, + text=self.config_reader.config.get('materialEnv', 'Not found') + ) + self.env_label.pack(side=tk.LEFT, padx=5) + + # Command preview + cmd_frame = ttk.LabelFrame(parent, text="Command Preview", padding="5") + cmd_frame.pack(fill=tk.X, pady=5) + + self.cmd_text = tk.Text(cmd_frame, height=3, wrap=tk.WORD) + self.cmd_text.pack(fill=tk.X) + self.update_command_preview() + + # Control buttons + button_frame = ttk.Frame(control_frame) + button_frame.pack(fill=tk.X, pady=5) + + ttk.Button( + button_frame, + text="Run Shifter", + command=self.run_shifter + ).pack(side=tk.LEFT, padx=5) + + ttk.Button( + button_frame, + text="Clear Status", + command=self.clear_status + ).pack(side=tk.RIGHT, padx=5) + + # Status section + status_frame = ttk.LabelFrame(parent, text="Status", padding="5") + status_frame.pack(fill=tk.BOTH, expand=True, pady=5) + + # Add scrollbar to status + status_scroll = ttk.Scrollbar(status_frame) + status_scroll.pack(side=tk.RIGHT, fill=tk.Y) + + self.status_text = tk.Text( + status_frame, + height=10, + wrap=tk.WORD, + yscrollcommand=status_scroll.set + ) + self.status_text.pack(fill=tk.BOTH, expand=True) + status_scroll.config(command=self.status_text.yview) + + def setup_preview_panel(self, parent): + preview_frame = ttk.LabelFrame(parent, text="Image Preview", padding="5") + preview_frame.pack(fill=tk.BOTH, expand=True) + + # Input image preview + input_preview_frame = ttk.LabelFrame(preview_frame, text="Input Image") + input_preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) + + self.input_preview = ttk.Label(input_preview_frame) + self.input_preview.pack(padx=5, pady=5) + + # Output image preview + output_preview_frame = ttk.LabelFrame(preview_frame, text="Shifted Image") + output_preview_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5) + + self.output_preview = ttk.Label(output_preview_frame) + self.output_preview.pack(padx=5, pady=5) + + def update_command_preview(self): + if not self.input_file_path: + self.cmd_text.delete(1.0, tk.END) + self.cmd_text.insert(tk.END, "Select an input file to see the command") + return + + cmd = f'''call "{self.config_reader.config["condaDir"]}\\condabin\\activate.bat" {self.config_reader.config["materialEnv"]} && python "{os.path.join(self.config_reader.directories['scriptDir'], "shifter.py")}" "{self.input_file_path}" "{self.shifted_image_path}" && call "{self.config_reader.config["condaDir"]}\\condabin\\deactivate.bat"''' + + self.cmd_text.delete(1.0, tk.END) + self.cmd_text.insert(tk.END, cmd) + + def select_input_file(self): + filepath = filedialog.askopenfilename( + filetypes=[("Image files", "*.png *.jpg *.jpeg")] + ) + if filepath: + self.input_file_path = os.path.normpath(filepath) + self.input_label.config(text=os.path.basename(filepath)) + self.update_status(f"Selected input file: {filepath}") + self.update_command_preview() + self.update_image_preview() + + def update_status(self, message): + self.status_text.insert(tk.END, f"{message}\n") + self.status_text.see(tk.END) + + def clear_status(self): + self.status_text.delete(1.0, tk.END) + + def run_shifter(self): + if not self.input_file_path: + messagebox.showwarning("Warning", "Please select an input file first") + return + + self.update_status("\nRunning image shifter...") + + try: + # Construct the command + cmd = f'''call "{self.config_reader.config["condaDir"]}\\condabin\\activate.bat" {self.config_reader.config["materialEnv"]} && python "{os.path.join(self.config_reader.directories['scriptDir'], "shifter.py")}" "{self.input_file_path}" "{self.shifted_image_path}" && call "{self.config_reader.config["condaDir"]}\\condabin\\deactivate.bat"''' + + # Run the command + self.update_status(f"Executing command:\n{cmd}\n") + + process = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True, + text=True + ) + stdout, stderr = process.communicate() + + if process.returncode == 0: + self.update_status("Image shifter completed successfully") + if stdout: + self.update_status("Output:\n" + stdout) + + if os.path.exists(self.shifted_image_path): + self.update_status(f"Shifted image saved to: {self.shifted_image_path}") + self.update_image_preview() + else: + self.update_status("Warning: Output file not found!") + else: + self.update_status("Image shifter failed with error:\n" + stderr) + messagebox.showerror("Error", f"Command failed:\n\n{stderr}") + + except Exception as e: + error_msg = f"Failed to run image shifter: {str(e)}" + self.update_status(error_msg) + messagebox.showerror("Error", error_msg) + + def update_image_preview(self): + preview_size = (300, 300) # Adjust size as needed + + # Update input image preview if exists + if self.input_file_path and os.path.exists(self.input_file_path): + try: + input_img = Image.open(self.input_file_path) + input_img.thumbnail(preview_size) + input_photo = ImageTk.PhotoImage(input_img) + self.input_preview.configure(image=input_photo) + self.input_preview.image = input_photo # Keep a reference + except Exception as e: + self.update_status(f"Failed to load input preview: {str(e)}") + + # Update shifted image preview if exists + if os.path.exists(self.shifted_image_path): + try: + output_img = Image.open(self.shifted_image_path) + output_img.thumbnail(preview_size) + output_photo = ImageTk.PhotoImage(output_img) + self.output_preview.configure(image=output_photo) + self.output_preview.image = output_photo # Keep a reference + except Exception as e: + self.update_status(f"Failed to load shifted image preview: {str(e)}") \ No newline at end of file diff --git a/scripts/debug_tool/utils/_init__.py b/scripts/debug_tool/utils/_init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/debug_tool/utils/config_reader.py b/scripts/debug_tool/utils/config_reader.py new file mode 100644 index 0000000000000000000000000000000000000000..6101e9127f52cf234a1cba1cbd1246122b76af44 --- /dev/null +++ b/scripts/debug_tool/utils/config_reader.py @@ -0,0 +1,50 @@ +import os + +class ConfigReader: + def __init__(self, script_dir, root_dir): + self.SCRIPT_DIR = script_dir # debug_tool directory + self.PIPELINE_DIR = os.path.dirname(script_dir) # scripts directory + self.ROOT_DIR = root_dir + + # Read from pipeline's config.ini + self.config = self.read_config() + self.directories = self.setup_directories() + self.file_paths = self.setup_file_paths() + + def read_config(self): + config = {} + # Use config.ini from scripts directory + config_path = os.path.join(self.PIPELINE_DIR, "config.ini") + try: + with open(config_path, 'r') as f: + for line in f: + if '=' in line: + key, value = line.strip().split('=', 1) + config[key.strip()] = value.strip() + except FileNotFoundError: + raise Exception(f"config.ini not found in {self.PIPELINE_DIR}") + return config + + def setup_directories(self): + return { + 'scriptDir': self.PIPELINE_DIR, # Point to scripts directory + 'debugDir': self.SCRIPT_DIR, # debug_tool directory + 'rootDir': self.ROOT_DIR, + 'monoDepthDir': os.path.join(self.ROOT_DIR, "scripts", "360monodepthexecution"), + 'outputDir': os.path.join(self.ROOT_DIR, "edgenet-360", "Output"), + 'materialRecogDir': os.path.join(self.ROOT_DIR, "Dynamic-Backward-Attention-Transformer"), + 'edgeNetDir': os.path.join(self.ROOT_DIR, "edgenet-360") + } + + def setup_file_paths(self): + return { + 'checkpointFile': os.path.join( + self.directories['materialRecogDir'], + "checkpoints/dpglt_mode95/accuracy/epoch=126-valid_acc_epoch=0.87.ckpt" + ), + 'shiftedImage': os.path.join(self.PIPELINE_DIR, "shifted_t.png"), # Use scripts directory + 'monoDepthImage': os.path.join( + self.directories['monoDepthDir'], + "rgb.jpg" + ) + } \ No newline at end of file diff --git a/scripts/debug_tool/utils/image_utils.py b/scripts/debug_tool/utils/image_utils.py new file mode 100644 index 0000000000000000000000000000000000000000..740992a711d5d2bdf00dc2d2d759a31530f5dc0b --- /dev/null +++ b/scripts/debug_tool/utils/image_utils.py @@ -0,0 +1,24 @@ +from PIL import Image, ImageTk +import os + +def create_preview(image_path, size=(300, 300)): + """Create a thumbnail preview of the given image""" + try: + if not os.path.exists(image_path): + raise FileNotFoundError(f"Image file not found: {image_path}") + + img = Image.open(image_path) + img.thumbnail(size) + return ImageTk.PhotoImage(img) + except Exception as e: + raise Exception(f"Failed to create image preview: {str(e)}") + +def verify_image(image_path): + """Verify that an image file exists and can be opened""" + try: + if not os.path.exists(image_path): + return False + Image.open(image_path) + return True + except: + return False \ No newline at end of file