Skip to content

Latest commit

 

History

History
293 lines (218 loc) · 10.5 KB

File metadata and controls

293 lines (218 loc) · 10.5 KB

Erkennungsalgorithmus

Der Detektor erkennt Behördenstempel auf gescannten Dokumenten und Fotos. Er verwendet einen zweistufigen Ansatz: farbbasierte Erkennung als primäre Methode und einen Graustufen-Kreisdetektor als Fallback. Beide Stufen wenden Formfilter, Positionsheuristiken und Dichtebewertung an, um Kandidaten zu bewerten und den besten Treffer auszuwählen.

Pipeline-Übersicht

Eingabe (Bild oder PDF-Seite)
  │
  ├─► Stufe 1: Farbbasierte Erkennung
  │     │
  │     ├─ 1. HSV-Farbmaskierung (rote, blaue, lila Tinte)
  │     ├─ 2. Morphologische Bereinigung (Lücken schließen, Rauschen entfernen)
  │     ├─ 3. Konturextraktion + Formfilter
  │     ├─ 4. Überlappende Bounding-Boxen zusammenführen
  │     ├─ 5. Bewertung: Farbdichte × Positionsgewicht
  │     └─ 6. Besten Kandidaten auswählen
  │
  ├─► Stufe 2: Graustufen-Kreis-Fallback (nur wenn Stufe 1 nichts findet)
  │     │
  │     ├─ 1. Gaußscher Weichzeichner + Canny-Kantenerkennung
  │     ├─ 2. Hough-Kreiserkennung
  │     ├─ 3. Tintendichte-Filterung
  │     ├─ 4. Bogenkontinuität-Bewertung
  │     ├─ 5. Bewertung: Dichtescore × Bogenkontinuität × Positionsgewicht
  │     └─ 6. Besten Kandidaten auswählen (Score > 0,40)
  │
  └─► OCR (EasyOCR) auf erkannter Stempelregion

Stufe 1: Farbbasierte Erkennung

1.1 HSV-Farbmaskierung

Das Bild wird in den HSV-Farbraum konvertiert. Eine Binärmaske wird erstellt, indem alle Pixel kombiniert werden, die in einen der folgenden Stempeltinten-Bereiche fallen:

Farbe Farbton (H) Sättigung (S) Hellwert (V)
Rot 0–10 100–255 50–255
Rot 160–180 100–255 50–255
Blau 100–130 100–255 50–255
Lila 130–160 100–255 50–255

Die Mindestsättigung von 100 stellt sicher, dass schwarzer/grauer Text und blasse Druckfarben ausgeschlossen werden — nur kräftige Stempeltinten passieren den Filter.

1.2 Morphologische Bereinigung

Zwei morphologische Operationen mit einem 11×11 elliptischen Kernel:

  1. CLOSE (4 Iterationen) — füllt kleine Lücken in der Stempeltinte (z. B. verblasste Bereiche)
  2. OPEN (3 Iterationen) — entfernt kleine Sprenkel und Rauschen

1.3 Konturextraktion + Formfilter

Externe Konturen werden aus der bereinigten Maske extrahiert. Jede Kontur muss alle folgenden Filter bestehen:

Filter Schwellwert Zweck
Fläche 15 000–250 000 px² Rauschen (zu klein) und große Farbflächen abweisen
Seitenverhältnis < 2,5 Langgestreckte Textzeilen abweisen
Rundheit >= 0,30 Nicht-kreisförmige Formen abweisen (1,0 = perfekter Kreis)
Farbdichte >= 3 % Bounding-Box muss ausreichend Tinte enthalten

Die Rundheit ist definiert als:

Rundheit = 4π × Fläche / Umfang²

Ein perfekter Kreis ergibt 1,0; langgestreckte Textzeilen liegen deutlich unter 0,30.

Jede bestehende Kontur erhält eine gepolsterte Bounding-Box (+20 px auf jeder Seite, begrenzt auf die Bildränder) für zusätzlichen OCR-Kontext.

