File size: 5,224 Bytes
7a87926 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
#!/usr/bin/env python3
"""
Quick test of smart pairing optimization.
Uses pre-computed poses to skip DA3 inference.
"""
import logging
import sys
from pathlib import Path
import numpy as np
# Add project root to path
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
from ylff.services.ba_validator import BAValidator # noqa: E402
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def test_smart_pairing():
"""Test smart pairing with a small set of images."""
# Use existing images from previous run
image_dir = project_root / "data" / "ba_validation_results_rickroll_v2" / "ba_work" / "images"
if not image_dir.exists():
logger.error(f"Image directory not found: {image_dir}")
logger.info("Please run BA validation first to generate images")
return
image_paths = sorted(list(image_dir.glob("*.jpg")))[:10] # Use first 10 images
image_paths = [str(p) for p in image_paths]
logger.info(f"Testing with {len(image_paths)} images")
# Create dummy poses (simulate DA3 output)
# For a video, poses should be relatively close together
np.random.seed(42)
base_pose = np.eye(4)[:3, :]
poses = []
for i in range(len(image_paths)):
# Small random translation (simulating camera movement)
pose = base_pose.copy()
pose[:3, 3] = np.random.randn(3) * 0.1 * i # Gradually move
poses.append(pose)
poses = np.array(poses)
logger.info(f"Generated {len(poses)} poses")
# Initialize validator
validator = BAValidator(
work_dir=project_root / "data" / "test_smart_pairing",
)
# Test pair generation
logger.info("\n=== Testing Pair Generation ===")
# Sequential
pairs_seq = validator._generate_smart_pairs(image_paths, sequential_only=True)
logger.info(f"Sequential pairs: {len(pairs_seq)}")
# Spatial
pairs_spatial = validator._generate_smart_pairs(
image_paths,
poses=poses,
max_baseline=0.3,
min_baseline=0.05,
max_pairs_per_image=5,
)
logger.info(f"Spatial pairs: {len(pairs_spatial)}")
# Exhaustive
pairs_exhaustive = validator._generate_smart_pairs(image_paths)
logger.info(f"Exhaustive pairs: {len(pairs_exhaustive)}")
logger.info("\n=== Speedup Analysis ===")
logger.info(f"Sequential: {len(pairs_exhaustive) / len(pairs_seq):.1f}x fewer pairs")
logger.info(f"Spatial: {len(pairs_exhaustive) / len(pairs_spatial):.1f}x fewer pairs")
# Test actual matching (if features exist)
features_path = (
project_root / "data" / "ba_validation_results_rickroll_v2" / "ba_work" / "features.h5"
)
if features_path.exists():
logger.info("\n=== Testing Matching with Smart Pairs ===")
import time
from hloc import match_features
# Test with sequential pairs
pairs_file_seq = validator.work_dir / "pairs_seq.txt"
with open(pairs_file_seq, "w") as f:
for img1, img2 in pairs_seq:
f.write(f"{Path(img1).name} {Path(img2).name}\n")
matches_file_seq = validator.work_dir / "matches_seq.h5"
logger.info(f"Matching {len(pairs_seq)} sequential pairs...")
start = time.time()
try:
match_conf = match_features.confs["superpoint+lightglue"]
match_features.main(
conf=match_conf,
pairs=pairs_file_seq,
features=features_path,
matches=matches_file_seq,
)
elapsed_seq = time.time() - start
logger.info(f"✓ Sequential matching completed in {elapsed_seq:.2f}s")
except Exception as e:
logger.error(f"Matching failed: {e}")
elapsed_seq = None
# Test with exhaustive pairs (if we have time)
if len(pairs_exhaustive) < 50: # Only if reasonable
pairs_file_exh = validator.work_dir / "pairs_exh.txt"
with open(pairs_file_exh, "w") as f:
for img1, img2 in pairs_exhaustive:
f.write(f"{Path(img1).name} {Path(img2).name}\n")
matches_file_exh = validator.work_dir / "matches_exh.h5"
logger.info(f"Matching {len(pairs_exhaustive)} exhaustive pairs...")
start = time.time()
try:
match_features.main(
conf=match_conf,
pairs=pairs_file_exh,
features=features_path,
matches=matches_file_exh,
)
elapsed_exh = time.time() - start
logger.info(f"✓ Exhaustive matching completed in {elapsed_exh:.2f}s")
if elapsed_seq:
speedup = elapsed_exh / elapsed_seq
logger.info(f"\n=== Speedup: {speedup:.1f}x ===")
except Exception as e:
logger.error(f"Matching failed: {e}")
else:
logger.info(f"\nFeatures not found at {features_path}")
logger.info("Skipping matching test. Run full BA validation first.")
logger.info("\n=== Test Complete ===")
if __name__ == "__main__":
test_smart_pairing()
|