Skip to content
Snippets Groups Projects
Commit 2248f5aa authored by mhby1g21's avatar mhby1g21
Browse files

refactored monodepth tab

parent 2260f0dd
No related branches found
No related tags found
1 merge request!4GDP 4.2.10 - Adding Debug mode to GUI.py to run individual modules
This commit is part of merge request !4. Comments created here will be created in the context of that merge request.
......@@ -4,6 +4,7 @@ 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(QMainWindow):
......@@ -36,6 +37,7 @@ class ModuleDebugGUI(QMainWindow):
# Initialize tabs
self.tabs.addTab(ConfigTab(self.config_reader), "Configuration")
self.tabs.addTab(ShifterTab(self.config_reader), "Image Shifter")
self.tabs.addTab(DepthTab(self.config_reader), "MonoDepth Estimation")
def main():
app = QApplication(sys.argv)
......
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
......@@ -2,6 +2,7 @@
from PyQt6.QtWidgets import QFileDialog, QMessageBox
import subprocess
import os
import shutil
def select_file(parent, title="Select File", file_types="All Files (*)", initial_dir=None):
"""
......@@ -126,4 +127,70 @@ def run_command(parent, cmd, status_callback=None):
if status_callback:
status_callback(error_msg)
QMessageBox.critical(parent, "Error", error_msg)
return False, error_msg
\ No newline at end of file
return False, error_msg
def clean_directory(directory_path, status_callback=None):
"""
Cleans all files in a directory.
Args:
directory_path: Directory to clean
status_callback: Optional callback for status updates
Returns:
bool: Success status
"""
try:
if not os.path.exists(directory_path):
os.makedirs(directory_path)
if status_callback:
status_callback(f"Created directory: {directory_path}")
return True
files = os.listdir(directory_path)
if not files:
if status_callback:
status_callback("Directory is already empty")
return True
for file in files:
file_path = os.path.join(directory_path, 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:
if status_callback:
status_callback(f"Error removing {file}: {str(e)}")
return False
if status_callback:
status_callback("Directory cleaned successfully")
return True
except Exception as e:
if status_callback:
status_callback(f"Failed to clean directory: {str(e)}")
return False
def copy_file(src, dest, status_callback=None):
"""
Copies a file to destination.
Args:
src: Source file path
dest: Destination file path
status_callback: Optional callback for status updates
Returns:
bool: Success status
"""
try:
os.makedirs(os.path.dirname(dest), exist_ok=True)
shutil.copy2(src, dest)
if status_callback:
status_callback(f"Copied file to: {dest}")
return True
except Exception as e:
if status_callback:
status_callback(f"Failed to copy file: {str(e)}")
return False
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment