diff --git a/scripts/debug_tool/tabs/edge_net_tab.py b/scripts/debug_tool/tabs/edge_net_tab.py
index 8331e2eb05c0c2dc17df59311215b39c829c7a19..754b68f32fd23de7366f43d73c250b7d0ceaa549 100644
--- a/scripts/debug_tool/tabs/edge_net_tab.py
+++ b/scripts/debug_tool/tabs/edge_net_tab.py
@@ -1,10 +1,12 @@
-
 import tkinter as tk
 from tkinter import ttk, messagebox, filedialog
 import os
-from PIL import Image, ImageTk
 import subprocess
 import shutil
+from PIL import Image, ImageTk
+import threading
+import queue
+import time
 
 class EdgeNetTab:
     def __init__(self, notebook, config_reader):
@@ -28,7 +30,19 @@ class EdgeNetTab:
             'material.png': None
         }
         
+        # Add queue for process output
+        self.output_queue = queue.Queue()
+        
+        # Add processing flag
+        self.is_processing = False
+        
+        # Add progress variables
+        self.progress_var = tk.DoubleVar(value=0)
+        
         self.setup_ui()
+        
+        # Start output monitoring
+        self.monitor_output()
 
     def setup_ui(self):
         # Split into left and right frames
@@ -189,7 +203,88 @@ class EdgeNetTab:
         )
         self.status_text.pack(fill=tk.BOTH, expand=True)
         status_scroll.config(command=self.status_text.yview)
+        
+        # Add progress bar
+        progress_frame = ttk.LabelFrame(parent, text="Progress", padding="5")
+        progress_frame.pack(fill=tk.X, pady=5)
+        
+        self.progress_bar = ttk.Progressbar(
+            progress_frame,
+            mode='indeterminate',
+            variable=self.progress_var
+        )
+        self.progress_bar.pack(fill=tk.X, padx=5, pady=5)
+        
+        # Add current operation label
+        self.operation_label = ttk.Label(progress_frame, text="")
+        self.operation_label.pack(pady=5)
+        
+        # Add cancel button (initially disabled)
+        self.cancel_button = ttk.Button(
+            progress_frame,
+            text="Cancel Operation",
+            command=self.cancel_operation,
+            state='disabled'
+        )
+        self.cancel_button.pack(pady=5)
 
+    def run_process_with_output(self, cmd, description):
+        """Run a process and capture output in real-time"""
+        process = subprocess.Popen(
+            cmd,
+            stdout=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+            shell=True,
+            text=True,
+            bufsize=1,
+            universal_newlines=True
+        )
+        
+        # Function to read output stream
+        def read_output(stream, queue):
+            for line in iter(stream.readline, ''):
+                queue.put(line)
+            stream.close()
+        
+        # Start output reader threads
+        stdout_thread = threading.Thread(
+            target=read_output, 
+            args=(process.stdout, self.output_queue)
+        )
+        stderr_thread = threading.Thread(
+            target=read_output, 
+            args=(process.stderr, self.output_queue)
+        )
+        
+        stdout_thread.daemon = True
+        stderr_thread.daemon = True
+        stdout_thread.start()
+        stderr_thread.start()
+        
+        # Wait for process to complete
+        return_code = process.wait()
+        
+        # Wait for output threads to finish
+        stdout_thread.join()
+        stderr_thread.join()
+        
+        return return_code
+    
+    def monitor_output(self):
+        """Monitor and display process output"""
+        try:
+            while True:
+                try:
+                    line = self.output_queue.get_nowait()
+                    self.update_status(line.strip())
+                    self.status_text.see(tk.END)
+                except queue.Empty:
+                    break
+        finally:
+            # Schedule next check
+            if self.is_processing:
+                self.tab.after(100, self.monitor_output)
+    
     def setup_preview_panel(self, parent):
         preview_frame = ttk.LabelFrame(parent, text="Process Previews", padding="5")
         preview_frame.pack(fill=tk.BOTH, expand=True)
@@ -342,94 +437,115 @@ class EdgeNetTab:
         return True
 
     def run_edge_net(self):
+        if self.is_processing:
+            messagebox.showwarning("Warning", "A process is already running!")
+            return
+            
+        # Start processing in a separate thread
+        thread = threading.Thread(target=self._run_edge_net_thread)
+        thread.daemon = True
+        thread.start()
+        
+        # Start progress bar
+        self.progress_bar.start(10)
+        self.is_processing = True
+        self.cancel_button.config(state='normal')
+        
+        # Start output monitoring
+        self.monitor_output()
+
+    def _run_edge_net_thread(self):
+        """Run EdgeNet processing in a separate thread"""
         try:
             # Verify input files first
+            self.operation_label.config(text="Verifying input files...")
             if not self.verify_enhance360_inputs():
-                # Try to copy manual inputs if verification failed
                 self.update_status("Attempting to copy manual inputs...")
                 self.copy_input_files()
                 
-                # Verify again after copying
                 if not self.verify_enhance360_inputs():
                     raise Exception("Missing required input files for enhance360.py")
-                
-            self.update_status("Running EdgeNet...")
-            self.edge_status.config(text="Running...", foreground="orange")
             
-            # Change to EdgeNet directory
             original_dir = os.getcwd()
             os.chdir(self.edge_net_dir)
             
