Skip to content
Snippets Groups Projects

GDP 4.2.10 - Adding Debug mode to GUI.py to run individual modules

Merged mhby1g21 requested to merge GDP-4.2.10 into master
3 files
+ 180
243
Compare changes
  • Side-by-side
  • Inline
Files
3
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout,
QGroupBox, QMessageBox)
from PyQt6.QtCore import Qt
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')
from utils.qt_widgets import (create_group_with_text, create_button_layout,
create_info_group, create_preview_group)
from utils.file_handlers import select_file, clean_directory, copy_file, run_command
from utils.image_handlers import update_preview
class DepthTab(QWidget):
def __init__(self, config_reader):
super().__init__()
self.config_reader = config_reader
self.depth_input_path = None
# Update paths
# Initialize 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'
'Data', 'Input', 'depth_e.png'
)
self.input_dir = os.path.join(
self.config_reader.directories['edgeNetDir'],
'Data',
'Input'
'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)
main_layout = QHBoxLayout(self)
main_layout.setContentsMargins(10, 10, 10, 10)
# Left panel (controls)
left_layout = QVBoxLayout()
self.setup_control_panel(left_layout)
main_layout.addLayout(left_layout)
# Right panel (preview)
right_layout = QVBoxLayout()
self.setup_preview_panel(right_layout)
main_layout.addLayout(right_layout)
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_control_panel(self, layout):
# Info display
info_rows = [
("Input file:", "No file selected"),
("Copy destination:", self.copy_dest_path),
("Depth map output:", self.depth_output_path)
]
info_group, self.info_labels = create_info_group("Controls", info_rows)
layout.addWidget(info_group)
# Buttons
buttons = [
("Select Input", self.handle_file_select, 'left'),
("Clean Data/Input Dir", self.clean_input_dir, 'left'),
("Remove rgb.png from dest path", self.remove_rgb, 'left'),
("Copy File", self.copy_file, 'left'),
("Run Depth Est.", self.run_depth_estimation, 'left'),
("Clear Status", lambda: self.status_text.clear(), 'right')
]
layout.addLayout(create_button_layout(*buttons))
# Status display
status_group, self.status_text = create_group_with_text("Status", 150)
layout.addWidget(status_group)
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)
def setup_preview_panel(self, layout):
preview_group = QGroupBox("Image Previews")
preview_layout = QHBoxLayout(preview_group)
self.input_preview = ttk.Label(input_preview_frame)
self.input_preview.pack(padx=5, pady=5)
input_group, self.input_preview = create_preview_group("RGB Image")
output_group, self.output_preview = create_preview_group("Depth Map")
# 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)
preview_layout.addWidget(input_group)
preview_layout.addWidget(output_group)
layout.addWidget(preview_group)
def select_depth_input(self):
filepath = filedialog.askopenfilename(
filetypes=[("Image files", "*.png *.jpg *.jpeg")]
def handle_file_select(self):
file_path = select_file(
self,
"Select Input Image",
"Images (*.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')
if file_path:
self.depth_input_path = file_path
self.info_labels["Input file:"].setText(os.path.basename(file_path))
self.update_status(f"Selected input file: {file_path}")
update_preview(self.input_preview, file_path,
error_callback=self.update_status)
def update_status(self, message):
self.status_text.insert(tk.END, f"{message}\n")
self.status_text.see(tk.END)
def remove_rgb(self):
rgb_path = self.copy_dest_path
if os.path.exists(rgb_path):
os.remove(rgb_path)
self.update_status("Removed rgb.png")
else:
self.update_status("rgb.png not found")
def clear_status(self):
self.status_text.delete(1.0, tk.END)
def clean_input_dir(self):
success = clean_directory(self.input_dir, self.update_status)
if success:
self.output_preview.clear()
else:
QMessageBox.critical(self, "Error", "Failed to clean input directory")
def copy_for_depth(self):
def copy_file(self):
if not self.depth_input_path:
messagebox.showwarning("Warning", "Please select an input file first")
QMessageBox.warning(self, "Warning", "Please select an input file first")
return
# Copy to monodepth directory
if not copy_file(self.depth_input_path, self.copy_dest_path, self.update_status):
QMessageBox.critical(self, "Error", "Failed to copy file to monodepth directory")
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)
# Copy to edgenet directory
edge_rgb_path = os.path.join(self.input_dir, 'rgb.png')
if not copy_file(self.depth_input_path, edge_rgb_path, self.update_status):
QMessageBox.critical(self, "Error", "Failed to copy file to edgenet directory")
def run_depth_estimation(self):
try:
self.update_status("Running depth estimation...")
# Change to mono depth directory
# Change to mono depth directory and run script
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
success, output = run_command(
self,
"powershell.exe -File masterscript.ps1",
self.update_status
)
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}")
if success and os.path.exists(self.depth_output_path):
self.update_status(f"Depth map generated at: {self.depth_output_path}")
update_preview(self.output_preview, self.depth_output_path,
error_callback=self.update_status)
except Exception as e:
error_msg = f"Failed to run depth estimation: {str(e)}"
self.update_status(error_msg)
messagebox.showerror("Error", error_msg)
QMessageBox.critical(self, "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
def update_status(self, message):
self.status_text.append(message)
# Scroll to bottom
scrollbar = self.status_text.verticalScrollBar()
scrollbar.setValue(scrollbar.maximum())
\ No newline at end of file
Loading