Files
AnyImage/src/anyimage/common/depth_data.py
nan e7aeeb21d4 Add tools and tests for AnyImage model management and documentation
- Implement sync_models.py for preparing and uploading ONNX artifacts.
- Create build_node.py for building and validating Blender scripts.
- Add docs.py for building and previewing documentation with Mike or MkDocs.
- Introduce model_exports.py for exporting PyTorch models to ONNX format.
- Develop pack.py for packaging the project with dependencies for different platforms.
- Add test_sync_models.py to validate sync_models functionality.
- Add test_tool_commands.py to ensure repository tools have correct command scripts.
- Initialize tools package with __init__.py.
2026-08-31 15:15:33 +08:00

81 lines
2.9 KiB
Python

"""Load and scale Depth file artifacts shared by Blender workflows."""
import json
from pathlib import Path
import bpy
from .image_data import depth_data_name, image_empty_bounds
def load_depth_metadata(path):
"""Read and validate the compact camera metadata beside a Depth texture."""
metadata = json.loads(Path(path).read_text(encoding="utf-8"))
try:
image_size = tuple(int(value) for value in metadata["image_size"])
intrinsics = tuple(
tuple(float(value) for value in row)
for row in metadata["intrinsics"]
)
reference_depth = float(metadata["reference_depth"])
except (KeyError, TypeError, ValueError) as error:
raise ValueError("Depth metadata is invalid") from error
if (
len(image_size) != 2
or min(image_size) <= 0
or len(intrinsics) != 3
or any(len(row) != 3 for row in intrinsics)
or intrinsics[0][0] <= 0.0
or intrinsics[1][1] <= 0.0
or reference_depth <= 0.0
):
raise ValueError("Depth metadata is invalid")
return {
"image_size": image_size,
"intrinsics": intrinsics,
"reference_depth": reference_depth,
}
def load_depth_result_image(path, source_object, metadata):
"""Load, validate, name, configure, and pack a generated Depth texture."""
image = bpy.data.images.load(str(path), check_existing=False)
try:
if tuple(int(value) for value in image.size) != metadata["image_size"]:
raise ValueError("Depth texture dimensions do not match its metadata")
image.name = depth_data_name(source_object)
image.colorspace_settings.name = "Non-Color"
image.alpha_mode = "CHANNEL_PACKED"
image.pack()
return image
except Exception:
bpy.data.images.remove(image, do_unlink=True)
raise
def camera_depth_values(image):
"""Return top-down camera Z and validity from a loaded Depth texture."""
import numpy as np
width, height = (int(value) for value in image.size)
pixels = np.empty(width * height * 4, dtype=np.float32)
image.pixels.foreach_get(pixels)
pixels = np.flipud(pixels.reshape((height, width, 4)))
return pixels[..., 2], pixels[..., 3] > 0.5
def depth_uniform_scale(source_object, metadata, bounds=None):
"""Convert model camera units uniformly into Image Empty local distance."""
import numpy as np
intrinsics = metadata["intrinsics"]
width, height = metadata["image_size"]
reference_depth = metadata["reference_depth"]
x_min, x_max, y_min, y_max = bounds or image_empty_bounds(source_object)
plane_width = x_max - x_min
plane_height = y_max - y_min
fx, fy = float(intrinsics[0][0]), float(intrinsics[1][1])
scale_x = plane_width * fx / (max(width - 1, 1) * reference_depth)
scale_y = plane_height * fy / (max(height - 1, 1) * reference_depth)
return float(np.sqrt(scale_x * scale_y))