-            # Run enhance360.py
-            self.update_status("Running enhance360.py...")
-            enhance_cmd = (f'wsl bash -c "source {self.config_reader.config["wslAnacondaDir"]}/activate'
-                         f' {self.config_reader.config["edgeNetEnv"]} && '
-                         f'python enhance360.py Input depth_e.png rgb.png enhanced_depth_e.png"')
-            
-            self.update_status(f"Executing command:\n{enhance_cmd}")
-            
-            process = subprocess.Popen(
-                enhance_cmd,
-                stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE,
-                shell=True,
-                text=True
-            )
-            stdout, stderr = process.communicate()
-            
-            if stdout:
-                self.update_status("enhance360.py output:\n" + stdout)
-            if stderr:
-                self.update_status("enhance360.py error:\n" + stderr)
-            
-            if process.returncode != 0:
-                raise Exception(f"enhance360.py failed: {stderr}")
+            try:
+                # Run enhance360.py
+                self.operation_label.config(text="Running enhance360.py...")
+                enhance_cmd = (f'wsl bash -c "source {self.config_reader.config["wslAnacondaDir"]}/activate'
+                             f' {self.config_reader.config["edgeNetEnv"]} && '
+                             f'python enhance360.py Input depth_e.png rgb.png enhanced_depth_e.png"')
                 
-            # Verify files for infer360.py
-            if not self.verify_infer360_inputs():
-                raise Exception("Missing required input files for infer360.py")
+                self.update_status(f"Executing command:\n{enhance_cmd}")
                 
-            # Run infer360.py
-            self.update_status("Running infer360.py...")
-            include_top_flag = "--include_top y" if self.include_top.get() else ""
-            infer_cmd = (f'wsl bash -c "source {self.config_reader.config["wslAnacondaDir"]}/activate'
-                        f' {self.config_reader.config["edgeNetEnv"]} && '
-                        f'python infer360.py Input enhanced_depth_e.png material.png rgb.png Input {include_top_flag}"')
-            
-            self.update_status(f"Executing command:\n{infer_cmd}")
-            
-            process = subprocess.Popen(
-                infer_cmd,
-                stdout=subprocess.PIPE,
-                stderr=subprocess.PIPE,
-                shell=True,
-                text=True
-            )
-            stdout, stderr = process.communicate()
-            
-            if stdout:
-                self.update_status("infer360.py output:\n" + stdout)
-            if stderr:
-                self.update_status("infer360.py error:\n" + stderr)
+                if self.run_process_with_output(enhance_cmd, "enhance360.py") != 0:
+                    raise Exception("enhance360.py failed")
+                
+                # Verify files for infer360.py
+                self.operation_label.config(text="Verifying infer360.py inputs...")
+                if not self.verify_infer360_inputs():
+                    raise Exception("Missing required input files for infer360.py")
+                
+                # Run infer360.py
+                self.operation_label.config(text="Running infer360.py...")
+                include_top_flag = "--include_top y" if self.include_top.get() else ""
+                infer_cmd = (f'wsl bash -c "source {self.config_reader.config["wslAnacondaDir"]}/activate'
+                            f' {self.config_reader.config["edgeNetEnv"]} && '
+                            f'python infer360.py Input enhanced_depth_e.png material.png rgb.png Input {include_top_flag}"')
+                
+                self.update_status(f"Executing command:\n{infer_cmd}")
+                
+                if self.run_process_with_output(infer_cmd, "infer360.py") != 0:
+                    raise Exception("infer360.py failed")
+                
+            finally:
+                os.chdir(original_dir)
+                # Deactivate WSL environment
+                subprocess.run('wsl bash -c "conda deactivate"', shell=True)
             
-            if process.returncode != 0:
-                raise Exception(f"infer360.py failed: {stderr}")
+            self.tab.after(0, self._process_complete, True)
             
+        except Exception as e:
+            self.tab.after(0, self._process_complete, False, str(e))
+        
+        finally:
+            self.is_processing = False
+
+    def _process_complete(self, success, error_message=None):
+        """Handle process completion in the main thread"""
+        self.progress_bar.stop()
+        self.cancel_button.config(state='disabled')
+        self.operation_label.config(text="")
+        
+        if success:
             self.update_status("EdgeNet processing completed successfully")
             self.edge_status.config(text="✓ Complete", foreground="green")
             self.update_depth_preview()
-                
-        except Exception as e:
-            self.update_status(f"Error in EdgeNet: {str(e)}")
+        else:
+            self.update_status(f"Error in EdgeNet: {error_message}")
             self.edge_status.config(text="✗ Failed", foreground="red")
-            messagebox.showerror("Error", f"EdgeNet failed: {str(e)}")
-        finally:
-            if original_dir:
-                os.chdir(original_dir)
-            
-            # Deactivate WSL environment
-            subprocess.run('wsl bash -c "conda deactivate"', shell=True)
+            messagebox.showerror("Error", f"EdgeNet failed: {error_message}")
 
+    def cancel_operation(self):
+        """Attempt to cancel the current operation"""
+        if not self.is_processing:
+            return
+            
+        if messagebox.askyesno("Confirm Cancel", "Are you sure you want to cancel the current operation?"):
+            self.update_status("Attempting to cancel operation...")
+            # TODO: Implement actual process cancellation
+            # This might require storing process handles and sending signals
+            self.is_processing = False
+
+    def update_status(self, message):
+        """Thread-safe status update"""
+        self.tab.after(0, self._update_status_safe, message)
+
+    def _update_status_safe(self, message):
+        """Update status text in the main thread"""
+        self.status_text.insert(tk.END, f"{message}\n")
+        self.status_text.see(tk.END)
+        
     def run_mesh_split(self):
         try:
             # Verify input files first