test(extract): Verschmelzungsfall und Schwellenwert von drop_map_labels absichern

Ruling 43: beruehren sich Schriftzug und echte Flaeche (z.B. eine Mole), bilden sie eine
Komponente und bleiben beide stehen - dieselbe vorsichtige Richtung wie bei Beschriftungen
auf dem Festland, lieber ein Buchstabe zu viel als eine Mole zu wenig.
Ruling 44: ein Tippfehler in LABEL_MAX_NATURAL (0.2 statt 0.02) faellt jetzt in einem Test auf,
der knapp oberhalb der Schwelle liegt.
MAINLAND_MIN_SIZE-Kommentar auf zwei Saetze gekuerzt (Stil wie LAND_REACH_PX/PALM_VERGE),
Wortdopplung im Docstring entfernt. Kein Verhalten geaendert: 41 statt 39 Tests, beide neuen
Tests waren vor jeder Aenderung bereits gruen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
knsoandClaude Sonnet 5 committed 2026-09-12 19:22:25 +02:00
1 parent 4289378561
commit 70c35faf86
2 files changed
+27 -7

No files matched your search

+7 -7
View File
@@ -45,11 +45,11 @@ def class_shares(labels: np.ndarray) -> dict[str, float]:
NATURAL_CLASSES = ("gruen", "sand", "land")
LABEL_MAX_NATURAL = 0.02 # Anteil natuerlicher Merkmale, ab dem eine Flaeche als echt gilt
# Groesser als jeder gemessene Buchstabe (4.876-14.760 px am realen Mosaik) und weit kleiner
# als die Hauptlandmasse (5.852.263 px): ohne diese Untergrenze waere in einer Szene ohne
# echte Hauptlandmasse die groesste - und einzige - Komponente automatisch "Festland" und
# damit nie loeschbar, auch wenn sie selbst ein Schriftzug ist (siehe
# test_letter_shaped_island_becomes_water, wo genau das die einzige Komponente ist).
# Ab dieser Groesse zaehlt die groesste Komponente als Festland; die Ausnahme gilt nur ihr,
# ein Buchstabe kann sie also nur erben, wenn die Szene sonst gar kein Land enthaelt. Jeder
# Wert zwischen dem groessten gemessenen Buchstaben (14.760 px) und der echten Hauptlandmasse
# (5.852.263 px) aendert am realen Mosaik nichts; 15.000 liegt in dieser Spanne und bleibt
# zugleich unter den 16.200 px aus test_mainland_is_never_dropped.
MAINLAND_MIN_SIZE = 15_000
@@ -61,8 +61,8 @@ def drop_map_labels(labels: np.ndarray) -> np.ndarray:
Region: ein Schriftzug im Wasser bildet eine eigene, vom Festland getrennte Nicht-Wasser-
Komponente ohne jedes natuerliche Merkmal, waehrend eine echte Insel Gruen oder Sand
traegt. Die groesste Komponente ist das Festland und bleibt unangetastet, sofern sie
ueberhaupt gross genug ist, um ueberhaupt als Festland infrage zu kommen (MAINLAND_MIN_SIZE);
sonst wird auch sie nur ueber den Anteil natuerlicher Merkmale beurteilt.
ueberhaupt gross genug ist, um als Festland infrage zu kommen (MAINLAND_MIN_SIZE); sonst
wird auch sie nur ueber den Anteil natuerlicher Merkmale beurteilt.
"""
solid = labels != CLASSES["wasser"]
if not solid.any():
+20
View File
@@ -58,3 +58,23 @@ def test_mainland_is_never_dropped():
labels[10:190, 10:100] = CLASSES["stadt"]
out = drop_map_labels(labels)
assert (out[10:190, 10:100] == CLASSES["stadt"]).all()
def test_lettering_touching_a_real_area_is_kept():
"""Beruehren sich Schriftzug und echte Flaeche, bilden sie eine Komponente, und es bleibt
beides stehen. Die vorsichtige Richtung: lieber ein Buchstabe zu viel als eine Mole zu
wenig. Dieselbe Entscheidung wie bei den Beschriftungen auf dem Festland."""
labels = np.full((200, 200), CLASSES["wasser"], dtype=np.uint8)
labels[40:60, 40:120] = CLASSES["strasse"] # Schriftzug, fuer sich genommen 0 % natuerlich
labels[60:90, 100:140] = CLASSES["stadt"] # Mole, beruehrt ihn an der Kante
labels[70:85, 110:135] = CLASSES["gruen"] # ... und traegt Gruen: echte Flaeche
out = drop_map_labels(labels)
assert (out[40:60, 40:120] == CLASSES["strasse"]).all()
def test_five_percent_of_green_already_counts_as_a_real_area():
"""Die Grenze liegt bei 2 %. Mit 5 % Gruen muss die Flaeche bleiben - daran faellt auch
ein Tippfehler in LABEL_MAX_NATURAL auf (0.2 statt 0.02), der sonst durchginge."""
labels = np.full((200, 200), CLASSES["wasser"], dtype=np.uint8)
labels[40:140, 40:140] = CLASSES["stadt"] # 10.000 px, unter MAINLAND_MIN_SIZE
labels[40:62, 40:63] = CLASSES["gruen"] # 506 px, also gut 5 %
out = drop_map_labels(labels)
assert (out[40:140, 40:140] != CLASSES["wasser"]).all()