Update OCR Pipeline docs: Grid Editor v4.7.0 with zone merging, heading detection, IPA fixes
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 24s
CI / test-go-edu-search (push) Successful in 25s
CI / test-python-klausur (push) Failing after 1m55s
CI / test-python-agent-core (push) Successful in 16s
CI / test-nodejs-website (push) Successful in 15s
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 24s
CI / test-go-edu-search (push) Successful in 25s
CI / test-python-klausur (push) Failing after 1m55s
CI / test-python-agent-core (push) Successful in 16s
CI / test-nodejs-website (push) Successful in 15s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# OCR Pipeline - Schrittweise Seitenrekonstruktion
|
||||
|
||||
**Version:** 4.3.0
|
||||
**Status:** Produktiv (Schritte 1–10 implementiert)
|
||||
**Version:** 4.7.0
|
||||
**Status:** Produktiv (Schritte 1–10 + Grid Editor implementiert)
|
||||
**URL:** https://macmini:3002/ai/ocr-pipeline
|
||||
|
||||
## Uebersicht
|
||||
@@ -148,13 +148,18 @@ klausur-service/backend/
|
||||
│ └── cv_vocab_pipeline.py # Computer Vision + NLP Algorithmen
|
||||
├── ocr_pipeline_api.py # FastAPI Router (Schritte 2-10)
|
||||
├── orientation_crop_api.py # FastAPI Router (Schritte 1 + 4)
|
||||
├── grid_editor_api.py # Grid Editor: build-grid, save-grid, grid-editor
|
||||
├── cv_ocr_engines.py # OCR-Engines, IPA-Korrektur, Britfone-Woerterbuch
|
||||
├── cv_box_detect.py # Box-Erkennung + Zonen-Aufteilung
|
||||
├── cv_graphic_detect.py # Grafik-/Bilderkennung (Region-basiert)
|
||||
├── cv_color_detect.py # Farbtext-Erkennung (HSV-Analyse)
|
||||
├── cv_words_first.py # Words-First Grid Builder (bottom-up)
|
||||
├── cv_vocab_types.py # Datentypen: PageZone, ColumnGeometry, etc.
|
||||
├── page_crop.py # Content-basierter Crop-Algorithmus
|
||||
├── ocr_pipeline_session_store.py # PostgreSQL Persistence
|
||||
├── layout_reconstruction_service.py # Fabric.js JSON + PDF/DOCX Export
|
||||
├── tests/
|
||||
│ └── test_grid_editor_api.py # 27 Tests fuer Grid Editor + IPA
|
||||
└── migrations/
|
||||
├── 002_ocr_pipeline_sessions.sql # Basis-Schema
|
||||
├── 003_add_row_result.sql # Row-Result Spalte
|
||||
@@ -311,6 +316,14 @@ Alle Endpoints unter `/api/v1/ocr-pipeline/`.
|
||||
| `POST` | `/sessions/{id}/reconstruction/validate` | Validierung speichern (Step 10) |
|
||||
| `GET` | `/sessions/{id}/reconstruction/validation` | Validierungsdaten abrufen |
|
||||
|
||||
### Grid Editor (Excel-aehnlich)
|
||||
|
||||
| Methode | Pfad | Beschreibung |
|
||||
|---------|------|--------------|
|
||||
| `POST` | `/sessions/{id}/build-grid` | Strukturiertes Grid aus Kombi-Wortdaten erstellen |
|
||||
| `POST` | `/sessions/{id}/save-grid` | Bearbeitetes Grid speichern |
|
||||
| `GET` | `/sessions/{id}/grid-editor` | Grid-Editor-Daten abrufen |
|
||||
|
||||
---
|
||||
|
||||
## Schritt 4: Zuschneiden/Crop (Detail)
|
||||
@@ -1057,6 +1070,169 @@ Body: {"cells": [{"cell_id": "r5_c2", "text": "corrected text"}]}
|
||||
|
||||
---
|
||||
|
||||
## Grid Editor (Detail)
|
||||
|
||||
Der Grid Editor baut aus den Kombi-Wortdaten (PaddleOCR + Tesseract) ein strukturiertes,
|
||||
Excel-aehnliches Grid mit Zonen, Spalten, Zeilen und Zellen. Er ersetzt die manuelle
|
||||
Rekonstruktion fuer Vokabelseiten mit komplexen Layouts (Bilder, Ueberschriften, IPA-Lautschrift).
|
||||
|
||||
**Dateien:**
|
||||
|
||||
| Datei | Beschreibung |
|
||||
|-------|--------------|
|
||||
| `grid_editor_api.py` | `_build_grid_core()` Pipeline, alle Steps |
|
||||
| `cv_ocr_engines.py` | IPA-Korrektur, Britfone-Woerterbuch, Garbled-IPA-Erkennung |
|
||||
| `cv_vocab_types.py` | `PageZone` (mit `image_overlays`), `ColumnGeometry` |
|
||||
| `tests/test_grid_editor_api.py` | 27 Tests |
|
||||
|
||||
### `_build_grid_core()` Pipeline
|
||||
|
||||
Die Grid-Erstellung laeuft in mehreren Steps:
|
||||
|
||||
```
|
||||
Kombi-Wortdaten
|
||||
│
|
||||
├─ Zone Merging: Content-Zonen durch Bilder zusammenfuegen
|
||||
│ → _merge_content_zones_across_boxes()
|
||||
│
|
||||
├─ Step 1: Zonen-Grid-Berechnung
|
||||
│ → Spalten (Column Union), Zeilen, Zellen pro Zone
|
||||
│
|
||||
├─ Step 2: Header-Zeilen erkennen + mergen
|
||||
│
|
||||
├─ Step 3: Ghost-Filter
|
||||
│ → _filter_border_ghosts(): Einzel-Char-Artefakte an Box-Raendern
|
||||
│
|
||||
├─ Step 4: Farb-Annotation
|
||||
│ → detect_word_colors(): HSV-Farbanalyse aller word_boxes
|
||||
│
|
||||
├─ Step 4c: Oversized Word Box Removal
|
||||
│ → word_boxes > 3x Median entfernen (Grafik-Artefakte)
|
||||
│
|
||||
├─ Step 5: Overlay-Wort-Filter
|
||||
│ → Woerter innerhalb image_overlays entfernen
|
||||
│
|
||||
├─ Step 5a: Heading Detection by Color + Height
|
||||
│ → _detect_heading_rows_by_color(): Farbige Ueberschriften erkennen
|
||||
│
|
||||
├─ Step 5b: Fix Unmatched Parentheses
|
||||
│
|
||||
├─ Step 5c: IPA Phonetic Correction
|
||||
│ → fix_cell_phonetics(): Garbled OCR-IPA durch Britfone ersetzen
|
||||
│
|
||||
└─ Step 5d: IPA Continuation Detection
|
||||
→ fix_ipa_continuation_cell(): Reine Klammer-Zellen als IPA-Fortsetzung
|
||||
```
|
||||
|
||||
### Zone Merging Across Images
|
||||
|
||||
`_merge_content_zones_across_boxes()` erkennt das Muster `[content, box, content]` und
|
||||
fuegt die Content-Zonen zu einer einzigen Zone zusammen. Die Box-Zonen werden als
|
||||
`image_overlays` auf der gemergten Zone gespeichert.
|
||||
|
||||
```
|
||||
Vorher: Zone 1 (content) → Zone 2 (box/Bild) → Zone 3 (content)
|
||||
Nachher: Zone 1 (content, mit image_overlays=[Zone 2])
|
||||
```
|
||||
|
||||
**PageZone.image_overlays:**
|
||||
|
||||
```json
|
||||
[{"y": 120, "height": 85, "x": 50, "width": 400, "box": {...}}]
|
||||
```
|
||||
|
||||
Box-Zonen die NICHT zwischen Content-Zonen liegen (z.B. "VOCABULARY" Header-Box)
|
||||
bleiben als eigenstaendige Zone erhalten.
|
||||
|
||||
### Heading Detection by Color + Height
|
||||
|
||||
`_detect_heading_rows_by_color()` erkennt farbige Zwischenueberschriften
|
||||
(z.B. "Unit 4: Bonnie Scotland") nach der Farb-Annotation:
|
||||
|
||||
1. **Farbkriterium:** ALLE word_boxes der Zeile haben `color_name != 'black'` (typisch: blau)
|
||||
2. **Hoehenkriterium:** Mittlere Worthoehe > 1.2× Median aller Woerter in der Zone
|
||||
|
||||
Erkannte Headings werden zu einer Spanning-Cell zusammengefuegt (`col_type: 'heading'`).
|
||||
|
||||
### Ghost-Filter
|
||||
|
||||
`_filter_border_ghosts()` entfernt einzelne Zeichen (a-z, A-Z, 0-9) die nahe an
|
||||
Box-Raendern erkannt werden — typische OCR-Artefakte von Rahmenlinien.
|
||||
|
||||
**Ausnahme:** Borderless Boxes (`border_thickness = 0`) ueberspringen den Ghost-Filter,
|
||||
da dort keine Rahmen-Artefakte entstehen.
|
||||
|
||||
### IPA Phonetic Correction (Step 5c)
|
||||
|
||||
PaddleOCR erkennt IPA-Symbole als ASCII-Zeichen:
|
||||
|
||||
| IPA-Symbol | OCR liest |
|
||||
|------------|-----------|
|
||||
| `ʒ` | `3` |
|
||||
| `ʃ` | `f` |
|
||||
| `ə` | `9` |
|
||||
| `ˈ` | `'` |
|
||||
| `ɪ` | `i` oder `1` |
|
||||
|
||||
**`fix_cell_phonetics()`** ersetzt garbled OCR-IPA durch korrekte Lautschrift aus dem
|
||||
Britfone-Woerterbuch (British English). Nur Zellen mit `col_type == 'column_en'` werden
|
||||
verarbeitet.
|
||||
|
||||
**`_text_has_garbled_ipa()`** erkennt garbled IPA anhand von:
|
||||
|
||||
- Typischen OCR-IPA-Zeichen: `' 3 9 @ : ;`
|
||||
- Bracket-Notation ohne echte IPA-Symbole: `[n, nn]`, `[1uedtX,1]`
|
||||
|
||||
### IPA Continuation Detection (Step 5d)
|
||||
|
||||
Vokabelseiten haben manchmal Zeilen, die nur Lautschrift enthalten (Fortsetzung
|
||||
des Headwords der vorherigen Zeile). Diese werden von PaddleOCR als garbled Text erkannt.
|
||||
|
||||
**`fix_ipa_continuation_cell()`:**
|
||||
|
||||
1. Prueft ob die Zelle **komplett in Klammern** steht (`[...]`) — Zellen wie
|
||||
"employee [im'ploi:]" werden NICHT ueberschrieben
|
||||
2. Sucht das Headword in der Zeile darueber
|
||||
3. Stripped Grammatik-Annotationen: `[sth.]`, `(adj.)` etc.
|
||||
4. Schlaegt IPA im Britfone-Woerterbuch nach
|
||||
5. Beruecksichtigt alle Wortteile (z.B. "close sth. down" → `[klˈəʊz dˈaʊn]`)
|
||||
|
||||
### `en_col_type` Erkennung
|
||||
|
||||
Die Erkennung der Englisch-Headword-Spalte nutzt **Bracket-IPA-Pattern-Count**
|
||||
statt "laengster Durchschnittstext":
|
||||
|
||||
1. Fuer jede `column_*`-Spalte: Zaehle Zellen mit `[` im Text
|
||||
2. Spalte mit den meisten Klammer-Mustern = `en_col_type`
|
||||
3. **Fallback:** Laengster Durchschnittstext (wenn keine Klammern vorhanden)
|
||||
|
||||
Dies verhindert, dass Beispielsatz-Spalten (laenger aber ohne IPA) faelschlicherweise
|
||||
als Headword-Spalte erkannt werden.
|
||||
|
||||
### Oversized Word Box Removal (Step 4c)
|
||||
|
||||
Entfernt `word_boxes` deren Flaeche > 3× der Median-Flaeche aller Woerter in der Zone.
|
||||
Diese sind typischerweise Grafik-Artefakte (z.B. ein einzelnes "N" das eine ganze
|
||||
Illustration abdeckt).
|
||||
|
||||
### Tests
|
||||
|
||||
```bash
|
||||
cd klausur-service/backend && pytest tests/test_grid_editor_api.py -v # 27 Tests
|
||||
```
|
||||
|
||||
| Klasse | Tests | Beschreibung |
|
||||
|--------|-------|--------------|
|
||||
| `TestZoneMerging` | 4 | Content-Zone-Merging ueber Box-Zonen |
|
||||
| `TestHeadingDetection` | 3 | Farb- + Hoehenbasierte Heading-Erkennung |
|
||||
| `TestGhostFilter` | 4 | Border-Ghost-Filterung inkl. Borderless |
|
||||
| `TestOversizedWordBoxes` | 2 | Grafik-Artefakt-Entfernung |
|
||||
| `TestGarbledIpaDetection` | 8 | Bracket-IPA, Continuation, en_col_type |
|
||||
| `TestColumnUnion` | 3 | Spalten-Vereinigung ueber Zonen |
|
||||
| `TestHeaderMerging` | 3 | Header-Zeilen zusammenfuegen |
|
||||
|
||||
---
|
||||
|
||||
## Wichtige Konstanten
|
||||
|
||||
| Konstante | Wert | Datei | Beschreibung |
|
||||
@@ -1360,6 +1536,7 @@ cd klausur-service/backend && pytest tests/test_paddle_kombi.py -v # 36 Tests
|
||||
|
||||
| Datum | Version | Aenderung |
|
||||
|-------|---------|----------|
|
||||
| 2026-03-20 | 4.7.0 | Grid Editor: Zone Merging ueber Bilder (`image_overlays`), Heading Detection (Farbe + Hoehe), Ghost-Filter (borderless-aware), Oversized Word Box Removal, IPA Phonetic Correction (Britfone), IPA Continuation Detection, `en_col_type` via Bracket-Count. 27 Tests. |
|
||||
| 2026-03-16 | 4.6.0 | Strukturerkennung (Schritt 8): Region-basierte Grafikerkennung (`cv_graphic_detect.py`) mit Zwei-Pass-Verfahren (Farbregionen + schwarze Illustrationen), Wort-Ueberlappungs-Filter, Box/Zonen/Farb-Analyse. Schritt laeuft nach Worterkennung. |
|
||||
| 2026-03-12 | 4.5.0 | Kombi-Modus (PaddleOCR + Tesseract): Beide Engines laufen parallel, Koordinaten werden IoU-basiert gematcht und confidence-gewichtet gemittelt. Ungematchte Tesseract-Woerter (Bullets, Symbole) werden hinzugefuegt. 3er-Toggle in OCR Overlay. |
|
||||
| 2026-03-12 | 4.4.0 | PaddleOCR Remote-Engine (`engine=paddle`): PP-OCRv5 Latin auf Hetzner x86_64. Neuer Microservice (`paddleocr-service/`), HTTP-Client (`paddleocr_remote.py`), Frontend-Dropdown-Option. Nutzt words_first Grid-Methode. |
|
||||
|
||||
Reference in New Issue
Block a user