data loading and plotting for results wip
This commit is contained in:
164
tools/plot_scripts/data_spherical_projection_as_trained.py
Normal file
164
tools/plot_scripts/data_spherical_projection_as_trained.py
Normal file
@@ -0,0 +1,164 @@
|
||||
import argparse
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import matplotlib.patches as mpatches
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from matplotlib.colors import LinearSegmentedColormap, ListedColormap
|
||||
from PIL import Image
|
||||
|
||||
# --- Setup output folders ---
|
||||
output_path = Path("/home/fedex/mt/plots/data_2d_projections_training")
|
||||
datetime_folder_name = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||
output_datetime_path = output_path / datetime_folder_name
|
||||
latest_folder_path = output_path / "latest"
|
||||
archive_folder_path = output_path / "archive"
|
||||
|
||||
for folder in (
|
||||
output_path,
|
||||
output_datetime_path,
|
||||
latest_folder_path,
|
||||
archive_folder_path,
|
||||
):
|
||||
folder.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
# --- Parse command-line arguments ---
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Plot two 2D projections as used in training (unstretched, grayscale)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--input1",
|
||||
type=Path,
|
||||
default=Path(
|
||||
"/home/fedex/mt/data/subter/new_projection/1_loop_closure_illuminated_2023-01-23.npy"
|
||||
),
|
||||
help="Path to first .npy file containing 2D projection data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--input2",
|
||||
type=Path,
|
||||
default=Path(
|
||||
"/home/fedex/mt/data/subter/new_projection/3_smoke_human_walking_2023-01-23.npy"
|
||||
),
|
||||
help="Path to second .npy file containing 2D projection data",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--frame1",
|
||||
type=int,
|
||||
default=955,
|
||||
help="Frame index to plot from first file (0-indexed)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--frame2",
|
||||
type=int,
|
||||
default=242,
|
||||
help="Frame index to plot from second file (0-indexed)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# --- Load the numpy projection data ---
|
||||
proj_data1 = np.load(args.input1)
|
||||
proj_data2 = np.load(args.input2)
|
||||
|
||||
# Choose the desired frames
|
||||
try:
|
||||
frame1 = proj_data1[args.frame1]
|
||||
frame2 = proj_data2[args.frame2]
|
||||
except IndexError as e:
|
||||
raise ValueError(f"Frame index out of range: {e}")
|
||||
|
||||
# Debug info: Print the percentage of missing data in each frame
|
||||
print(f"Frame 1 missing data percentage: {np.isnan(frame1).mean() * 100:.2f}%")
|
||||
print(f"Frame 2 missing data percentage: {np.isnan(frame2).mean() * 100:.2f}%")
|
||||
|
||||
# --- Create a figure with 2 vertical subplots ---
|
||||
fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1, figsize=(10, 5))
|
||||
|
||||
# Create custom colormap for missing data visualization
|
||||
missing_color = [1, 0, 0, 1] # Red with full alpha
|
||||
cmap_missing = ListedColormap([missing_color])
|
||||
|
||||
# Replace the plotting section
|
||||
for ax, frame, title in zip(
|
||||
(ax1, ax2),
|
||||
(frame1, frame2),
|
||||
(
|
||||
"Normal LiDAR Frame",
|
||||
"Degraded LiDAR Frame (Smoke)",
|
||||
),
|
||||
):
|
||||
# Create mask for missing data (directly from NaN values)
|
||||
missing_mask = np.isnan(frame)
|
||||
|
||||
# Plot the valid data in grayscale
|
||||
frame_valid = np.copy(frame)
|
||||
frame_valid[missing_mask] = 0 # Set missing values to black in base image
|
||||
im = ax.imshow(frame_valid, cmap="gray", aspect="equal", vmin=0, vmax=0.8)
|
||||
|
||||
# Overlay missing data in red with reduced alpha
|
||||
ax.imshow(
|
||||
missing_mask,
|
||||
cmap=ListedColormap([[1, 0, 0, 1]]), # Pure red
|
||||
alpha=0.3, # Reduced alpha for better visibility
|
||||
)
|
||||
|
||||
ax.set_title(title)
|
||||
ax.axis("off")
|
||||
|
||||
# Adjust layout
|
||||
plt.tight_layout()
|
||||
|
||||
# Create a more informative legend
|
||||
legend_elements = [
|
||||
mpatches.Patch(facecolor="red", alpha=0.7, label="Missing Data"),
|
||||
mpatches.Patch(facecolor="white", label="Close Distance (0m)"),
|
||||
mpatches.Patch(facecolor="gray", label="Mid Distance"),
|
||||
mpatches.Patch(facecolor="black", label="Far Distance (70m)"),
|
||||
]
|
||||
|
||||
# Add legend with better positioning and formatting
|
||||
fig.legend(
|
||||
handles=legend_elements,
|
||||
loc="center right",
|
||||
bbox_to_anchor=(0.98, 0.5),
|
||||
title="Distance Information",
|
||||
framealpha=1.0,
|
||||
)
|
||||
|
||||
# Save the plot
|
||||
output_file = output_datetime_path / "data_2d_projections_training.png"
|
||||
plt.savefig(output_file, dpi=300, bbox_inches="tight", pad_inches=0.1)
|
||||
plt.close()
|
||||
|
||||
print(f"Plot saved to: {output_file}")
|
||||
|
||||
# --- Create grayscale training images ---
|
||||
for degradation_status, frame_number, frame in (
|
||||
("normal", args.frame1, frame1),
|
||||
("smoke", args.frame2, frame2),
|
||||
):
|
||||
frame_gray = np.nan_to_num(frame, nan=0).astype(np.float32)
|
||||
gray_image = Image.fromarray(frame_gray, mode="F")
|
||||
gray_output_file = (
|
||||
output_datetime_path
|
||||
/ f"frame_{frame_number}_training_{degradation_status}.tiff"
|
||||
)
|
||||
gray_image.save(gray_output_file)
|
||||
print(f"Training image saved to: {gray_output_file}")
|
||||
|
||||
# --- Handle folder structure ---
|
||||
shutil.rmtree(latest_folder_path, ignore_errors=True)
|
||||
latest_folder_path.mkdir(exist_ok=True, parents=True)
|
||||
|
||||
for file in output_datetime_path.iterdir():
|
||||
shutil.copy2(file, latest_folder_path)
|
||||
|
||||
script_path = Path(__file__)
|
||||
shutil.copy2(script_path, output_datetime_path)
|
||||
shutil.copy2(script_path, latest_folder_path)
|
||||
|
||||
shutil.move(output_datetime_path, archive_folder_path)
|
||||
print(f"Output archived to: {archive_folder_path}")
|
||||
Reference in New Issue
Block a user