Expand YOLO training AOIs safely
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-07-12 23:42:29 +02:00
parent 53cd38a5b2
commit 0f49c980ba
11 changed files with 310 additions and 7 deletions
+42 -2
View File
@@ -25,6 +25,12 @@ DEFAULT_GRB_MAX_FEATURES = 100000
REFERENCE_AOI_CATEGORY = "reference_aoi"
PURE_EMPTY_BACKGROUND_CATEGORY = "pure_empty_negative"
SPARSE_BACKGROUND_CATEGORY = "sparse_building_context"
TRAINING_EXPANSION_SAMPLE_SLUGS = frozenset(
{"olen_center", "lille_center", "oud_turnhout_center", "kasterlee_center"}
)
DEFAULT_VALIDATION_SAMPLE_SLUGS = frozenset(
{"turnhout", "retie", "westerlo", "arendonk_heide"}
)
requests: Any = None
rasterio: Any = None
Transformer: Any = None
@@ -92,6 +98,30 @@ SAMPLES: dict[str, OperatorSample] = {
center_lat=51.0909,
half_size_m=220.0,
),
"olen_center": OperatorSample(
slug="olen_center",
display_name="Olen center training expansion",
center_lon=4.8597257,
center_lat=51.1438611,
),
"lille_center": OperatorSample(
slug="lille_center",
display_name="Lille center training expansion",
center_lon=4.8242404,
center_lat=51.2382180,
),
"oud_turnhout_center": OperatorSample(
slug="oud_turnhout_center",
display_name="Oud-Turnhout center training expansion",
center_lon=4.9817086,
center_lat=51.3178319,
),
"kasterlee_center": OperatorSample(
slug="kasterlee_center",
display_name="Kasterlee center training expansion",
center_lon=4.9678120,
center_lat=51.2407915,
),
"postel_bos": OperatorSample(
slug="postel_bos",
display_name="Postel forest background candidate",
@@ -270,6 +300,10 @@ def background_category_for_sample(sample: OperatorSample, reference_feature_cou
return PURE_EMPTY_BACKGROUND_CATEGORY if reference_feature_count <= 0 else SPARSE_BACKGROUND_CATEGORY
def recommended_split_for_sample(sample: OperatorSample) -> str:
return "val" if sample.slug in DEFAULT_VALIDATION_SAMPLE_SLUGS else "train"
def apply_sample_overrides(
sample: OperatorSample,
*,
@@ -481,6 +515,7 @@ def fetch_reference(
reference["sample_role"] = sample.sample_role
reference["allow_empty_reference"] = sample.allow_empty_reference
reference["background_category"] = background_category_for_sample(sample, len(features))
reference["recommended_split"] = recommended_split_for_sample(sample)
reference["reference_page_limit"] = page_limit
reference["reference_max_features"] = max_features
reference["reference_pages_fetched"] = len(pages)
@@ -495,6 +530,7 @@ def fetch_reference(
props.setdefault("sample_slug", sample.slug)
props.setdefault("sample_role", sample.sample_role)
props.setdefault("background_category", background_category_for_sample(sample, len(features)))
props.setdefault("recommended_split", recommended_split_for_sample(sample))
reference_path.write_text(json.dumps(reference, ensure_ascii=False), encoding="utf-8")
return prepared_url(GRB_GBG_URL, ogc_params), len(features)
@@ -537,6 +573,7 @@ def prepare_sample(
"sample_role": sample.sample_role,
"allow_empty_reference": sample.allow_empty_reference,
"background_category": background_category,
"recommended_split": recommended_split_for_sample(sample),
"raster_path": str(ortho_path),
"reference_path": str(reference_path),
"reference_feature_count": reference_feature_count,
@@ -572,7 +609,8 @@ def write_readme(output_dir: Path, samples: list[dict[str, Any]]) -> None:
f"- `{sample['sample_slug']}`: `{Path(sample['raster_path']).name}` and "
f"`{Path(sample['reference_path']).name}`, "
f"{sample['reference_feature_count']} reference features, role `{sample['sample_role']}`, "
f"background category `{sample['background_category']}`."
f"background category `{sample['background_category']}`, "
f"recommended split `{sample['recommended_split']}`."
)
lines.append("")
lines.append("Purpose: configured-YOLO detection + persisted QA/QC validation with operator-provided files.")
@@ -602,7 +640,7 @@ def main() -> int:
write_readme(output_dir, samples)
manifest = {
"schema_version": 1,
"schema_version": 2,
"description": "GeoIntel operator real-data samples for configured-YOLO QA validation.",
"output_dir": str(output_dir),
"sample_width": args.width,
@@ -610,6 +648,8 @@ def main() -> int:
"half_size_scale": args.half_size_scale,
"reference_page_limit": args.reference_page_limit,
"reference_max_features": args.reference_max_features,
"default_validation_sample_slugs": sorted(DEFAULT_VALIDATION_SAMPLE_SLUGS),
"training_expansion_sample_slugs": sorted(TRAINING_EXPANSION_SAMPLE_SLUGS),
"samples": samples,
}
manifest_path = output_dir / args.manifest_name