mirror of
https://github.com/azaion/gps-denied-onboard.git
synced 2026-04-23 01:36:36 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import pytest
|
||||
pytest.skip("Obsolete test file replaced by test_f09_local_geospatial_anchoring", allow_module_level=True)
|
||||
|
||||
import os
|
||||
import numpy as np
|
||||
import cv2
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
# Trigger deep learning model mocks for CI/CD environments
|
||||
os.environ["USE_MOCK_MODELS"] = "1"
|
||||
from f09_metric_refinement import MetricRefinement, TileBounds, GPSPoint
|
||||
|
||||
@pytest.fixture
|
||||
def metric_refinement():
|
||||
"""Initializes the F09 Metric Refinement module with CPU-based mock models."""
|
||||
return MetricRefinement(device="cpu", max_keypoints=100)
|
||||
|
||||
@pytest.fixture
|
||||
def dummy_tile_bounds():
|
||||
return TileBounds(
|
||||
nw=GPSPoint(lat=48.001, lon=37.0),
|
||||
ne=GPSPoint(lat=48.001, lon=37.001),
|
||||
sw=GPSPoint(lat=48.0, lon=37.0),
|
||||
se=GPSPoint(lat=48.0, lon=37.001),
|
||||
center=GPSPoint(lat=48.0005, lon=37.0005),
|
||||
gsd=0.5 # 0.5 meters per pixel
|
||||
)
|
||||
|
||||
class TestMetricRefinement:
|
||||
|
||||
def test_compute_homography_success(self, metric_refinement):
|
||||
"""Tests that sufficient matches successfully generate a homography matrix and MRE."""
|
||||
# Create dummy images
|
||||
uav_image = np.zeros((256, 256, 3), dtype=np.uint8)
|
||||
satellite_tile = np.zeros((512, 512, 3), dtype=np.uint8)
|
||||
|
||||
# Because we are using USE_MOCK_MODELS=1, SuperPoint and LightGlue will
|
||||
# emit random matched tensors. We need to mock cv2.findHomography to
|
||||
# guarantee a deterministic matrix return for the test.
|
||||
with patch('f09_metric_refinement.cv2.findHomography') as mock_find_h:
|
||||
# Return an identity homography matrix and an all-inlier mask of 25 points
|
||||
mock_find_h.return_value = (np.eye(3), np.ones((25, 1), dtype=np.uint8))
|
||||
|
||||
H, mask, total_corr, mre = metric_refinement.compute_homography(uav_image, satellite_tile)
|
||||
|
||||
assert H is not None
|
||||
assert np.array_equal(H, np.eye(3))
|
||||
assert mask is not None
|
||||
assert np.sum(mask) == 25
|
||||
assert total_corr == 25
|
||||
# Identity matrix applied to identical points yields 0.0 error
|
||||
assert isinstance(mre, float)
|
||||
|
||||
def test_extract_gps_from_alignment(self, metric_refinement, dummy_tile_bounds):
|
||||
"""Verifies pixel-to-GPS interpolation using the homography matrix and tile GSD."""
|
||||
# Simulate a homography that translates the UAV center by exactly 100 pixels on X and 50 pixels on Y
|
||||
H = np.array([
|
||||
[1.0, 0.0, 100.0],
|
||||
[0.0, 1.0, 50.0],
|
||||
[0.0, 0.0, 1.0]
|
||||
])
|
||||
|
||||
image_center = (200, 200) # (cx, cy)
|
||||
|
||||
# Expected Satellite Pixel = (200+100, 200+50) = (300, 250)
|
||||
gps = metric_refinement.extract_gps_from_alignment(H, dummy_tile_bounds, image_center)
|
||||
|
||||
assert gps is not None
|
||||
# The GPS should be shifted South and East from the NW corner
|
||||
assert gps.lat < dummy_tile_bounds.nw.lat
|
||||
assert gps.lon > dummy_tile_bounds.nw.lon
|
||||
|
||||
def test_compute_match_confidence(self, metric_refinement):
|
||||
"""Verifies the heuristic confidence scoring based on inliers and reprojection error."""
|
||||
|
||||
# High confidence: Lots of inliers, low MRE
|
||||
conf_high = metric_refinement.compute_match_confidence(inlier_count=60, total_correspondences=100, reprojection_error=0.5)
|
||||
assert conf_high >= 0.8
|
||||
|
||||
# Medium confidence: Decent inliers, high MRE
|
||||
conf_med = metric_refinement.compute_match_confidence(inlier_count=30, total_correspondences=100, reprojection_error=2.5)
|
||||
assert 0.5 <= conf_med <= 0.8
|
||||
|
||||
# Low confidence: Few inliers
|
||||
conf_low = metric_refinement.compute_match_confidence(inlier_count=10, total_correspondences=100, reprojection_error=5.0)
|
||||
assert conf_low < 0.5
|
||||
|
||||
# Zero correspondences
|
||||
conf_zero = metric_refinement.compute_match_confidence(inlier_count=0, total_correspondences=0, reprojection_error=0.0)
|
||||
assert conf_zero == 0.0
|
||||
Reference in New Issue
Block a user