Suppress duplicate YOLO tile detections
GeoIntel CI / docs-smoke (push) Has been cancelled
GeoIntel CI / contract-smoke (push) Has been cancelled

This commit is contained in:
Codex
2026-07-09 10:55:45 +02:00
parent 638534f011
commit 3f5ca4c85e
24 changed files with 266 additions and 39 deletions
+18 -4
View File
@@ -98,6 +98,7 @@ for threshold in ${thresholds_normalized}; do
threshold_label="$(printf '%s' "${threshold}" | tr '.-' 'pm')"
run_log="${CALIBRATION_OUTPUT_DIR}/threshold_${threshold_label}.log"
quality_response="${CALIBRATION_OUTPUT_DIR}/threshold_${threshold_label}_quality_checks.json"
detection_run_response="${CALIBRATION_OUTPUT_DIR}/threshold_${threshold_label}_detection_run.json"
run_summary="${CALIBRATION_OUTPUT_DIR}/threshold_${threshold_label}_summary.json"
echo "-- Threshold ${threshold} (${run_index}) --"
@@ -121,9 +122,11 @@ for threshold in ${thresholds_normalized}; do
fi
curl -fsS "${BASE_URL%/}/api/v1/projects/${project_id}/quality-checks?limit=200" > "${quality_response}"
curl -fsS "${BASE_URL%/}/api/v1/detection/runs/${analysis_run_id}" > "${detection_run_response}"
"${PYTHON_BIN}" - \
"${quality_response}" \
"${detection_run_response}" \
"${run_summary}" \
"${threshold}" \
"${project_id}" \
@@ -134,11 +137,17 @@ for threshold in ${thresholds_normalized}; do
import json
import sys
quality_path, output_path, threshold, project_id, analysis_run_id, quality_check_id, detection_count, run_log = sys.argv[1:9]
quality_path, detection_run_path, output_path, threshold, project_id, analysis_run_id, quality_check_id, detection_count, run_log = sys.argv[1:10]
with open(quality_path, "r", encoding="utf-8") as handle:
payload = json.load(handle)
if "data" not in payload:
raise SystemExit("Quality-check list is not a canonical GeoIntel data envelope")
with open(detection_run_path, "r", encoding="utf-8") as handle:
detection_run_payload = json.load(handle)
if "data" not in detection_run_payload:
raise SystemExit("Detection run detail is not a canonical GeoIntel data envelope")
detection_run = detection_run_payload["data"]
run_result = detection_run.get("result_json") or {}
items = payload["data"].get("items") or []
quality_check = next((item for item in items if str(item.get("id")) == quality_check_id), None)
if quality_check is None:
@@ -157,6 +166,9 @@ summary = {
"detection_count": int(detection_count),
"quality_status": quality_check.get("status"),
"quality_score": quality_check.get("score"),
"raw_detection_count": run_result.get("raw_detection_count", int(detection_count)),
"suppressed_detection_count": run_result.get("suppressed_detection_count", 0),
"duplicate_iou_threshold": run_result.get("duplicate_iou_threshold"),
"precision": metrics.get("precision"),
"recall": metrics.get("recall"),
"f1_score": metrics.get("f1_score", metrics.get("f1")),
@@ -169,10 +181,12 @@ summary = {
with open(output_path, "w", encoding="utf-8") as handle:
json.dump(summary, handle, indent=2, sort_keys=True)
print(
"threshold={threshold} detections={detections} score={score} "
"threshold={threshold} detections={detections} raw={raw} suppressed={suppressed} score={score} "
"precision={precision} recall={recall} f1={f1} matches={matches} fp={fp} fn={fn}".format(
threshold=summary["threshold"],
detections=summary["detection_count"],
raw=summary["raw_detection_count"],
suppressed=summary["suppressed_detection_count"],
score=summary["quality_score"],
precision=summary["precision"],
recall=summary["recall"],
@@ -217,10 +231,10 @@ with open(summary_path, "w", encoding="utf-8") as handle:
print("")
print("Detection calibration summary")
print("threshold\tdetections\tscore\tprecision\trecall\tf1\tmatches\tfp\tfn")
print("threshold\tdetections\traw\tsuppressed\tscore\tprecision\trecall\tf1\tmatches\tfp\tfn")
for item in items:
print(
"{threshold:.2f}\t{detection_count}\t{quality_score}\t{precision}\t{recall}\t{f1_score}\t{matches}\t{false_positives}\t{false_negatives}".format(
"{threshold:.2f}\t{detection_count}\t{raw_detection_count}\t{suppressed_detection_count}\t{quality_score}\t{precision}\t{recall}\t{f1_score}\t{matches}\t{false_positives}\t{false_negatives}".format(
**item
)
)