Add "OCR neu + Grid" button to Grid Review
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 51s
CI / test-go-edu-search (push) Successful in 42s
CI / test-python-klausur (push) Failing after 2m53s
CI / test-python-agent-core (push) Successful in 21s
CI / test-nodejs-website (push) Successful in 55s

New endpoint POST /sessions/{id}/rerun-ocr-and-build-grid that:
1. Runs scan quality assessment
2. Applies CLAHE enhancement if degraded (controlled by enhance toggle)
3. Re-runs dual-engine OCR (RapidOCR + Tesseract) with min_conf filter
4. Merges OCR results and stores updated word_result
5. Builds grid with max_columns constraint

Frontend: Orange "OCR neu + Grid" button in GridToolbar.
Unlike "Neu berechnen" (which only rebuilds grid from existing words),
this button re-runs the full OCR pipeline with quality settings.

Now CLAHE toggle actually has an effect — it enhances the image
before OCR runs, not after.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-23 16:55:01 +02:00
parent 141f69ceaa
commit 00eb9f26f6
3 changed files with 209 additions and 0 deletions

View File

@@ -80,6 +80,38 @@ export function useGridEditor(sessionId: string | null) {
}
}, [sessionId, ipaMode, syllableMode, ocrEnhance, ocrMaxCols, ocrMinConf])
/** Re-run OCR with current quality settings, then rebuild grid */
const rerunOcr = useCallback(async () => {
if (!sessionId) return
setLoading(true)
setError(null)
try {
const params = new URLSearchParams()
params.set('ipa_mode', ipaMode)
params.set('syllable_mode', syllableMode)
params.set('enhance', String(ocrEnhance))
if (ocrMaxCols > 0) params.set('max_cols', String(ocrMaxCols))
if (ocrMinConf > 0) params.set('min_conf', String(ocrMinConf))
const res = await fetch(
`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/rerun-ocr-and-build-grid?${params}`,
{ method: 'POST' },
)
if (!res.ok) {
const data = await res.json().catch(() => ({}))
throw new Error(data.detail || `HTTP ${res.status}`)
}
const data: StructuredGrid = await res.json()
setGrid(data)
setDirty(false)
undoStack.current = []
redoStack.current = []
} catch (e) {
setError(e instanceof Error ? e.message : String(e))
} finally {
setLoading(false)
}
}, [sessionId, ipaMode, syllableMode, ocrEnhance, ocrMaxCols, ocrMinConf])
const loadGrid = useCallback(async () => {
if (!sessionId) return
setLoading(true)
@@ -998,5 +1030,6 @@ export function useGridEditor(sessionId: string | null) {
setOcrMaxCols,
ocrMinConf,
setOcrMinConf,
rerunOcr,
}
}

View File

@@ -67,6 +67,7 @@ export function StepGridReview({ sessionId, onNext, saveRef }: StepGridReviewPro
setOcrMaxCols,
ocrMinConf,
setOcrMinConf,
rerunOcr,
} = useGridEditor(sessionId)
const [showImage, setShowImage] = useState(true)
@@ -336,6 +337,14 @@ export function StepGridReview({ sessionId, onNext, saveRef }: StepGridReviewPro
onIpaModeChange={setIpaMode}
onSyllableModeChange={setSyllableMode}
/>
<button
onClick={rerunOcr}
disabled={loading}
className="ml-2 px-3 py-1.5 text-xs font-medium rounded border border-orange-300 dark:border-orange-700 bg-orange-50 dark:bg-orange-900/20 text-orange-700 dark:text-orange-300 hover:bg-orange-100 dark:hover:bg-orange-900/40 transition-colors disabled:opacity-50"
title="OCR komplett neu ausfuehren mit aktuellen Quality-Step-Einstellungen (CLAHE, MinConf), dann Grid neu bauen"
>
{loading ? 'OCR laeuft...' : 'OCR neu + Grid'}
</button>
</div>
{/* Split View: Image left + Grid right */}