Simam3D-GPU / tests /test_core.py
junaid-simamdigital's picture
Test malformed-pose fallback
10d6ded verified
Raw History Blame Contribute Delete
16.6 kB
import numpy as np
from pathlib import Path
from types import SimpleNamespace
from simam3d_core import (
FusionResult,
analyze_light_field,
classify_scene_hypothesis,
classify_fusion_support,
deterministic_demo_depth,
estimate_depth_light,
filter_fusion_by_support,
default_intrinsics,
depth_to_camera_points,
fuse_point_views,
fusion_metrics,
input_diversity_metrics,
gaussian_initialization,
normalize_map,
normalize_prediction_contract,
next_view_plan,
orbit_project_points,
project_world_points,
reprojection_consistency,
prepare_intrinsics,
reveal_uncertainty,
synthetic_orbit_poses,
write_confidence_ply,
write_gaussian_ply,
)
def test_input_diversity_flags_duplicate_views_without_rejecting_batch():
duplicate = input_diversity_metrics(["a", "a", "b"])
assert duplicate["has_duplicate_input_views"] is True
assert duplicate["unique_input_view_count"] == 2
assert duplicate["duplicate_input_view_count"] == 1
assert duplicate["near_duplicate_pair_count"] == 0
assert duplicate["input_diversity_status"] == "duplicate_inputs"
distinct = input_diversity_metrics(["a", "b"])
assert distinct["has_duplicate_input_views"] is False
assert distinct["input_diversity_status"] == "distinct_inputs"
near = input_diversity_metrics(["a", "b"], near_duplicate_pair_count=1)
assert near["input_diversity_status"] == "near_duplicate_inputs"
def test_fusion_support_classification_is_explicit_about_view_count_and_agreement():
assert classify_fusion_support({}, 1) == "single_view_baseline"
assert classify_fusion_support({"multi_view_voxel_fraction": 0.9}, 2, 1) == "duplicate_input_support"
assert classify_fusion_support({"multi_view_voxel_fraction": 0.9}, 2, 2, "depth_anything_3", 1) == "near_duplicate_input_support"
assert classify_fusion_support({"multi_view_voxel_fraction": 0.9}, 2, 2, "synthetic_orbit_prior") == "synthetic_prior_support"
assert classify_fusion_support({"multi_view_voxel_fraction": 0.05}, 3) == "low_multi_view_support"
assert classify_fusion_support({"multi_view_voxel_fraction": 0.25}, 3) == "partial_multi_view_support"
assert classify_fusion_support({"multi_view_voxel_fraction": 0.75}, 3) == "strong_multi_view_support"
def test_light_field_detector_returns_bright_side_and_bounded_confidence():
image = np.zeros((8, 8, 3), dtype=np.uint8)
image[:, 6:] = 255
result = analyze_light_field(image)
assert result["bright_centroid_x"] > 0.2
assert result["detector_confidence"] >= 0.0
assert result["detector_confidence"] <= 1.0
assert "directional" in result["lighting_label"]
def test_depth_light_estimate_returns_normalized_camera_direction():
depth = np.tile(np.linspace(0.0, 1.0, 8, dtype=np.float32), (8, 1))
colors = np.zeros((8, 8, 3), dtype=np.uint8)
colors[:, 5:] = 255
result = estimate_depth_light(depth, colors)
direction = np.array([result["light_direction_x"], result["light_direction_y"], result["light_direction_z"]])
assert np.isfinite(direction).all()
assert np.isclose(np.linalg.norm(direction), 1.0)
assert 0.0 <= result["photometric_confidence"] <= 1.0
def test_deterministic_demo_depth_is_shape_stable_and_explicitly_numeric():
colors = np.array([[[0, 0, 0], [255, 255, 255]]], dtype=np.uint8)
depth = deterministic_demo_depth(colors)
assert depth.shape == (1, 2)
assert np.allclose(depth, [[255.0, 0.0]])
def test_scene_hypothesis_is_explicit_and_transparent():
result = classify_scene_hypothesis("I think a garden is behind the portrait")
assert result["user_guess"].startswith("I think")
assert "outdoor" in result["semantic_cues"]
assert "nature" in result["semantic_cues"]
assert "not verified" in result["status"]
def test_reveal_uncertainty_preserves_shape_and_confidence_signal():
depth = np.tile(np.linspace(0.0, 1.0, 8, dtype=np.float32), (8, 1))
confidence = np.ones_like(depth)
result = reveal_uncertainty(depth, confidence)
assert result.shape == depth.shape
assert np.isfinite(result).all()
assert float(result.max()) <= 1.0
assert float(result.mean()) < 0.1
def test_next_view_plan_is_deterministic_and_prefers_gaps():
plan = next_view_plan(1)
assert len(plan) == 5
assert plan[0]["gap_from_existing_deg"] >= plan[-1]["gap_from_existing_deg"]
assert all(item["reason"] == "largest observed azimuth gap" for item in plan)
def test_next_view_plan_uses_observed_camera_centers_when_available():
camera_to_world = np.eye(4, dtype=np.float32)
camera_to_world[:3, 3] = [1.0, 0.0, 0.0]
world_to_camera = np.linalg.inv(camera_to_world)
plan = next_view_plan(1, np.asarray([world_to_camera], dtype=np.float32))
assert plan[0]["yaw_deg"] == 270.0
assert plan[0]["gap_from_existing_deg"] == 180.0
def test_orbit_projection_rotates_points_without_nan():
points = np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]], dtype=np.float32)
xy, depth = orbit_project_points(points, 90.0)
assert xy.shape == (2, 2)
assert depth.shape == (2,)
assert np.isfinite(xy).all()
assert np.isfinite(depth).all()
assert np.all(np.abs(xy) <= 1.0)
def test_prediction_contract_normalizes_single_view_and_optional_fields():
prediction = SimpleNamespace(depth=np.ones((4, 5), dtype=np.float32), conf=None)
depth, confidence, extrinsics, intrinsics, confidence_source, pose_source = normalize_prediction_contract(prediction, 1)
assert depth.shape == (1, 4, 5)
assert confidence.shape == depth.shape
assert extrinsics.shape == (1, 4, 4)
assert intrinsics.shape == (1, 3, 3)
assert confidence_source == "baseline_uniform"
assert pose_source == "synthetic_orbit_prior"
def test_prediction_contract_rejects_mismatched_confidence():
prediction = SimpleNamespace(
depth=np.ones((2, 4, 5), dtype=np.float32),
conf=np.ones((1, 4, 5), dtype=np.float32),
)
try:
normalize_prediction_contract(prediction, 2)
except ValueError as exc:
assert "confidence" in str(exc)
else:
raise AssertionError("mismatched DA3 confidence should be rejected")
def test_prediction_contract_downgrades_singular_poses_to_synthetic_prior():
prediction = SimpleNamespace(
depth=np.ones((1, 4, 5), dtype=np.float32),
conf=np.ones((1, 4, 5), dtype=np.float32),
extrinsics=np.zeros((1, 4, 4), dtype=np.float32),
)
_, _, extrinsics, _, _, pose_source = normalize_prediction_contract(prediction, 1)
assert extrinsics.shape == (1, 4, 4)
assert pose_source == "synthetic_orbit_prior"
def test_world_projection_reports_in_frame_points():
points = np.array([[0.0, 0.0, 1.0], [2.0, 0.0, 1.0]], dtype=np.float32)
pixels, depths, inside = project_world_points(points, None, None, 10, 10)
assert pixels.shape == (2, 2)
assert np.allclose(pixels[0], [5.0, 5.0])
assert np.isclose(depths[0], 1.0)
assert inside.tolist() == [True, False]
def test_reprojection_consistency_detects_self_consistent_depth():
depth = np.tile(np.linspace(0.0, 1.0, 6, dtype=np.float32), (6, 1))
points, _ = depth_to_camera_points(depth)
metrics = reprojection_consistency(points, depth, None, None)
assert metrics["coverage"] > 0.8
assert metrics["mean_absolute_error"] < 0.05
def test_normalize_map_handles_constant_and_nan_values():
assert np.all(normalize_map(np.ones((2, 2))) == 0)
normalized = normalize_map(np.array([[np.nan, 1.0], [2.0, 3.0]], dtype=np.float32))
assert normalized.shape == (2, 2)
assert np.isfinite(normalized).all()
assert normalized.max() == 1.0
def test_depth_projection_has_expected_shape():
depth = np.ones((4, 5), dtype=np.float32)
points, weights = depth_to_camera_points(depth, default_intrinsics(5, 4))
assert points.shape == (20, 3)
assert weights.shape == (20,)
assert np.isfinite(points).all()
def test_relative_depth_projection_matches_exporter_convention():
depth = np.array([[0.0, 1.0]], dtype=np.float32)
points, _ = depth_to_camera_points(depth)
assert points[0, 2] > points[1, 2]
def test_fusion_is_deterministic_and_voxel_reduces_duplicates():
depth = np.ones((3, 3), dtype=np.float32)
colors = np.zeros((3, 3, 3), dtype=np.uint8)
views = [(depth, np.ones_like(depth), None, None, colors), (depth, np.ones_like(depth), None, None, colors)]
first = fuse_point_views(views, voxel_size=0.1)
second = fuse_point_views(views, voxel_size=0.1)
assert len(first.points) < 18
assert np.array_equal(first.points, second.points)
assert fusion_metrics(first)["point_count"] == len(first.points)
assert fusion_metrics(first)["dominant_source_view_count"] == 1
assert fusion_metrics(first)["supported_source_view_count"] == 2
assert fusion_metrics(first)["multi_view_voxel_fraction"] == 1.0
def test_filter_fusion_by_support_prunes_weak_lineage_and_preserves_default():
depth = np.ones((3, 3), dtype=np.float32)
colors = np.zeros((3, 3, 3), dtype=np.uint8)
views = [(depth, np.ones_like(depth), None, None, colors), (depth, np.ones_like(depth), None, None, colors)]
result = fuse_point_views(views, voxel_size=0.1)
assert filter_fusion_by_support(result, 1) is result
filtered = filter_fusion_by_support(result, 2)
assert len(filtered.points) == len(result.points)
assert all(int(mask).bit_count() >= 2 for mask in filtered.source_masks)
mixed = FusionResult(
points=np.zeros((3, 3), dtype=np.float32),
colors=np.zeros((3, 3), dtype=np.uint8),
weights=np.ones(3, dtype=np.float32),
source_views=np.array([0, 1, 0], dtype=np.int32),
source_masks=np.array([1, 3, 2], dtype=np.int32),
)
pruned = filter_fusion_by_support(mixed, 2)
assert len(pruned.points) == 1
assert pruned.source_masks.tolist() == [3]
def test_extrinsics_move_camera_points_into_world_coordinates():
depth = np.ones((2, 2), dtype=np.float32)
colors = np.full((2, 2, 3), 127, dtype=np.uint8)
translation = np.eye(4, dtype=np.float32)
translation[0, 3] = 2.0
result = fuse_point_views([(depth, None, None, translation, colors)], voxel_size=0.0)
camera_points, _ = depth_to_camera_points(depth)
assert np.allclose(result.points[:, 0], camera_points[:, 0] - 2.0)
def test_zero_confidence_points_are_excluded():
depth = np.ones((2, 2), dtype=np.float32)
colors = np.zeros((2, 2, 3), dtype=np.uint8)
confidence = np.array([[1.0, 0.0], [0.0, 1.0]], dtype=np.float32)
result = fuse_point_views([(depth, confidence, None, None, colors)], voxel_size=0.0)
assert len(result.points) == 2
def test_constant_positive_confidence_remains_usable():
depth = np.ones((2, 2), dtype=np.float32)
colors = np.zeros((2, 2, 3), dtype=np.uint8)
result = fuse_point_views([(depth, np.ones_like(depth), None, None, colors)], voxel_size=0.0)
assert len(result.points) == 4
assert np.all(result.weights == 1.0)
def test_synthetic_orbit_poses_are_valid_and_distinct():
assert np.allclose(synthetic_orbit_poses(1)[0], np.eye(4, dtype=np.float32))
poses = synthetic_orbit_poses(4)
assert poses.shape == (4, 4, 4)
assert np.isfinite(poses).all()
assert not np.allclose(poses[0], poses[1])
assert np.allclose(poses[:, 3, :], np.array([[0, 0, 0, 1]] * 4, dtype=np.float32))
def test_gaussian_initialization_tracks_confidence():
opacity, log_scale = gaussian_initialization(np.array([0.0, 0.5, 1.0]), 3)
assert np.all(np.diff(opacity) > 0)
assert np.all(np.diff(log_scale) < 0)
assert np.isclose(opacity[0], 0.05)
assert np.isclose(opacity[-1], 0.95)
def test_voxel_fusion_uses_confidence_weighted_centroid_and_color():
depth = np.ones((1, 2), dtype=np.float32)
colors = np.array([[[255, 0, 0], [0, 0, 255]]], dtype=np.uint8)
intrinsics = np.array([[2.0, 0.0, -1.0], [0.0, 2.0, 0.5], [0.0, 0.0, 1.0]], dtype=np.float32)
first = fuse_point_views(
[(depth, np.array([[1.0, 0.5]], dtype=np.float32), intrinsics, None, colors)],
voxel_size=10.0,
)
assert len(first.points) == 1
assert first.colors[0, 0] > first.colors[0, 2]
assert np.isclose(first.weights[0], 0.75)
assert first.source_views[0] == 0
assert first.source_masks[0] == 1
assert fusion_metrics(first)["multi_view_voxel_fraction"] == 0.0
def test_confidence_ply_retains_per_point_evidence(tmp_path=None):
path = Path("confidence_test.ply")
try:
write_confidence_ply(
path,
np.array([[0.0, 0.0, 1.0]], dtype=np.float32),
np.array([[10, 20, 30]], dtype=np.uint8),
np.array([0.75], dtype=np.float32),
)
contents = path.read_text(encoding="utf-8")
assert "property float confidence" in contents
assert "property int source_view" in contents
assert "property int source_mask" in contents
assert "0 0 1 10 20 30 0.75 -1 0" in contents
finally:
if path.exists():
path.unlink()
def test_gaussian_ply_contains_3dgs_and_evidence_fields():
path = Path("gaussian_test.ply")
try:
write_gaussian_ply(
path,
np.array([[0.0, 0.0, 1.0]], dtype=np.float32),
np.array([[10, 20, 30]], dtype=np.uint8),
np.array([0.75], dtype=np.float32),
np.array([2], dtype=np.int32),
)
contents = path.read_text(encoding="utf-8")
assert "property float opacity" in contents
assert "property float confidence" in contents
assert "property int source_view" in contents
assert "property int source_mask" in contents
assert contents.rstrip().endswith("0.75 2 4")
finally:
if path.exists():
path.unlink()
def test_gaussian_ply_preserves_direct_parameters():
path = Path("gaussian_direct_test.ply")
try:
write_gaussian_ply(
path,
np.array([[0.0, 0.0, 1.0]], dtype=np.float32),
np.array([[100, 120, 140]], dtype=np.uint8),
scales=np.array([[0.1, 0.2, 0.3]], dtype=np.float32),
rotations=np.array([[0.0, 0.0, 0.0, 2.0]], dtype=np.float32),
opacities=np.array([0.8], dtype=np.float32),
)
contents = path.read_text(encoding="utf-8")
assert "property float scale_2" in contents
assert "property float rot_3" in contents
assert "0.8 -2.302585 -1.609438 -1.203973" in contents
assert contents.rstrip().endswith("1 -1 0")
finally:
path.unlink(missing_ok=True)
def test_normalized_intrinsics_are_converted_to_pixels():
normalized = np.array([[0.8, 0.0, 0.5], [0.0, 0.8, 0.5], [0.0, 0.0, 1.0]], dtype=np.float32)
pixels = prepare_intrinsics(normalized, 100, 50)
assert np.allclose(pixels, [[80, 0, 50], [0, 40, 25], [0, 0, 1]])
def test_identity_intrinsics_use_centered_default():
pixels = prepare_intrinsics(np.eye(3, dtype=np.float32), 100, 50)
assert np.allclose(pixels, default_intrinsics(100, 50))
def test_multiview_demo_contract_exports_reproducible_evidence(tmp_path):
depth = np.tile(np.linspace(0.1, 0.9, 12, dtype=np.float32), (10, 1))
views = []
for index, pose in enumerate(synthetic_orbit_poses(3)):
colors = np.zeros((10, 12, 3), dtype=np.uint8)
colors[..., index] = 180
confidence = np.full_like(depth, 1.0 - 0.15 * index)
views.append((depth, confidence, None, pose, colors))
result = fuse_point_views(views, voxel_size=0.03, max_points=5000)
assert len(result.points) > 0
metrics = fusion_metrics(result)
assert metrics["supported_source_view_count"] == 3
confidence_path = Path("fused_integration_test.ply")
gaussian_path = Path("gaussians_integration_test.ply")
try:
write_confidence_ply(confidence_path, result.points, result.colors, result.weights, result.source_views, result.source_masks)
write_gaussian_ply(gaussian_path, result.points, result.colors, result.weights, result.source_views, result.source_masks)
confidence_text = confidence_path.read_text(encoding="utf-8")
gaussian_text = gaussian_path.read_text(encoding="utf-8")
assert "property int source_mask" in confidence_text
assert "property float opacity" in gaussian_text
assert "property int source_mask" in gaussian_text
finally:
confidence_path.unlink(missing_ok=True)
gaussian_path.unlink(missing_ok=True)