expand AI-assisted review to full building corpus
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Jens
2026-08-09 18:37:08 +02:00
parent f9a466b221
commit 7e07fe8486
7 changed files with 112 additions and 50 deletions
+5
View File
@@ -6,6 +6,11 @@ model and dataset hashes, standard Ultralytics detection metrics and a separate
pure-background detection count. The output claim is validation ranking only;
the script neither reads protected test data nor promotes a model.
`render_operator_yolo_label_qa_contact_sheets.py` paginates complete visual
reviews with `--tiles-per-sheet` (default `64`). This keeps large corpora
inspectable while preserving deterministic tile selection, ordering, label
accounting and stable `contact_sheet_001.png` naming for the first page.
Setup-, import-, demo- en maintenance-scripts voor GeoIntel.
## WALOUS source provisioning
@@ -19,7 +19,7 @@ from PIL import Image, ImageDraw, ImageFont
JSON_NAME = "operator_yolo_label_qa_summary.json"
MARKDOWN_NAME = "operator_yolo_label_qa_contact_sheet.md"
CONTACT_SHEET_NAME = "contact_sheet_001.png"
CONTACT_SHEET_NAME_TEMPLATE = "contact_sheet_{index:03d}.png"
def parse_args() -> argparse.Namespace:
@@ -37,6 +37,12 @@ def parse_args() -> argparse.Namespace:
)
parser.add_argument("--columns", type=int, default=4, help="Contact-sheet columns")
parser.add_argument("--thumb-size", type=int, default=256, help="Rendered tile thumbnail size in pixels")
parser.add_argument(
"--tiles-per-sheet",
type=int,
default=64,
help="Maximum rendered cards per contact-sheet page. Default: 64.",
)
parser.add_argument(
"--blank-range-threshold",
type=int,
@@ -329,16 +335,17 @@ def build_report(summary: dict[str, Any], summary_path: Path, args: argparse.Nam
}
)
contact_sheets = []
if rendered_cards:
contact_sheets.append(
{
"path": CONTACT_SHEET_NAME,
"tile_count": len(rendered_cards),
"columns": args.columns,
"thumb_size": args.thumb_size,
}
)
if args.tiles_per_sheet <= 0:
raise ValueError("tiles_per_sheet must be positive")
contact_sheets = [
{
"path": CONTACT_SHEET_NAME_TEMPLATE.format(index=(start // args.tiles_per_sheet) + 1),
"tile_count": len(rendered_cards[start : start + args.tiles_per_sheet]),
"columns": args.columns,
"thumb_size": args.thumb_size,
}
for start in range(0, len(rendered_cards), args.tiles_per_sheet)
]
return (
{
@@ -350,6 +357,7 @@ def build_report(summary: dict[str, Any], summary_path: Path, args: argparse.Nam
"requested_sample_slugs": sorted(set(args.sample_slug)),
"columns": args.columns,
"thumb_size": args.thumb_size,
"tiles_per_sheet": args.tiles_per_sheet,
"selected_tile_count": len(selected_tiles),
"selected_sample_count": len(
{str(tile.get("sample_slug") or "unknown") for tile in selected_tiles}
@@ -424,8 +432,10 @@ def main() -> int:
summary = load_json(summary_path)
report, cards = build_report(summary, summary_path, args)
if cards:
build_contact_sheet(cards, args.columns, output_dir / CONTACT_SHEET_NAME)
for page_index, start in enumerate(range(0, len(cards), args.tiles_per_sheet), start=1):
page_cards = cards[start : start + args.tiles_per_sheet]
page_name = CONTACT_SHEET_NAME_TEMPLATE.format(index=page_index)
build_contact_sheet(page_cards, args.columns, output_dir / page_name)
(output_dir / JSON_NAME).write_text(json.dumps(report, indent=2, sort_keys=True), encoding="utf-8")
write_markdown(report, output_dir)