1.4 Überlappende Boxen zusammenführen

Überlappende Erkennungen werden mittels Fixpunkt-IoU-Iteration zusammengeführt:

  • Wenn zwei Boxen mit IoU > 15 % überlappen, werden sie zur Vereinigung zusammengeführt
  • Die Iteration wiederholt sich, bis keine weiteren Zusammenführungen stattfinden
  • Der Fixpunkt-Ansatz verhindert „Schneeballeffekte" durch verkettete Zusammenführungen

1.5 Bewertung

Jeder Kandidat erhält einen Gesamtscore:

Gesamtscore = Farbdichte × Positionsgewicht

Dabei ist:

  • Farbdichte = Anteil der Pixel innerhalb der Bounding-Box, die farbige Tinte sind
  • Positionsgewicht = vertikaler Positionsfaktor (siehe Positionsheuristiken)

1.6 Auswahl

Kandidaten werden nach Gesamtscore sortiert (absteigend). Nur der beste Kandidat pro Dokument wird behalten:

  • Einzelbilder: 1 bester Kandidat
  • Mehrseitige PDFs: 1 bester Kandidat über alle Seiten hinweg

Stufe 2: Graustufen-Kreis-Fallback

Wird nur aktiviert, wenn Stufe 1 keine farbigen Stempelkandidaten findet. Entwickelt für schwarze oder graue Stempel, die den Farbfilter nicht auslösen.

2.1 Kantenerkennung

Bild → Graustufen → Gaußscher Weichzeichner (9×9, σ=2) → Canny (50, 150)

2.2 Hough-Kreiserkennung

Parameter:

Parameter Wert
dp 1,2
minDist 200 px
param1 100
param2 80
minRadius 60 px
maxRadius 200 px

Erwartete Stempelgröße bei 150 DPI: Radius 60–200 px (Durchmesser ca. 2–7 cm).

2.3 Tintendichte-Filterung

Für jeden erkannten Kreis wird eine binarisierte Tintenmaske erstellt (Schwellwert 160, invertiert). Der Anteil dunkler Pixel innerhalb der Bounding-Box des Kreises muss folgende Bedingung erfüllen:

8 % <= Tintendichte <= 60 %
  • Unter 8 %: zu blass, wahrscheinlich kein Stempel
  • Über 60 %: zu dicht, wahrscheinlich ein Textblock oder eine Vollgrafik

2.4 Bogenkontinuität-Bewertung

Misst, wie viel des Kreisumfangs einen sichtbar gezeichneten Rand aufweist:

  1. 72 Punkte gleichmäßig entlang des Umfangs abtasten (alle 5 Grad)
  2. An jedem Punkt eine 5×5-Nachbarschaft auf Canny-Kantenpixel prüfen
  3. Den längsten aufeinanderfolgenden Lauf von Treffern finden (mit Umlauf)
  4. Score = längster_Lauf / 72

Typische Werte:

  • Echte Stempel mit gezeichnetem Rand: 0,6–1,0
  • Fehlerkennungen aus Text: 0,05–0,30

2.5 Kombinierter Score

Dichtescore = max(0,0;  1,0 − |Tintendichte − 0,25| / 0,35)
Score = Dichtescore × Bogenkontinuität × Positionsgewicht
  • Dichtescore erreicht sein Maximum bei Tintendichte = 0,25 (ideale Stempeldichte) und fällt an den Extremen auf null
  • Bogenkontinuität belohnt Kreise mit sichtbar gezeichnetem Rand
  • Positionsgewicht wendet dieselbe Positionsheuristik wie in Stufe 1 an

Nur Kandidaten mit Score > 0,40 werden zurückgegeben.


Positionsheuristiken

Behördenstempel werden fast immer im unteren Bereich eines Dokuments platziert, in der Nähe von Unterschriften. Logos und Briefköpfe befinden sich im Kopfbereich. Das Positionsgewicht nutzt dies, um Fehlerkennungen im Kopfbereich abzuweisen und Kandidaten im unteren Seitenbereich zu bevorzugen.

