Initial public release
GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
"""Segmentation must honour the same post-processing configuration as detection.
|
||||
|
||||
Segmentation reuses the detection suppressor but passed only the IoU threshold,
|
||||
so it silently fell back to the hardcoded containment constant while detection
|
||||
read a configured one. A deployment tuning containment for a promoted model
|
||||
changed detection behaviour and left segmentation on the old value.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from shapely.geometry import box
|
||||
|
||||
from app.core.config import Settings
|
||||
|
||||
|
||||
def test_segmentation_has_its_own_containment_setting() -> None:
|
||||
settings = Settings(_env_file=None)
|
||||
|
||||
assert settings.segmentation_containment_nms_threshold == pytest.approx(0.85)
|
||||
|
||||
|
||||
def test_the_setting_is_independent_of_the_detection_one() -> None:
|
||||
"""Masks and boxes overlap differently; one value need not fit both."""
|
||||
|
||||
settings = Settings(
|
||||
_env_file=None,
|
||||
yolo_containment_nms_threshold=0.7,
|
||||
segmentation_containment_nms_threshold=0.95,
|
||||
)
|
||||
|
||||
assert settings.yolo_containment_nms_threshold == pytest.approx(0.7)
|
||||
assert settings.segmentation_containment_nms_threshold == pytest.approx(0.95)
|
||||
|
||||
|
||||
def test_the_configured_value_reaches_the_suppressor() -> None:
|
||||
from app.services.detection_service import DetectionService
|
||||
|
||||
def candidate(name: str, geometry, confidence: float):
|
||||
return {
|
||||
"class_name": "building",
|
||||
"confidence": confidence,
|
||||
"geometry": geometry,
|
||||
"bbox": [0.0, 0.0, 1.0, 1.0],
|
||||
"source_tile_path": f"/tiles/{name}.tif",
|
||||
"properties": {"name": name},
|
||||
}
|
||||
|
||||
outer = candidate("outer", box(0, 0, 10, 10), 0.9)
|
||||
# Containment 0.9, IoU 0.09: only the containment rule can act on this pair.
|
||||
mostly_nested = candidate("mostly", box(8.2, 1, 10.2, 6), 0.5)
|
||||
|
||||
strict = DetectionService._suppress_duplicate_candidates(
|
||||
[outer, mostly_nested], iou_threshold=0.5, containment_threshold=0.95
|
||||
)
|
||||
loose = DetectionService._suppress_duplicate_candidates(
|
||||
[outer, mostly_nested], iou_threshold=0.5, containment_threshold=0.7
|
||||
)
|
||||
|
||||
assert len(strict) == 2
|
||||
assert len(loose) == 1
|
||||
Reference in New Issue
Block a user