From fa958d31f6234e5fcb8c4135a2e547d36809006b Mon Sep 17 00:00:00 2001 From: BreakPilot Dev Date: Mon, 9 Feb 2026 23:52:35 +0100 Subject: [PATCH] feat(ocr): Add CV Document Reconstruction Pipeline for vocabulary extraction New OCR method using classical Computer Vision: high-res rendering (432 DPI), deskew, dewarp, binarization, projection-profile layout analysis, multi-pass Tesseract OCR with region-specific PSM, and Y-coordinate line alignment. Includes bugfix for convert_pdf_to_image call (line 869) and 39 unit tests. Co-Authored-By: Claude Opus 4.6 --- admin-v2/app/(admin)/ai/ocr-compare/page.tsx | 82 +- klausur-service/backend/cv_vocab_pipeline.py | 1019 +++++++++++++++++ .../backend/tests/test_cv_vocab_pipeline.py | 569 +++++++++ .../backend/vocab_worksheet_api.py | 476 +++++++- 4 files changed, 2096 insertions(+), 50 deletions(-) create mode 100644 klausur-service/backend/cv_vocab_pipeline.py create mode 100644 klausur-service/backend/tests/test_cv_vocab_pipeline.py diff --git a/admin-v2/app/(admin)/ai/ocr-compare/page.tsx b/admin-v2/app/(admin)/ai/ocr-compare/page.tsx index d2ee594..4c2e69d 100644 --- a/admin-v2/app/(admin)/ai/ocr-compare/page.tsx +++ b/admin-v2/app/(admin)/ai/ocr-compare/page.tsx @@ -93,6 +93,15 @@ const OCR_METHODS = { description: 'ARM64-nativ, Standard', enabled: true, }, + cv_pipeline: { + id: 'cv_pipeline', + name: 'Loesung E: Document Reconstruction', + shortName: 'E: Doc Recon', + model: 'opencv + tesseract (multi-pass)', + color: 'green', + description: 'CV-Pipeline: Deskew, Dewarp, Binarisierung, Multi-Pass OCR', + enabled: true, + }, } export default function OCRComparePage() { @@ -115,7 +124,7 @@ export default function OCRComparePage() { const [uploading, setUploading] = useState(false) // Method Selection - const [selectedMethods, setSelectedMethods] = useState(['vision_llm', 'tesseract']) + const [selectedMethods, setSelectedMethods] = useState(['vision_llm', 'tesseract', 'cv_pipeline']) // QR Upload State const [showQRModal, setShowQRModal] = useState(false) @@ -133,6 +142,9 @@ export default function OCRComparePage() { const [showGridOverlay, setShowGridOverlay] = useState(true) const [selectedCell, setSelectedCell] = useState(null) const [showCellDialog, setShowCellDialog] = useState(false) + const [showMmGrid, setShowMmGrid] = useState(false) + const [showTextAtPosition, setShowTextAtPosition] = useState(false) + const [editableText, setEditableText] = useState(false) // Block Review State const [blockReviewMode, setBlockReviewMode] = useState(false) @@ -651,6 +663,7 @@ export default function OCRComparePage() { blue: { bg: 'bg-blue-50', border: 'border-blue-300', text: 'text-blue-700' }, red: { bg: 'bg-red-50', border: 'border-red-300', text: 'text-red-700' }, purple: { bg: 'bg-purple-50', border: 'border-purple-300', text: 'text-purple-700' }, + green: { bg: 'bg-green-50', border: 'border-green-300', text: 'text-green-700' }, } return colors[color]?.[type] || colors.slate[type] } @@ -839,7 +852,7 @@ export default function OCRComparePage() { {/* Grid Analysis Button */}