feat(extract): Beschriftungen suchen, Liste auf Vollständigkeit prüfen, Prüfbilder

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Opus 5 committed 2026-09-13 19:38:14 +02:00
1 parent b219013bbf
commit f098fe14b7
2 files changed
+251

No files matched your search

@@ -0,0 +1,56 @@
import numpy as np
from PIL import Image
from shapely.geometry import box
import find_annotations as fa
from leonida.annotations import Annotation, AnnotationList, Keep, parse_annotations
URBAN, WHITE, MAGENTA = (216, 216, 216), (248, 248, 248), (200, 0, 200)
WATER, COAST = np.array([48, 144, 192]), np.array([0, 200, 240])
def picture():
img = np.zeros((200, 300, 3), dtype=np.uint8)
img[:] = URBAN
img[40:70, 30:120] = WHITE # Schriftzug
for left in range(40, 100, 12):
img[120:140, left:left + 4] = MAGENTA # Markerschrift, harte Kanten
for offset in range(80): # weicher Küstenverlauf
weight = 1 - abs(offset - 40) / 40
img[:, 200 + offset] = np.round(WATER * (1 - weight) + COAST * weight).astype(np.uint8)
return img
def test_scan_finds_text_and_markers_but_not_a_soft_coast_gradient():
spots = fa.scan(picture())
assert sorted(s.kind for s in spots) == ["marker", "text_white"]
assert all(s.cols[1] <= 200 for s in spots)
text = next(s for s in spots if s.kind == "text_white")
assert (text.rows, text.cols) == ((40, 70), (30, 120))
assert text.chunk == "A1"
def test_uncovered_respects_annotation_and_keep_frames():
spots = fa.scan(picture())
text = next(s for s in spots if s.kind == "text_white")
marker = next(s for s in spots if s.kind == "marker")
covering = Annotation(1, "Text", "text_white", box(*text.centre, *text.centre).buffer(5).bounds, None)
keep = Keep(1, box(*marker.centre, *marker.centre).buffer(5).bounds, "echt")
assert fa.uncovered(spots, AnnotationList([covering], [keep])) == []
assert fa.uncovered(spots, AnnotationList([covering])) == [marker]
def test_proposal_is_a_valid_list_with_padded_frames():
spots = fa.scan(picture())
parsed = parse_annotations(fa.propose_toml(spots))
assert [a.kind for a in parsed.annotations] == [s.kind for s in spots]
text = next(a for a in parsed.annotations if a.kind == "text_white")
assert text.box == (-980.0, 2421.0, -871.0, 2470.0) # Pixel 30–119 / 40–69 plus 10 m Luft
def test_review_writes_one_page_per_entry_and_an_overview(tmp_path):
img = picture()
entry = Annotation(1, "Text", "text_white", (-980.0, 2420.0, -870.0, 2470.0), None)
written = fa.review(img, AnnotationList([entry]), Image.fromarray(img), tmp_path)
assert [p.name for p in written] == ["001-Text.png"]
assert (tmp_path / "uebersicht.png").exists()