y_Verhältnis = BBox_Mittelpunkt_y / Bildhöhe     (0,0 = oben, 1,0 = unten)
Zone y_Verhältnis Gewicht
Kopfbereich (Abweisung) 0,0–0,15 0,0 (verworfen)
Oberer Inhaltsbereich 0,15–0,50 0,50–0,71
Unterer Inhaltsbereich 0,50–0,80 0,71–0,88
Fußbereich (Unterschriften) 0,80–1,0 0,88–1,0

Das Gewicht steigt linear von 0,5 (knapp unter dem Kopfbereich) auf 1,0 (Seitenende):

t = (y_Verhältnis − 0,15) / (1,0 − 0,15)
Positionsgewicht = 0,5 + 0,5 × t

Auswirkung auf die Bewertung

Beispiel mit zwei konkurrierenden Kandidaten:

Kandidat Farbdichte Position (y_Verhältnis) Positionsgewicht Gesamtscore
Kopfzeilen-Logo 0,12 0,08 0,0 verworfen
Stempel 0,08 0,75 0,85 0,068

Das Logo wird trotz höherer Farbdichte abgewiesen. Der Stempel gewinnt.


Texterkennung (OCR)

Nachdem der beste Stempelkandidat ausgewählt wurde, wird seine Bounding-Box-Region zugeschnitten und an EasyOCR (nur CPU) zur Textextraktion übergeben:

  • Sprachen: Deutsch + Englisch (konfigurierbar)
  • Alle erkannten Textfragmente werden mit Leerzeichen verkettet

Ausgabeformat

Einzelbild

{
  "filename": "dokument.jpg",
  "stamp_count": 1,
  "stamps": [
    {
      "bbox": [x1, y1, x2, y2],
      "text": "IHK Elbe-Weser ...",
      "image": "<Base64-kodiertes PNG>"
    }
  ]
}

PDF-Dokument

{
  "filename": "dokument.pdf",
  "total_pages": 3,
  "total_stamps": 1,
  "pages": [
    { "page": 1, "stamp_count": 0, "stamps": [] },
    { "page": 2, "stamp_count": 0, "stamps": [] },
    {
      "page": 3,
      "stamp_count": 1,
      "stamps": [
        {
          "bbox": [x1, y1, x2, y2],
          "text": "...",
          "image": "<Base64>"
        }
      ]
    }
  ]
}

Konfigurierbare Konstanten

Konstante Standard Beschreibung
MIN_STAMP_AREA 15 000 Minimale Konturfläche in px²
MAX_STAMP_AREA 250 000 Maximale Konturfläche in px²
MIN_CIRCULARITY 0,30 Mindest-Rundheit (4πA/P²)
MAX_ASPECT_RATIO 2,5 Maximales Seitenverhältnis (Breite/Höhe)
REGION_PADDING 20 Randpuffer der Bounding-Box in px
IOU_MERGE_THRESH 0,15 IoU-Schwellwert zum Zusammenführen überlappender Boxen
MIN_COLOUR_DENSITY 0,03 Mindestanteil farbiger Pixel in der BBox
MAX_STAMPS_PER_PAGE 1 Maximale Anzahl zurückgegebener Stempelkandidaten
HEADER_ZONE 0,15 Oberer Seitenanteil als Kopfbereich (Abweisung)
POSITION_WEIGHT_MIN 0,5 Positionsgewicht am oberen Rand des Inhaltsbereichs
POSITION_WEIGHT_MAX 1,0 Positionsgewicht am Seitenende
HOUGH_MIN_RADIUS 60 Minimaler Kreisradius für Graustufen-Fallback
HOUGH_MAX_RADIUS 200 Maximaler Kreisradius für Graustufen-Fallback
MIN_INK_DENSITY 0,08 Mindestanteil dunkler Pixel (Graustufen)
MAX_INK_DENSITY 0,60 Maximalanteil dunkler Pixel (Graustufen)