From 3eaafdd17c90c9e3593da084dee67c31eee51c2a Mon Sep 17 00:00:00 2001 From: tee1g21 <92794120+tee1g21@users.noreply.github.com> Date: Thu, 12 Dec 2024 23:22:23 +0000 Subject: [PATCH 1/5] First disparity map - looks completely wrong --- scripts/Depth2Disparity/depth2disparity.py | 105 -------------- scripts/Depth2Disparity/depth_to_disparity.py | 137 ++++++++++++++++++ scripts/simple_tab.py | 51 +++++-- 3 files changed, 175 insertions(+), 118 deletions(-) delete mode 100644 scripts/Depth2Disparity/depth2disparity.py create mode 100644 scripts/Depth2Disparity/depth_to_disparity.py diff --git a/scripts/Depth2Disparity/depth2disparity.py b/scripts/Depth2Disparity/depth2disparity.py deleted file mode 100644 index 08c6bb2..0000000 --- a/scripts/Depth2Disparity/depth2disparity.py +++ /dev/null @@ -1,105 +0,0 @@ -# takes 2 pixel coordinates and corresponding distance values - and a relative depth map -# caculates relative to absolute function - if linear -# applies function to relative depth map to get absolute depth map -# then convert to disparity map using depth disparity formula - - -import argparse -import numpy as np -import cv2 - -def relative2abs(rel_depth_map, coord1, dist1, coord2, dist2): - # Get the relative depth values at the two points - rel_value1 = rel_depth_map[coord1[1], coord1[0]] # (y, x) - rel_value2 = rel_depth_map[coord2[1], coord2[0]] - - # Calculate the linear transformation: depth = a * rel_depth + b - a = (dist2 - dist1) / (rel_value2 - rel_value1) - b = dist1 - a * rel_value1 - - # Apply the transformation to the entire relative depth map - abs_depth_map = a * rel_depth_map + b - - # this should not be normalised, the values in the array should equate to literal distances - return abs_depth_map - -def depth2disparity(abs_depth_map, baseline=0.176, disp_scale=2.0, disp_offset=-120): - - # Get image dimensions - height, width = abs_depth_map.shape - - # Calculate angular coordinates for each pixel - unit_w = 2.0 / width # Longitude step size - unit_h = 1.0 / height # Latitude step size - - # Initialize disparity map - disparity_map = np.zeros_like(abs_depth_map, dtype=np.float32) - - for i in range(height): - theta_t = i * unit_h * np.pi # Latitude angle for the row - - for j in range(width): - # Longitude angle (not strictly needed for disparity calculation) - phi = j * unit_w * np.pi - - # Retrieve the absolute depth (r_t) for this pixel - r_t = abs_depth_map[i, j] - - # Avoid invalid or infinite depth values - if r_t <= 0: - disparity_map[i, j] = 0 - continue - - try: - # Compute denominator with stability checks - epsilon = 1e-8 # Small value to prevent division instability - tan_theta_t = np.tan(theta_t) if np.abs(np.cos(theta_t)) > epsilon else np.sign(np.sin(theta_t)) * np.inf - - denominator = r_t * np.sin(theta_t) + r_t * np.cos(theta_t) * tan_theta_t - if denominator <= 0: - disparity_map[i, j] = 0 - continue - - # Calculate angular disparity (d) - angle_disp = np.arctan(baseline / denominator) - theta_t - - # Convert angular disparity to pixel disparity - disparity_map[i, j] = (angle_disp / (unit_h * np.pi) - disp_offset) * disp_scale - - except ZeroDivisionError: - disparity_map[i, j] = 0 - - return disparity_map - -if __name__ == "__main__": - # Set up argument parser - parser = argparse.ArgumentParser(description="Convert relative depth map to absolute depth map.") - parser.add_argument("rel_depth_map", type=str, help="Path to the relative depth map (image file).") - parser.add_argument("coord1", type=int, nargs=2, help="Pixel coordinates of the first point (x y).") - parser.add_argument("dist1", type=float, help="Absolute depth value at the first point.") - parser.add_argument("coord2", type=int, nargs=2, help="Pixel coordinates of the second point (x y).") - parser.add_argument("dist2", type=float, help="Absolute depth value at the second point.") - - # Parse arguments - args = parser.parse_args() - - # Load the relative depth map (dummy placeholder for now) - print(f"Loading relative depth map from: {args.rel_depth_map}") - rel_depth_map = cv2.imread(args.rel_depth_map, cv2.IMREAD_GRAYSCALE) # Load as grayscale - if rel_depth_map is None: - raise FileNotFoundError(f"Unable to load file: {args.rel_depth_map}") - - # Normalise depth map - rel_depth_map = rel_depth_map / 255.0 - - # Convert relative to absolute depth - abs_depth_map = relative2abs( - rel_depth_map, tuple(args.coord1), args.dist1, tuple(args.coord2), args.dist2 - ) - - # Convert depth map to disparity map - disparity_map = depth2disparity(abs_depth_map) - - # save disparity map - #cv2.imwrite(f"{args.rel_depth_map}-disparity.png", disparity_map) - \ No newline at end of file diff --git a/scripts/Depth2Disparity/depth_to_disparity.py b/scripts/Depth2Disparity/depth_to_disparity.py new file mode 100644 index 0000000..f2ca50b --- /dev/null +++ b/scripts/Depth2Disparity/depth_to_disparity.py @@ -0,0 +1,137 @@ +# takes 2 pixel coordinates and corresponding distance values - and a relative depth map +# caculates relative to absolute function - if linear +# applies function to relative depth map to get absolute depth map +# then convert to disparity map using depth disparity formula + + +import argparse +import numpy as np +import cv2 +import os + + +class Depth2Disparity: + + def __init__(self, baseline=0.176, disp_scale=2.0, disp_offset=-120): + """ + Initialize the Depth2Disparity class with correct parameters. + + Parameters: + baseline (float): Baseline distance between the stereo cameras (in meters). + disp_scale (float): Scaling factor for disparity values. + disp_offset (float): Offset added to the disparity values. + """ + self.baseline = baseline + self.disp_scale = disp_scale + self.disp_offset = disp_offset + + + def execute(self, rel_depth_path, coord1, dist1, coord2, dist2): + + # Load the relative depth map + print(f"Loading relative depth map from: {rel_depth_path}") + rel_depth_map = cv2.imread(rel_depth_path, cv2.IMREAD_GRAYSCALE) # Load as grayscale + if rel_depth_map is None: + raise FileNotFoundError(f"Unable to load file: {rel_depth_path}") + + # Normalize depth map + print("Normalizing depth map...") + rel_depth_map = rel_depth_map / 255.0 + + # Convert relative to absolute depth + print("Converting relative to absolute ...") + abs_depth_map = self._relative2abs(rel_depth_map, coord1, dist1, coord2, dist2) + + # Convert depth map to disparity map + print("Converting abs depth to disparity ...") + disparity_map = self._depth2disparity(abs_depth_map) + + # Determine the output path for the disparity map + disparity_dir = os.path.dirname(rel_depth_path) + disparity_base = "depth_e.png" + disparity_path = os.path.join(disparity_dir, disparity_base) + + # Check if an existing disparity map needs to be renamed + print(f"Checking for old depth map: {disparity_path}") + if os.path.exists(disparity_path): + old_depth_path = os.path.join(disparity_dir, "depth_e_old.png") + print(f"Renaming monodepth map to: {old_depth_path}") + os.rename(disparity_path, old_depth_path) + + # Save the new disparity map + print(f"Saving new disparity map to: {disparity_path}") + cv2.imwrite(disparity_path, (disparity_map * 255).astype(np.uint8)) + + # Debug message for GUI or logs + print("Complete") + + # add typing to this method defintion + def _relative2abs(self, rel_depth_map, coord1: tuple, dist1: float, coord2: tuple, dist2: float): + + print("\tStoring relative depth value at coordinates") + # Get the relative depth values at the two points + rel_value1 = rel_depth_map[coord1[1], coord1[0]] # (y, x) + rel_value2 = rel_depth_map[coord2[1], coord2[0]] + + print("\tPerforming linear transformation") + # Calculate the linear transformation: depth = a * rel_depth + b + a = (dist2 - dist1) / (rel_value2 - rel_value1) + b = dist1 - a * rel_value1 + + print("\tApplying transformation to entire depth map") + # Apply the transformation to the entire relative depth map + abs_depth_map = a * rel_depth_map + b + + # this should not be normalised, the values in the array should equate to literal distances + return abs_depth_map + + def _depth2disparity(self, abs_depth_map): + + # Get image dimensions + height, width = abs_depth_map.shape + + # Calculate angular coordinates for each pixel + unit_w = 2.0 / width # Longitude step size + unit_h = 1.0 / height # Latitude step size + + # Initialize disparity map + disparity_map = np.zeros_like(abs_depth_map, dtype=np.float32) + + for i in range(height): + theta_t = i * unit_h * np.pi # Latitude angle for the row + + for j in range(width): + # Longitude angle (not strictly needed for disparity calculation) + phi = j * unit_w * np.pi + + # Retrieve the absolute depth (r_t) for this pixel + r_t = abs_depth_map[i, j] + + # Avoid invalid or infinite depth values + if r_t <= 0: + disparity_map[i, j] = 0 + continue + + try: + # Compute denominator with stability checks + epsilon = 1e-8 # Small value to prevent division instability + tan_theta_t = np.tan(theta_t) if np.abs(np.cos(theta_t)) > epsilon else np.sign(np.sin(theta_t)) * np.inf + + denominator = r_t * np.sin(theta_t) + r_t * np.cos(theta_t) * tan_theta_t + if denominator <= 0: + disparity_map[i, j] = 0 + continue + + # Calculate angular disparity (d) + angle_disp = np.arctan(self.baseline / denominator) - theta_t + + # Convert angular disparity to pixel disparity + disparity_map[i, j] = (angle_disp / (unit_h * np.pi) - self.disp_offset) * self.disp_scale + + except ZeroDivisionError: + disparity_map[i, j] = 0 + + return disparity_map + + + \ No newline at end of file diff --git a/scripts/simple_tab.py b/scripts/simple_tab.py index 867c06a..ff0c912 100644 --- a/scripts/simple_tab.py +++ b/scripts/simple_tab.py @@ -18,14 +18,17 @@ from debug_tool.tabs.depth_tab import DepthTab from debug_tool.tabs.material_tab import MaterialTab from debug_tool.tabs.edge_net_tab import EdgeNetTab +from Depth2Disparity.depth_to_disparity import Depth2Disparity + class PipelineWorker(QThread): progress = pyqtSignal(str) finished = pyqtSignal(bool, str) def __init__(self, tab_instance): super().__init__() - self.tab = tab_instance - + self.tab = tab_instance + self.distance_points = self.tab.distance_points # added distance points to class for disparity calculation + def run(self): try: self.run_pipeline() @@ -86,6 +89,26 @@ class PipelineWorker(QThread): self.progress.emit("Running depth estimation...") self.tab.depth.run_depth_estimation(False) print("Completed depth_estimation") # Debug print + + def run_depth_to_disparity(self): + print("\nStarting depth2disparity") + self.progress.emit("Converting mono-depthmap to disparity map...") + + # execute function to convert depth to disparity + real_depth_path = self.tab.depth.depth_output_path # depthmap path + coord1 = int(self.distance_points[0][0]), int(self.distance_points[0][1]) # x,y coordinates of point 1 + dist1 = float(self.distance_points[0][2]) # distance from camera to point 1 + coord2 = int(self.distance_points[1][0]), int(self.distance_points[1][1]) # x,y coordinates of point 2 + dist2 = float(self.distance_points[1][2]) # distance from camera to point 2 + print(f"{coord1}, {dist1}, {coord2}, {dist2}") + + convert_d2d = Depth2Disparity() + print("Executing...") + convert_d2d.execute(real_depth_path, coord1, dist1, coord2, dist2) + + print("Saved disparity map to output directory: " + real_depth_path) + self.progress.emit("Completed Disparity Map Conversion") + def run_material_recognition(self): print("Starting material_recognition") @@ -148,13 +171,15 @@ class PipelineWorker(QThread): self.progress.emit("File saved in edgenet-360\Output") def run_pipeline(self): - self.clean_temp_files() - self.shift_image() - self.copy_file() - self.run_depth_estimation() - self.run_material_recognition() - self.run_edge_net() - self.run_post_processing() + #self.clean_temp_files() + #self.shift_image() + #self.copy_file() + #self.run_depth_estimation() + self.run_depth_to_disparity() + + #self.run_material_recognition() + #self.run_edge_net() + #self.run_post_processing() self.progress.emit("Pipeline completed!") class SimpleTab(QWidget): @@ -612,6 +637,10 @@ class SimpleTab(QWidget): self.progress_bar.show() self.run_pipeline_btn.setEnabled(False) + #TODO: Add distance points to the pipeline for depth estimation + # Get the distance points + self.distance_points = self.distance_preview.get_points() + self.pipeline_thread = PipelineWorker(self) # Connect signals @@ -626,10 +655,6 @@ class SimpleTab(QWidget): #TODO: Add model selection for EdgeNet or MDBNet # Set the SSC model self.selected_model = self.ssc_model_combo.currentText() - - #TODO: Add distance points to the pipeline for depth estimation - # Get the distance points - self.distance_points = self.distance_preview.get_points() # Start the pipeline self.pipeline_thread.start() -- GitLab From 263d026e4bfa555bf7210057ead1114e40368464 Mon Sep 17 00:00:00 2001 From: tee1g21 <92794120+tee1g21@users.noreply.github.com> Date: Tue, 24 Dec 2024 04:23:05 +0000 Subject: [PATCH 2/5] Fixed ratio scaling problem, absolute depth maps now generate well but completely rely on monodepth --- scripts/Depth2Disparity/depth_to_disparity.py | 97 +++++++++++++------ scripts/debug_tool/utils/image_handlers.py | 4 +- scripts/simple_tab.py | 13 +-- 3 files changed, 78 insertions(+), 36 deletions(-) diff --git a/scripts/Depth2Disparity/depth_to_disparity.py b/scripts/Depth2Disparity/depth_to_disparity.py index f2ca50b..a0e3abe 100644 --- a/scripts/Depth2Disparity/depth_to_disparity.py +++ b/scripts/Depth2Disparity/depth_to_disparity.py @@ -8,6 +8,12 @@ import argparse import numpy as np import cv2 import os +import matplotlib.pyplot as plt +import matplotlib +matplotlib.use("TkAgg") # Use TkAgg for GUI rendering +import warnings +warnings.filterwarnings( "ignore", module = "matplotlib\..*" ) + class Depth2Disparity: @@ -34,33 +40,40 @@ class Depth2Disparity: if rel_depth_map is None: raise FileNotFoundError(f"Unable to load file: {rel_depth_path}") - # Normalize depth map - print("Normalizing depth map...") - rel_depth_map = rel_depth_map / 255.0 - # Convert relative to absolute depth print("Converting relative to absolute ...") abs_depth_map = self._relative2abs(rel_depth_map, coord1, dist1, coord2, dist2) - # Convert depth map to disparity map - print("Converting abs depth to disparity ...") - disparity_map = self._depth2disparity(abs_depth_map) + # Normalize depth map for saving + abs_depth_map_normalized = (abs_depth_map - abs_depth_map.min()) / (abs_depth_map.max() - abs_depth_map.min()) + abs_depth_map_normalized *= 255 + abs_depth_map_normalized = abs_depth_map_normalized.astype(np.uint8) - # Determine the output path for the disparity map - disparity_dir = os.path.dirname(rel_depth_path) - disparity_base = "depth_e.png" - disparity_path = os.path.join(disparity_dir, disparity_base) + # store absolute dpet map for debugging + abs_depth_path = os.path.join(os.path.dirname(rel_depth_path), "abs_depth.png") + cv2.imwrite(abs_depth_path, abs_depth_map_normalized) + print(f"Absolute depth map saved to: {abs_depth_path}\n") - # Check if an existing disparity map needs to be renamed - print(f"Checking for old depth map: {disparity_path}") - if os.path.exists(disparity_path): - old_depth_path = os.path.join(disparity_dir, "depth_e_old.png") - print(f"Renaming monodepth map to: {old_depth_path}") - os.rename(disparity_path, old_depth_path) - - # Save the new disparity map - print(f"Saving new disparity map to: {disparity_path}") - cv2.imwrite(disparity_path, (disparity_map * 255).astype(np.uint8)) + # Convert depth map to disparity map + #print("Converting abs depth to disparity ...") + #disparity_map = self._depth2disparity(abs_depth_map) + + ## Determine the output path for the disparity map + #disparity_dir = os.path.dirname(rel_depth_path) + #disparity_base = "disp_map.png"#"depth_e.png" + #disparity_path = os.path.join(disparity_dir, disparity_base) + + ## Check if an existing disparity map needs to be renamed + ##if os.path.exists(disparity_path): + ## old_depth_path = os.path.join(disparity_dir, "depth_e_old.png") + ## print(f"Renaming monodepth map to: {old_depth_path}") + ## # if pre-existing 'old depth map' exists, remove it + ## if os.path.exists(old_depth_path): + ## os.remove(old_depth_path) + ## os.rename(disparity_path, old_depth_path) + ## Save the new disparity map + ##print(f"Saving new disparity map to: {disparity_path}") + ##cv2.imwrite(disparity_path, (disparity_map).astype(np.uint8)) # Debug message for GUI or logs print("Complete") @@ -68,19 +81,43 @@ class Depth2Disparity: # add typing to this method defintion def _relative2abs(self, rel_depth_map, coord1: tuple, dist1: float, coord2: tuple, dist2: float): - print("\tStoring relative depth value at coordinates") + # Normalize depth map + print("Normalizing depth map...") + #rel_depth_map = rel_depth_map.astype(np.float32) / 255.0 + + plt.imshow(rel_depth_map, cmap='gray') + plt.colorbar() + plt.show() + + #print("\tStoring relative depth value at coordinates") # Get the relative depth values at the two points - rel_value1 = rel_depth_map[coord1[1], coord1[0]] # (y, x) - rel_value2 = rel_depth_map[coord2[1], coord2[0]] + rel_value1 = float(rel_depth_map[coord1[1], coord1[0]]) # (y, x) + rel_value2 = float(rel_depth_map[coord2[1], coord2[0]]) + print(f"rel1: {rel_value1}, rel2: {rel_value2}, dist1: {dist1}, dist2: {dist2}") + + #if rel_value1 > rel_value2: + # coord1, coord2 = coord2, coord1 + # dist1, dist2 = dist2, dist1 - print("\tPerforming linear transformation") + + #print("\tPerforming linear transformation") # Calculate the linear transformation: depth = a * rel_depth + b - a = (dist2 - dist1) / (rel_value2 - rel_value1) + numerator = dist2 - dist1 + denominator = rel_value2 - rel_value1 + a = numerator / denominator + print("Calculated a: ", a) b = dist1 - a * rel_value1 - - print("\tApplying transformation to entire depth map") + print("Calculated b: ", b) + + #print("\tApplying transformation to entire depth map") # Apply the transformation to the entire relative depth map abs_depth_map = a * rel_depth_map + b + print("Applied transformation to entire depth map") + + plt.imshow(abs_depth_map, cmap='gray') + plt.colorbar() + plt.show() + # this should not be normalised, the values in the array should equate to literal distances return abs_depth_map @@ -131,6 +168,10 @@ class Depth2Disparity: except ZeroDivisionError: disparity_map[i, j] = 0 + plt.imshow(disparity_map, cmap='gray') + plt.colorbar() + plt.show() + return disparity_map diff --git a/scripts/debug_tool/utils/image_handlers.py b/scripts/debug_tool/utils/image_handlers.py index e1cdcdd..7ecd65c 100644 --- a/scripts/debug_tool/utils/image_handlers.py +++ b/scripts/debug_tool/utils/image_handlers.py @@ -49,7 +49,7 @@ def load_and_resize_image(image_path, max_size=800): new_size = (int(width * ratio), int(height * ratio)) img = cv2.resize(img, new_size, interpolation=cv2.INTER_AREA) - return img + return img, ratio except Exception as e: raise Exception(f"Error loading image: {str(e)}") @@ -65,7 +65,7 @@ def update_preview(preview_label, image_path, max_size=300, error_callback=None) """ if image_path and os.path.exists(image_path): try: - img = load_and_resize_image(image_path, max_size) + img, ratio = load_and_resize_image(image_path, max_size) pixmap = convert_cv_to_pixmap(img) preview_label.setPixmap(pixmap) except Exception as e: diff --git a/scripts/simple_tab.py b/scripts/simple_tab.py index ff0c912..ab01fa7 100644 --- a/scripts/simple_tab.py +++ b/scripts/simple_tab.py @@ -28,7 +28,8 @@ class PipelineWorker(QThread): super().__init__() self.tab = tab_instance self.distance_points = self.tab.distance_points # added distance points to class for disparity calculation - + self.ratio = self.tab.ratio # image scale ratio for reversal + def run(self): try: self.run_pipeline() @@ -96,17 +97,17 @@ class PipelineWorker(QThread): # execute function to convert depth to disparity real_depth_path = self.tab.depth.depth_output_path # depthmap path - coord1 = int(self.distance_points[0][0]), int(self.distance_points[0][1]) # x,y coordinates of point 1 + coord1 = int(self.distance_points[0][0] / self.ratio), int(self.distance_points[0][1] / self.ratio) # x,y coordinates of point 1 dist1 = float(self.distance_points[0][2]) # distance from camera to point 1 - coord2 = int(self.distance_points[1][0]), int(self.distance_points[1][1]) # x,y coordinates of point 2 + coord2 = int(self.distance_points[1][0] / self.ratio), int(self.distance_points[1][1] / self.ratio) # x,y coordinates of point 2 dist2 = float(self.distance_points[1][2]) # distance from camera to point 2 - print(f"{coord1}, {dist1}, {coord2}, {dist2}") + print(f"{coord1}, {dist1}, {coord2}, {dist2}. Ratio: {self.ratio}") convert_d2d = Depth2Disparity() print("Executing...") convert_d2d.execute(real_depth_path, coord1, dist1, coord2, dist2) - print("Saved disparity map to output directory: " + real_depth_path) + #print("Saved disparity map to output directory: " + real_depth_path) self.progress.emit("Completed Disparity Map Conversion") @@ -573,7 +574,7 @@ class SimpleTab(QWidget): update_preview(self.input_preview, file_path, error_callback=self.update_status) update_preview(self.distance_preview,file_path,max_size=1500) - pixmap = load_and_resize_image(file_path, 1500) + pixmap, self.ratio = load_and_resize_image(file_path, 1500) pixmap = convert_cv_to_pixmap(pixmap) self.distance_preview.setFixedSize(pixmap.size()) self.image_distance_group.show() -- GitLab From c1cc588d17f1a80c48c8a6333fa8676756c48f6a Mon Sep 17 00:00:00 2001 From: tee1g21 <92794120+tee1g21@users.noreply.github.com> Date: Fri, 27 Dec 2024 20:25:37 +0000 Subject: [PATCH 3/5] Absolute depthmap working, disp not --- scripts/Depth2Disparity/depth_to_disparity.py | 83 ++++++++++--------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/scripts/Depth2Disparity/depth_to_disparity.py b/scripts/Depth2Disparity/depth_to_disparity.py index a0e3abe..d13d3dc 100644 --- a/scripts/Depth2Disparity/depth_to_disparity.py +++ b/scripts/Depth2Disparity/depth_to_disparity.py @@ -12,7 +12,7 @@ import matplotlib.pyplot as plt import matplotlib matplotlib.use("TkAgg") # Use TkAgg for GUI rendering import warnings -warnings.filterwarnings( "ignore", module = "matplotlib\..*" ) +warnings.filterwarnings( "ignore") @@ -55,13 +55,13 @@ class Depth2Disparity: print(f"Absolute depth map saved to: {abs_depth_path}\n") # Convert depth map to disparity map - #print("Converting abs depth to disparity ...") - #disparity_map = self._depth2disparity(abs_depth_map) + print("Converting abs depth to disparity ...") + disparity_map, disparity_map_normalized = self._depth2disparity(abs_depth_map) - ## Determine the output path for the disparity map - #disparity_dir = os.path.dirname(rel_depth_path) - #disparity_base = "disp_map.png"#"depth_e.png" - #disparity_path = os.path.join(disparity_dir, disparity_base) + # Determine the output path for the disparity map + disparity_dir = os.path.dirname(rel_depth_path) + disparity_base = "disp_map.png"#"depth_e.png" + disparity_path = os.path.join(disparity_dir, disparity_base) ## Check if an existing disparity map needs to be renamed ##if os.path.exists(disparity_path): @@ -71,10 +71,12 @@ class Depth2Disparity: ## if os.path.exists(old_depth_path): ## os.remove(old_depth_path) ## os.rename(disparity_path, old_depth_path) - ## Save the new disparity map - ##print(f"Saving new disparity map to: {disparity_path}") - ##cv2.imwrite(disparity_path, (disparity_map).astype(np.uint8)) - + + # Save the new disparity map + print(f"Saving new disparity map to: {disparity_path}") + cv2.imwrite(disparity_path, disparity_map_normalized) + + # Debug message for GUI or logs print("Complete") @@ -84,27 +86,20 @@ class Depth2Disparity: # Normalize depth map print("Normalizing depth map...") #rel_depth_map = rel_depth_map.astype(np.float32) / 255.0 + rel_depth_map = (rel_depth_map - rel_depth_map.min()) / (rel_depth_map.max() - rel_depth_map.min()) - plt.imshow(rel_depth_map, cmap='gray') - plt.colorbar() - plt.show() + #plt.imshow(rel_depth_map, cmap='gray') + #plt.colorbar() + #plt.show() - #print("\tStoring relative depth value at coordinates") # Get the relative depth values at the two points rel_value1 = float(rel_depth_map[coord1[1], coord1[0]]) # (y, x) rel_value2 = float(rel_depth_map[coord2[1], coord2[0]]) print(f"rel1: {rel_value1}, rel2: {rel_value2}, dist1: {dist1}, dist2: {dist2}") - #if rel_value1 > rel_value2: - # coord1, coord2 = coord2, coord1 - # dist1, dist2 = dist2, dist1 - - - #print("\tPerforming linear transformation") + # Calculate the linear transformation: depth = a * rel_depth + b - numerator = dist2 - dist1 - denominator = rel_value2 - rel_value1 - a = numerator / denominator + a = (dist2 - dist1) / (rel_value2 - rel_value1) print("Calculated a: ", a) b = dist1 - a * rel_value1 print("Calculated b: ", b) @@ -114,33 +109,34 @@ class Depth2Disparity: abs_depth_map = a * rel_depth_map + b print("Applied transformation to entire depth map") - plt.imshow(abs_depth_map, cmap='gray') - plt.colorbar() - plt.show() - + abs_depth_map = np.maximum(abs_depth_map, 0.01) + #plt.imshow(abs_depth_map, cmap='gray') + #plt.colorbar() + #plt.show() + # this should not be normalised, the values in the array should equate to literal distances return abs_depth_map def _depth2disparity(self, abs_depth_map): - # Get image dimensions + # Get image dimensions + # Get image dimensions height, width = abs_depth_map.shape - # Calculate angular coordinates for each pixel + # Calculate step sizes unit_w = 2.0 / width # Longitude step size unit_h = 1.0 / height # Latitude step size # Initialize disparity map disparity_map = np.zeros_like(abs_depth_map, dtype=np.float32) + # Iterate over each pixel for i in range(height): - theta_t = i * unit_h * np.pi # Latitude angle for the row + # Calculate latitude angle for the row + theta_t = i * unit_h * np.pi for j in range(width): - # Longitude angle (not strictly needed for disparity calculation) - phi = j * unit_w * np.pi - # Retrieve the absolute depth (r_t) for this pixel r_t = abs_depth_map[i, j] @@ -150,20 +146,22 @@ class Depth2Disparity: continue try: - # Compute denominator with stability checks - epsilon = 1e-8 # Small value to prevent division instability + # Compute denominator for the formula + epsilon = 1e-8 # Small value to prevent instability tan_theta_t = np.tan(theta_t) if np.abs(np.cos(theta_t)) > epsilon else np.sign(np.sin(theta_t)) * np.inf - denominator = r_t * np.sin(theta_t) + r_t * np.cos(theta_t) * tan_theta_t + + # Avoid invalid denominator values if denominator <= 0: disparity_map[i, j] = 0 continue - # Calculate angular disparity (d) + # Calculate angular disparity angle_disp = np.arctan(self.baseline / denominator) - theta_t # Convert angular disparity to pixel disparity - disparity_map[i, j] = (angle_disp / (unit_h * np.pi) - self.disp_offset) * self.disp_scale + pixel_disp = (angle_disp / (unit_h * np.pi) - self.disp_offset) * self.disp_scale + disparity_map[i, j] = pixel_disp except ZeroDivisionError: disparity_map[i, j] = 0 @@ -172,7 +170,12 @@ class Depth2Disparity: plt.colorbar() plt.show() - return disparity_map + # Normalize disparity map for visualization + disparity_map_normalized = (disparity_map - disparity_map.min()) / (disparity_map.max() - disparity_map.min()) + disparity_map_normalized *= 255 + disparity_map_normalized = disparity_map_normalized.astype(np.uint8) + + return disparity_map, disparity_map_normalized \ No newline at end of file -- GitLab From cd34cfa37723eeafe91f5bf90b9f2e1c83d0221e Mon Sep 17 00:00:00 2001 From: tee1g21 <92794120+tee1g21@users.noreply.github.com> Date: Mon, 30 Dec 2024 21:13:22 +0000 Subject: [PATCH 4/5] Real depth working, disparity not currently feasible --- scripts/Depth2Disparity/depth_to_disparity.py | 162 +++++++++++------- 1 file changed, 101 insertions(+), 61 deletions(-) diff --git a/scripts/Depth2Disparity/depth_to_disparity.py b/scripts/Depth2Disparity/depth_to_disparity.py index d13d3dc..10c0df9 100644 --- a/scripts/Depth2Disparity/depth_to_disparity.py +++ b/scripts/Depth2Disparity/depth_to_disparity.py @@ -109,73 +109,113 @@ class Depth2Disparity: abs_depth_map = a * rel_depth_map + b print("Applied transformation to entire depth map") - abs_depth_map = np.maximum(abs_depth_map, 0.01) + #abs_depth_map = np.maximum(abs_depth_map, 0.01) - #plt.imshow(abs_depth_map, cmap='gray') - #plt.colorbar() - #plt.show() + plt.imshow(abs_depth_map, cmap='gray') + plt.colorbar() + plt.show() # this should not be normalised, the values in the array should equate to literal distances return abs_depth_map def _depth2disparity(self, abs_depth_map): - - # Get image dimensions - # Get image dimensions - height, width = abs_depth_map.shape - - # Calculate step sizes - unit_w = 2.0 / width # Longitude step size - unit_h = 1.0 / height # Latitude step size - - # Initialize disparity map - disparity_map = np.zeros_like(abs_depth_map, dtype=np.float32) - - # Iterate over each pixel - for i in range(height): - # Calculate latitude angle for the row - theta_t = i * unit_h * np.pi - - for j in range(width): - # Retrieve the absolute depth (r_t) for this pixel - r_t = abs_depth_map[i, j] - - # Avoid invalid or infinite depth values - if r_t <= 0: - disparity_map[i, j] = 0 - continue - - try: - # Compute denominator for the formula - epsilon = 1e-8 # Small value to prevent instability - tan_theta_t = np.tan(theta_t) if np.abs(np.cos(theta_t)) > epsilon else np.sign(np.sin(theta_t)) * np.inf - denominator = r_t * np.sin(theta_t) + r_t * np.cos(theta_t) * tan_theta_t - - # Avoid invalid denominator values - if denominator <= 0: - disparity_map[i, j] = 0 - continue - - # Calculate angular disparity - angle_disp = np.arctan(self.baseline / denominator) - theta_t - - # Convert angular disparity to pixel disparity - pixel_disp = (angle_disp / (unit_h * np.pi) - self.disp_offset) * self.disp_scale - disparity_map[i, j] = pixel_disp - - except ZeroDivisionError: - disparity_map[i, j] = 0 - - plt.imshow(disparity_map, cmap='gray') - plt.colorbar() - plt.show() - - # Normalize disparity map for visualization - disparity_map_normalized = (disparity_map - disparity_map.min()) / (disparity_map.max() - disparity_map.min()) - disparity_map_normalized *= 255 - disparity_map_normalized = disparity_map_normalized.astype(np.uint8) - - return disparity_map, disparity_map_normalized + """ + Convert absolute depth map to disparity map for 360-degree images. + + Parameters: + abs_depth_map (numpy.ndarray): Absolute depth map with pixel values as distances in meters. + + Returns: + disparity_map (numpy.ndarray): Disparity map with values representing disparity. + disparity_map_normalized (numpy.ndarray): Normalized disparity map for visualization. + """ + # Define parameters for the conversion + height, width = abs_depth_map.shape + + # Latitude grid (θ_l) + epsilon = 1e-6 + latitudes = np.linspace(-np.pi / 2, np.pi / 2, height) + latitudes_grid = np.tile(latitudes[:, np.newaxis], (1, width)) + + # Clamp extreme latitudes to avoid instability + latitudes_grid = np.clip(latitudes_grid, -np.pi/2 + epsilon, np.pi/2 - epsilon) + + plt.imshow(latitudes_grid, cmap="jet") + plt.colorbar() + plt.title("Latitude Grid") + plt.show() + + self.baseline = 0.176 + + + # Calculate angular disparity Δθ(x, y) + # Δθ(x, y) = arctan(B / (r_t * sin(θ_l) + r_t * cos(θ_l) * tan(θ_l))) - θ_l + epsilon = 1e-6 # Small value to prevent instability + denominator = ( + abs_depth_map * np.sin(latitudes_grid) + + abs_depth_map * np.cos(latitudes_grid) * np.tan(latitudes_grid) + + epsilon + ) + angular_disparity = np.arctan(self.baseline / denominator) - latitudes_grid + + self.disp_scale = 10 + self.disp_offset = np.median(angular_disparity) + + # Normalize the disparity map for saving + pixel_angle_scale = 1 # Assume scale factor is 1 if not provided (can be adjusted if needed) + disparity_map = (angular_disparity / pixel_angle_scale - self.disp_offset) * self.disp_scale + + # Normalize for visualization + disparity_map_normalized = (disparity_map - disparity_map.min()) / (disparity_map.max() - disparity_map.min()) + disparity_map_normalized *= 255 + disparity_map_normalized = disparity_map_normalized.astype(np.uint8) + + # Debugging visualization + plt.imshow(disparity_map, cmap="jet") + plt.colorbar() + plt.title("Disparity Map (Debugging)") + plt.show() + + return disparity_map, disparity_map_normalized + + def __depth2disparity(self, abs_depth_map): + height, width = abs_depth_map.shape + unit_w = 2.0 / width # Horizontal unit angle + unit_h = 1.0 / height # Vertical unit angle + epsilon = 1e-8 # Small value to prevent instability + + # Latitude angles (theta_t) for each row + theta_t_grid = np.linspace(0, np.pi, height).reshape(height, 1) + + # Ensure no instability in tangent calculation + tan_theta_t = np.tan(np.clip(theta_t_grid, -np.pi/2 + epsilon, np.pi/2 - epsilon)) + # Broadcast depth map and latitude grid + r_t = abs_depth_map # Absolute depth values (meters) + sin_theta_t = np.sin(theta_t_grid) + cos_theta_t = np.cos(theta_t_grid) + + # Compute denominator + denominator = r_t * sin_theta_t + r_t * cos_theta_t * tan_theta_t + epsilon + + # Avoid invalid denominator values + denominator[denominator <= 0] = epsilon + + # Calculate angular disparity + angle_disp = np.arctan(self.baseline / denominator) - theta_t_grid + + # Convert angular disparity to pixel disparity + disparity_map = (angle_disp / (unit_h * np.pi) - self.disp_offset) * self.disp_scale + + plt.imshow(disparity_map, cmap='gray') + plt.colorbar() + plt.show() + + # Normalize disparity map for visualization + disparity_map_normalized = (disparity_map - disparity_map.min()) / (disparity_map.max() - disparity_map.min()) + disparity_map_normalized *= 255 + disparity_map_normalized = disparity_map_normalized.astype(np.uint8) + + return disparity_map, disparity_map_normalized \ No newline at end of file -- GitLab From 0240142df25a5033e99196bebe07213ebf527c83 Mon Sep 17 00:00:00 2001 From: tee1g21 <92794120+tee1g21@users.noreply.github.com> Date: Wed, 15 Jan 2025 23:33:17 +0000 Subject: [PATCH 5/5] Final version of depth2disparity --- scripts/Depth2Disparity/depth_to_disparity.py | 178 +++++++++--------- scripts/simple_tab.py | 19 +- 2 files changed, 93 insertions(+), 104 deletions(-) diff --git a/scripts/Depth2Disparity/depth_to_disparity.py b/scripts/Depth2Disparity/depth_to_disparity.py index 10c0df9..e329440 100644 --- a/scripts/Depth2Disparity/depth_to_disparity.py +++ b/scripts/Depth2Disparity/depth_to_disparity.py @@ -64,13 +64,13 @@ class Depth2Disparity: disparity_path = os.path.join(disparity_dir, disparity_base) ## Check if an existing disparity map needs to be renamed - ##if os.path.exists(disparity_path): - ## old_depth_path = os.path.join(disparity_dir, "depth_e_old.png") - ## print(f"Renaming monodepth map to: {old_depth_path}") - ## # if pre-existing 'old depth map' exists, remove it - ## if os.path.exists(old_depth_path): - ## os.remove(old_depth_path) - ## os.rename(disparity_path, old_depth_path) + if os.path.exists(disparity_path): + old_depth_path = os.path.join(disparity_dir, "depth_e_old.png") + print(f"Renaming monodepth map to: {old_depth_path}") + # if pre-existing 'old depth map' exists, remove it + if os.path.exists(old_depth_path): + os.remove(old_depth_path) + os.rename(disparity_path, old_depth_path) # Save the new disparity map print(f"Saving new disparity map to: {disparity_path}") @@ -119,103 +119,93 @@ class Depth2Disparity: return abs_depth_map def _depth2disparity(self, abs_depth_map): - """ - Convert absolute depth map to disparity map for 360-degree images. - - Parameters: - abs_depth_map (numpy.ndarray): Absolute depth map with pixel values as distances in meters. - - Returns: - disparity_map (numpy.ndarray): Disparity map with values representing disparity. - disparity_map_normalized (numpy.ndarray): Normalized disparity map for visualization. - """ - # Define parameters for the conversion height, width = abs_depth_map.shape - - # Latitude grid (θ_l) - epsilon = 1e-6 - latitudes = np.linspace(-np.pi / 2, np.pi / 2, height) - latitudes_grid = np.tile(latitudes[:, np.newaxis], (1, width)) - - # Clamp extreme latitudes to avoid instability - latitudes_grid = np.clip(latitudes_grid, -np.pi/2 + epsilon, np.pi/2 - epsilon) - - plt.imshow(latitudes_grid, cmap="jet") - plt.colorbar() - plt.title("Latitude Grid") - plt.show() - - self.baseline = 0.176 - - - # Calculate angular disparity Δθ(x, y) - # Δθ(x, y) = arctan(B / (r_t * sin(θ_l) + r_t * cos(θ_l) * tan(θ_l))) - θ_l - epsilon = 1e-6 # Small value to prevent instability - denominator = ( - abs_depth_map * np.sin(latitudes_grid) + - abs_depth_map * np.cos(latitudes_grid) * np.tan(latitudes_grid) + - epsilon - ) - angular_disparity = np.arctan(self.baseline / denominator) - latitudes_grid - - self.disp_scale = 10 - self.disp_offset = np.median(angular_disparity) - - # Normalize the disparity map for saving - pixel_angle_scale = 1 # Assume scale factor is 1 if not provided (can be adjusted if needed) - disparity_map = (angular_disparity / pixel_angle_scale - self.disp_offset) * self.disp_scale + unit_h = 1.0 / height + disparity_map = np.zeros_like(abs_depth_map, dtype=np.float32) + + for i in range(height): + theta_t = i * unit_h * np.pi + for j in range(width): + r_t = max(abs_depth_map[i, j], 0.01) # Clamp small depths + if r_t <= 0: + disparity_map[i, j] = 0 + continue + try: + tan_theta_t = np.tan(theta_t) if np.abs(np.cos(theta_t)) > 1e-6 else np.sign(np.sin(theta_t)) * np.inf + denominator = max(r_t * np.sin(theta_t) + r_t * np.cos(theta_t) * tan_theta_t, 1e-6) + angle_disp = np.arctan(self.baseline / denominator) - theta_t + pixel_disp = (angle_disp / (unit_h * np.pi) - self.disp_offset) * self.disp_scale + disparity_map[i, j] = pixel_disp + except ZeroDivisionError: + disparity_map[i, j] = 0 # Normalize for visualization disparity_map_normalized = (disparity_map - disparity_map.min()) / (disparity_map.max() - disparity_map.min()) disparity_map_normalized *= 255 disparity_map_normalized = disparity_map_normalized.astype(np.uint8) - # Debugging visualization - plt.imshow(disparity_map, cmap="jet") - plt.colorbar() - plt.title("Disparity Map (Debugging)") - plt.show() - - return disparity_map, disparity_map_normalized - - def __depth2disparity(self, abs_depth_map): - height, width = abs_depth_map.shape - unit_w = 2.0 / width # Horizontal unit angle - unit_h = 1.0 / height # Vertical unit angle - epsilon = 1e-8 # Small value to prevent instability - - # Latitude angles (theta_t) for each row - theta_t_grid = np.linspace(0, np.pi, height).reshape(height, 1) - - # Ensure no instability in tangent calculation - tan_theta_t = np.tan(np.clip(theta_t_grid, -np.pi/2 + epsilon, np.pi/2 - epsilon)) - - # Broadcast depth map and latitude grid - r_t = abs_depth_map # Absolute depth values (meters) - sin_theta_t = np.sin(theta_t_grid) - cos_theta_t = np.cos(theta_t_grid) - - # Compute denominator - denominator = r_t * sin_theta_t + r_t * cos_theta_t * tan_theta_t + epsilon - - # Avoid invalid denominator values - denominator[denominator <= 0] = epsilon - - # Calculate angular disparity - angle_disp = np.arctan(self.baseline / denominator) - theta_t_grid - - # Convert angular disparity to pixel disparity - disparity_map = (angle_disp / (unit_h * np.pi) - self.disp_offset) * self.disp_scale - plt.imshow(disparity_map, cmap='gray') plt.colorbar() plt.show() - - # Normalize disparity map for visualization - disparity_map_normalized = (disparity_map - disparity_map.min()) / (disparity_map.max() - disparity_map.min()) - disparity_map_normalized *= 255 - disparity_map_normalized = disparity_map_normalized.astype(np.uint8) return disparity_map, disparity_map_normalized - \ No newline at end of file + #def __depth2disparity(self, abs_depth_map): + # """ + # Convert absolute depth map to disparity map for 360-degree images. + + # Parameters: + # abs_depth_map (numpy.ndarray): Absolute depth map with pixel values as distances in meters. + + # Returns: + # disparity_map (numpy.ndarray): Disparity map with values representing disparity. + # disparity_map_normalized (numpy.ndarray): Normalized disparity map for visualization. + # """ + # # Define parameters for the conversion + # height, width = abs_depth_map.shape + # + # # Latitude grid (θ_l) + # epsilon = 1e-6 + # latitudes = np.linspace(-np.pi / 2, np.pi / 2, height) + # latitudes_grid = np.tile(latitudes[:, np.newaxis], (1, width)) + + # # Clamp extreme latitudes to avoid instability + # latitudes_grid = np.clip(latitudes_grid, -np.pi/2 + epsilon, np.pi/2 - epsilon) + + # plt.imshow(latitudes_grid, cmap="jet") + # plt.colorbar() + # plt.title("Latitude Grid") + # plt.show() + + # self.baseline = 0.176 + # + # + # # Calculate angular disparity Δθ(x, y) + # # Δθ(x, y) = arctan(B / (r_t * sin(θ_l) + r_t * cos(θ_l) * tan(θ_l))) - θ_l + # epsilon = 1e-6 # Small value to prevent instability + # denominator = ( + # abs_depth_map * np.sin(latitudes_grid) + + # abs_depth_map * np.cos(latitudes_grid) * np.tan(latitudes_grid) + + # epsilon + # ) + # angular_disparity = np.arctan(self.baseline / denominator) - latitudes_grid + # + # self.disp_scale = 10 + # self.disp_offset = np.median(angular_disparity) + # + # # Normalize the disparity map for saving + # pixel_angle_scale = 1 # Assume scale factor is 1 if not provided (can be adjusted if needed) + # disparity_map = (angular_disparity / pixel_angle_scale - self.disp_offset) * self.disp_scale + + # # Normalize for visualization + # disparity_map_normalized = (disparity_map - disparity_map.min()) / (disparity_map.max() - disparity_map.min()) + # disparity_map_normalized *= 255 + # disparity_map_normalized = disparity_map_normalized.astype(np.uint8) + + # # Debugging visualization + # plt.imshow(disparity_map, cmap="jet") + # plt.colorbar() + # plt.title("Disparity Map (Debugging)") + # plt.show() + + # return disparity_map, disparity_map_normalized \ No newline at end of file diff --git a/scripts/simple_tab.py b/scripts/simple_tab.py index ab01fa7..026ab0d 100644 --- a/scripts/simple_tab.py +++ b/scripts/simple_tab.py @@ -172,16 +172,15 @@ class PipelineWorker(QThread): self.progress.emit("File saved in edgenet-360\Output") def run_pipeline(self): - #self.clean_temp_files() - #self.shift_image() - #self.copy_file() - #self.run_depth_estimation() - self.run_depth_to_disparity() - - #self.run_material_recognition() - #self.run_edge_net() - #self.run_post_processing() - self.progress.emit("Pipeline completed!") + self.clean_temp_files() + self.shift_image() + self.copy_file() + self.run_depth_estimation() + #self.run_depth_to_disparity() + self.run_material_recognition() + self.run_edge_net() + self.run_post_processing() + self.progress.emit("Pipeline completed!") class SimpleTab(QWidget): def __init__(self, config_reader): -- GitLab