Spaces:
Running on Zero
Running on Zero
Download utils/visualization.py from happy0612/GeoNeXt: direct link, hf CLI and curl.
- Browser
- Download file 2.76 kB
-
https://huggingface.co/spaces/happy0612/GeoNeXt/resolve/main/utils/visualization.py
- Command line
-
hf download hf://spaces/happy0612/GeoNeXt/utils/visualization.py
-
curl -L -o visualization.py https://huggingface.co/spaces/happy0612/GeoNeXt/resolve/main/utils/visualization.py
2.76 kB
| """Shared prediction visualization and output helpers.""" | |
| from pathlib import Path | |
| import numpy as np | |
| from PIL import Image | |
| # ColorBrewer Spectral (reversed by default for disparity-style predictions). | |
| _SPECTRAL = np.asarray( | |
| [ | |
| [158, 1, 66], [213, 62, 79], [244, 109, 67], [253, 174, 97], | |
| [254, 224, 139], [255, 255, 191], [230, 245, 152], [171, 221, 164], | |
| [102, 194, 165], [50, 136, 189], [94, 79, 162], | |
| ], | |
| dtype=np.float32, | |
| ) | |
| def depth_to_vis(depth, reverse_color=True): | |
| """Convert a 2-D depth/disparity array to an RGB visualization.""" | |
| values = np.asarray(depth, dtype=np.float32) | |
| if values.ndim != 2: | |
| raise ValueError("depth must have shape [H, W]") | |
| finite = np.isfinite(values) | |
| normalized = np.zeros_like(values) | |
| if finite.any(): | |
| low = float(values[finite].min()) | |
| high = float(values[finite].max()) | |
| if high > low: | |
| normalized[finite] = (values[finite] - low) / (high - low) | |
| if reverse_color: | |
| normalized = 1.0 - normalized | |
| position = normalized * (len(_SPECTRAL) - 1) | |
| lower = np.floor(position).astype(np.intp) | |
| upper = np.minimum(lower + 1, len(_SPECTRAL) - 1) | |
| weight = (position - lower)[..., None] | |
| rgb = _SPECTRAL[lower] * (1.0 - weight) + _SPECTRAL[upper] * weight | |
| rgb[~finite] = 0 | |
| return Image.fromarray(np.rint(rgb).astype(np.uint8), mode="RGB") | |
| def normal_to_vis(normal): | |
| """Convert normal vectors in [-1, 1] to an RGB visualization.""" | |
| values = np.asarray(normal, dtype=np.float32) | |
| if values.ndim != 3 or values.shape[-1] != 3: | |
| raise ValueError("normal must have shape [H, W, 3]") | |
| rgb = np.rint((np.clip(values, -1.0, 1.0) + 1.0) * 127.5).astype(np.uint8) | |
| return Image.fromarray(rgb, mode="RGB") | |
| def save_prediction_outputs(output_root, stem, rgb, depth, normal): | |
| """Save raw predictions and their visualizations using the release layout.""" | |
| root = Path(output_root) | |
| directories = { | |
| name: root / name | |
| for name in ("depth_raw", "depth_vis", "normal_raw", "normal_vis", "rgb_recon") | |
| } | |
| for directory in directories.values(): | |
| directory.mkdir(parents=True, exist_ok=True) | |
| # Both public backends store normalized disparity in [0, 1]. | |
| depth = np.clip(np.asarray(depth, dtype=np.float32), 0.0, 1.0) | |
| normal = np.asarray(normal, dtype=np.float32) | |
| np.save(directories["depth_raw"] / (stem + ".npy"), depth) | |
| np.save(directories["normal_raw"] / (stem + ".npy"), normal) | |
| depth_to_vis(depth, reverse_color=True).save(directories["depth_vis"] / (stem + ".png")) | |
| normal_to_vis(normal).save(directories["normal_vis"] / (stem + ".png")) | |
| rgb.convert("RGB").save(directories["rgb_recon"] / (stem + ".png")) | |