feat: formula_img2latex 0.1.0 – Formelbilder geprüft durch LaTeX ersetzen
Nachbearbeitung für epub2md- und pdf2md-Ausgaben: scan → recognize (Vision-LLM lokal/OpenRouter) → verify → review → apply/revert. - Rendern mit pdflatex (Batch, Fehlerisolierung, unsichere Befehle gesperrt), Schrift-Presets cm/times/txfonts/palatino/stix/euler, automatische Wahl je Buch - Bildvergleich in Originalauflösung mit ¼-Pixel-Ausrichtung, Pixel/Punkt-Konsistenz - Kontrasttest gegen layouttreue Verwechslungsvarianten, Selbstkorrektur per Hill-Climbing - Pandoc/MathML-Prüfung vor jeder Annahme - pdf2md: Formelbild per Template-Matching auf der Seite finden, 600-dpi-Neuausschnitt - Review-Galerie auf localhost (Token-geschützt), idempotentes apply mit Sicherung, revert - calibrate: Messung an Formelbildern mit TeX im alt-Text (0/600 Falsch-Annahmen) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
eb72d0b0f2
1 changed files with 4363 additions and 0 deletions
649
Idee/02_IdeeFormulaImgToLaTeX.md
Normal file
649
Idee/02_IdeeFormulaImgToLaTeX.md
Normal file
|
|
@ -0,0 +1,649 @@
|
|||
<img src="https://r2cdn.perplexity.ai/pplx-full-logo-primary-dark%402x.png" style="height:64px;margin-right:32px"/>
|
||||
|
||||
# Ist bei Mathe-Lehrbüchern die Wahrscheinlichkeit höher, dass die LaTeX-Übersetzung der enthaltenen Formeln eher in der EPUB-Ausgabe oder in der PDF-Ausgabe enthalten sind, größer?
|
||||
|
||||
Eher in der **EPUB-Ausgabe** – allerdings mit einer wichtigen Einschränkung: Dort ist es technisch deutlich wahrscheinlicher, dass Formeln als strukturierte Daten vorliegen, typischerweise MathML und gelegentlich zusätzlich TeX/LaTeX als Alternativ- oder Quelldarstellung. In einer gewöhnlichen PDF sind Formeln meist nur als positionierte Glyphen oder Vektoren gespeichert, nicht als rekonstruierbarer LaTeX-Quelltext.[^1_1][^1_2]
|
||||
|
||||
## Warum EPUB eher geeignet ist
|
||||
|
||||
EPUB 3 basiert im Kern auf Web-Technologien wie XHTML, CSS und XML. Für Mathematik ist MathML vorgesehen. Ein Verlag kann daher pro Formel unter anderem speichern:
|
||||
|
||||
- sichtbare Formel als MathML,
|
||||
- Textalternative für Screenreader,
|
||||
- ggf. semantische Annotationen,
|
||||
- manchmal den ursprünglichen LaTeX-Code, etwa in einem `annotation`-Element.
|
||||
|
||||
Ein sauber produziertes, zugängliches EPUB kann mathematische Formeln also wesentlich maschinenlesbarer machen. Aktuelle Empfehlungen zur EPUB-Produktion nennen MathML als Quelldatenformat; daraus können Darstellung und zugängliche Textrepräsentationen abgeleitet werden.[^1_3]
|
||||
|
||||
Beispielhaft könnte eine Formel intern ungefähr so aussehen:
|
||||
|
||||
```xml
|
||||
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||
<semantics>
|
||||
<mrow>
|
||||
<msup><mi>x</mi><mn>2</mn></msup>
|
||||
<mo>+</mo><msup><mi>y</mi><mn>2</mn></msup>
|
||||
<mo>=</mo><msup><mi>r</mi><mn>2</mn></msup>
|
||||
</mrow>
|
||||
<annotation encoding="application/x-tex">
|
||||
x^2 + y^2 = r^2
|
||||
</annotation>
|
||||
</semantics>
|
||||
</math>
|
||||
```
|
||||
|
||||
Der `annotation`-Teil wäre dann tatsächlich ein extrahierbarer LaTeX-/TeX-String. Seine Existenz ist aber nicht garantiert.
|
||||
|
||||
## Warum PDF meist schlechter ist
|
||||
|
||||
Ein PDF ist primär ein festes Seitenlayout. Selbst wenn es ursprünglich mit LaTeX erzeugt wurde, enthält das End-PDF in der Regel nicht mehr die ursprünglichen Eingaben wie `\frac{a}{b}` oder `\int_0^1`. Stattdessen enthält es Anweisungen wie: zeichne dieses Zeichen mit dieser Schrift an dieser Position.
|
||||
|
||||
Das führt zu mehreren Problemen:
|
||||
|
||||
- Kopierter Formeltext ist oft unvollständig oder in falscher Reihenfolge.
|
||||
- Brüche, Indizes, Matrizen und mehrzeilige Gleichungen verlieren ihre Struktur.
|
||||
- Formeln können als Vektorgrafik, Bild oder Kombination aus Text und Grafik vorliegen.
|
||||
- Selbst „getaggte“ PDFs enthalten häufig nur begrenzte mathematische Semantik; TeX-Quellcode ist selten eingebettet.
|
||||
|
||||
Bei kommerziellen PDF-E-Books werden Formeln häufig nicht einmal als passende Formel-Tags oder strukturierte Inhalte bereitgestellt.[^1_2][^1_4]
|
||||
|
||||
## Die praktische Einschränkung
|
||||
|
||||
„EPUB ist besser geeignet“ bedeutet nicht automatisch: „Das konkrete EPUB enthält LaTeX.“
|
||||
|
||||
Viele Verlage nutzen leider weiterhin:
|
||||
|
||||
- Formelbilder, etwa SVG oder PNG,
|
||||
- gerenderte Formelgrafiken ohne aussagekräftigen Alternativtext,
|
||||
- MathML ohne eingebettete TeX-Annotation,
|
||||
- proprietäre Konvertierungspipelines, die Struktur beim Export verlieren.
|
||||
|
||||
Der EPUB-Standard unterstützt MathML zwar, doch Reader-Unterstützung ist uneinheitlich. Deshalb empfehlen Branchenleitfäden teils weiterhin, Formeln visuell als Bild einzubinden und parallel aus MathML abgeleitete Textalternativen zu hinterlegen.[^1_3]
|
||||
|
||||
## Faustregel
|
||||
|
||||
| Was du suchst | Wahrscheinlicheres Format | Begründung |
|
||||
| :-- | :-- | :-- |
|
||||
| Originaler LaTeX-Quelltext | Weder PDF noch EPUB zuverlässig | Meist nur beim Autor, Verlag oder in einem Open-Source-Repository erhältlich |
|
||||
| Maschinenlesbare Formelstruktur | EPUB | EPUB kann MathML und semantische Metadaten enthalten |
|
||||
| Visuell originalgetreue Satzseite | PDF | PDF konserviert das gedruckte Layout |
|
||||
| Extraktion für eigene Verarbeitung | EPUB, aber prüfen | XHTML/MathML ist oft besser zugänglich als PDF-Glyphen |
|
||||
| LaTeX aus gekauften Lehrbüchern | Selten in beiden | Eine eingebettete TeX-Annotation ist eher Ausnahme als Regel |
|
||||
|
||||
Wenn dein Ziel die Weiterverarbeitung von Formeln ist, ist die sinnvollste Reihenfolge meist:
|
||||
|
||||
1. EPUB entpacken – eine `.epub` ist technisch ein ZIP-Archiv.
|
||||
2. Nach `.xhtml`, `.html`, `.svg`, `<math`, `MathML` und `application/x-tex` suchen.
|
||||
3. Falls MathML existiert, dieses in LaTeX konvertieren.
|
||||
4. Nur wenn keine Struktur vorhanden ist, PDF-Extraktion oder Formel-OCR einsetzen.
|
||||
|
||||
Kurz: Für strukturierten mathematischen Inhalt ist EPUB statistisch die bessere Hoffnung; für ausdrücklich eingebetteten LaTeX-Code sollte man aber in beiden Formaten eher skeptisch sein.
|
||||
|
||||
<span style="display:none">[^1_10][^1_5][^1_6][^1_7][^1_8][^1_9]</span>
|
||||
|
||||
<div align="center">⁂</div>
|
||||
|
||||
[^1_1]: https://ethz.ch/staffnet/de/lehre/accessibility-and-inclusion-in-teaching/accessible-learning-materials/accessible-documents---presentations/latex.html
|
||||
|
||||
[^1_2]: https://www.anleitungen.rrze.fau.de/files/2019/11/Mathematische-Formeln-erstellen-und-vorlesen.pdf
|
||||
|
||||
[^1_3]: https://www.boersenverein.de/beratung-service/barrierefreiheit/leitfaden-barrierefreie-epub3-e-books-seite-2/
|
||||
|
||||
[^1_4]: https://www.anleitungen.rrze.fau.de/files/2019/08/Mathematische-Formeln-erstellen-und-vorlesen-18a.pdf
|
||||
|
||||
[^1_5]: https://www.anleitungen.rrze.fau.de/files/2019/11/E-Book-Beispiel-Deep-Learning-Technische-Eigenschaften.pdf
|
||||
|
||||
[^1_6]: https://wr.informatik.uni-hamburg.de/\_media/teaching/sommersemester_2021/siw-21latex_und_bibtex_stahl_ausarbeitung-neu.pdf
|
||||
|
||||
[^1_7]: https://www.uni-frankfurt.de/69481937/handout.pdf
|
||||
|
||||
[^1_8]: https://www.stochastik.uni-freiburg.de/de/professoren/peter-pfaffelhuber/inhalte/schreiben_math
|
||||
|
||||
[^1_9]: https://pressbooks.pub/ebooksgrundlagen/chapter/e-books-formate/
|
||||
|
||||
[^1_10]: https://archiv.dante.de/DTK/PDF/komoedie_2015_4.pdf
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Ich habe jetzt Tools gebaut, die kapitelweise EPUB-Bücher in MDs übersetzen und PDF-Bücher in MDs übersetzen. Wie kann ich automatisieren, dass Formeln, wenn sie noch nicht in LaTeX-Schreibweise vorliegen (sondern als BIld oder SVG etc.) in LaTeX-Schreibweise konvertiert werden. Aber ACHTUNG: Genaue Kontrolle, ob die Formel genauso gerendert wird, wie sie im Original steht! Begründung: So bekommen die Formeln beim erneuten Erstellen der Bücher als MD, EPUB oder PDF eine zum Text passende Größe und das Layout sieht viel besser aus.
|
||||
|
||||
Ja: Baue dafür keine einfache „Formelbild → LaTeX“-Ersetzung, sondern eine **mehrstufige, revisionssichere Pipeline**. Die automatische Erkennung erzeugt nur einen Kandidaten; erst eine visuelle und strukturelle Gegenprüfung entscheidet, ob das Bild durch LaTeX ersetzt werden darf.
|
||||
|
||||
Das passt besonders gut zu deinem kapitelweisen EPUB-/PDF-nach-Markdown-Workflow: Du kannst jede Formel mit Herkunft, OCR-Ergebnis, Rendervergleich und Review-Status versionieren. So bleiben fehlerhafte Kandidaten als Originalbild erhalten und werden nicht stillschweigend in fachlich falsches LaTeX verwandelt.
|
||||
|
||||
## Zielarchitektur
|
||||
|
||||
Trenne strikt zwischen vier Dingen:
|
||||
|
||||
1. **Original-Asset:** Die exakt ausgeschnittene Formelgrafik bzw. der Formelbereich aus der PDF.
|
||||
2. **Kandidat:** vom OCR-Modell erzeugter LaTeX-String plus Metadaten.
|
||||
3. **Prüfrendering:** Aus dem Kandidaten mit einer festgelegten Rendering-Engine erzeugtes SVG/PNG.
|
||||
4. **Entscheidung:** automatischer Vergleich und bei Unsicherheit menschliche Freigabe.
|
||||
|
||||
Die Kernregel sollte sein:
|
||||
|
||||
> Ersetze eine Originalformel nur, wenn der LaTeX-Kandidat syntaktisch kompiliert, seine gerenderte Darstellung hinreichend ähnlich ist und kein Regelwerk einen semantischen Risikofall erkennt.
|
||||
|
||||
Nicht bestandene oder zweifelhafte Fälle bleiben im Markdown als Bild, zusammen mit einer maschinenlesbaren Markierung. Dadurch erzeugst du zwar zunächst nicht hundertprozentig „reines LaTeX-Markdown“, aber du vermeidest den viel gravierenderen Fehler, mathematische Aussagen unbemerkt zu verfälschen.
|
||||
|
||||
## Extraktionsreihenfolge
|
||||
|
||||
Bevor du irgendein OCR-Modell auf ein Bild loslässt, solltest du die Formelquelle in dieser Reihenfolge prüfen. Das spart Kosten, erhöht Genauigkeit und liefert häufig die bessere Semantik.
|
||||
|
||||
|
||||
| Priorität | Quelle im Buch | Vorgehen | Vertrauen |
|
||||
| :-- | :-- | :-- | :-- |
|
||||
| 1 | Vorhandenes MathML im EPUB | MathML direkt übernehmen oder nach LaTeX konvertieren | Sehr hoch |
|
||||
| 2 | TeX-Annotation im MathML/SVG | Nach `application/x-tex`, `annotation`, `<title>`, `<desc>` und Metadaten suchen | Sehr hoch |
|
||||
| 3 | Textbasierte PDF-Formel | PDF-Textobjekte und Tags extrahieren; nur bei sauberer Reihenfolge verwenden | Mittel bis hoch |
|
||||
| 4 | SVG mit echten Textknoten | `<text>`-, `<tspan>`- und MathJax-/KaTeX-Struktur analysieren | Mittel |
|
||||
| 5 | SVG-Pfade oder Rasterbild | Formel beschneiden und Math-OCR verwenden | Variabel |
|
||||
| 6 | Bild mit schlechter Qualität | Hochskalieren, entzerren, ggf. manuell nachbearbeiten | Niedrig |
|
||||
|
||||
EPUB 3 kann mathematische Inhalte als MathML enthalten. Bei sauber produzierten Büchern ist das wertvoller als eine optische Rückerkennung. MathML kann zusätzlich TeX als Annotation führen, beispielsweise in einem Element mit `encoding="application/x-tex"`. Für solche Fälle gilt: extrahiere den vorhandenen Inhalt; mache keine OCR. Die EPUB-Empfehlungen verlangen für Formeln MathML statt bloßer Bildformeln, auch wenn die Verlagsrealität leider oft schlechter ist.[^2_1][^2_2]
|
||||
|
||||
## Formelquellen erkennen
|
||||
|
||||
Für deine EPUB-Pipeline würde ich pro XHTML-Datei zuerst eine Klassifikation durchführen:
|
||||
|
||||
```python
|
||||
FORMULA_HINTS = (
|
||||
"math",
|
||||
"mathml",
|
||||
"equation",
|
||||
"formula",
|
||||
"latex",
|
||||
"tex",
|
||||
"mathjax",
|
||||
"katex",
|
||||
)
|
||||
|
||||
def classify_formula_node(node) -> str | None:
|
||||
tag = getattr(node, "name", "") or ""
|
||||
classes = " ".join(node.get("class", []))
|
||||
node_id = node.get("id", "")
|
||||
probe = f"{tag} {classes} {node_id}".lower()
|
||||
|
||||
if tag.lower() == "math" or "mathml" in probe:
|
||||
return "mathml"
|
||||
if tag.lower() == "svg" or node.find("svg"):
|
||||
return "svg"
|
||||
if tag.lower() == "img" and any(hint in probe for hint in FORMULA_HINTS):
|
||||
return "image"
|
||||
return None
|
||||
```
|
||||
|
||||
Für jedes gefundene Objekt solltest du eine eindeutige Formel-ID erzeugen. Sie muss stabil sein, damit du Korrekturen oder Freigaben bei einem erneuten Lauf wieder zuordnen kannst:
|
||||
|
||||
```text
|
||||
book-id/
|
||||
chapter-003/
|
||||
formulas/
|
||||
f-003-001-original.svg
|
||||
f-003-001-source.png
|
||||
f-003-001-candidate.tex
|
||||
f-003-001-rendered.svg
|
||||
f-003-001-rendered.png
|
||||
f-003-001-diff.png
|
||||
f-003-001.json
|
||||
```
|
||||
|
||||
Eine mögliche ID wäre beispielsweise:
|
||||
|
||||
```text
|
||||
f-003-001
|
||||
```
|
||||
|
||||
oder, wenn du Stabilität bei erneuten Konvertierungen brauchst:
|
||||
|
||||
```text
|
||||
f-003-001-8b7f2e1c
|
||||
```
|
||||
|
||||
Der Hash sollte sich aus Kapitelpfad, Elementposition und einem Hash des Originalassets zusammensetzen.
|
||||
|
||||
## LaTeX-OCR einsetzen
|
||||
|
||||
Für gedruckte, komplexe Lehrbuchformeln ist Mathpix als Qualitätsreferenz sinnvoll: Die API akzeptiert Bilder sowie ganze PDF-, EPUB- und Dokumentdateien und kann LaTeX, MathML, Markdown und strukturierte Zeilendaten liefern. Die zeilenbasierten Ergebnisse enthalten Formel-/Texttyp, Bounding Boxes, LaTeX und Konfidenzwerte.[^2_3][^2_4]
|
||||
|
||||
Als lokale und datenschutzfreundliche Alternative kannst du pix2tex/LaTeX-OCR einsetzen. Das Projekt verwendet ein Vision-Transformer-Modell, das Formelfotos bzw. -bilder in LaTeX übersetzt; es lässt sich als Kommandozeilenprogramm, Python-Bibliothek oder Docker/HTTP-API betreiben. Für deinen Server-Workflow wäre die Python- oder Docker-Variante passend.[^2_5][^2_6]
|
||||
|
||||
Ich würde nicht „Mathpix oder pix2tex“ wählen, sondern beide als abgestufte Kandidatengeneratoren verwenden:
|
||||
|
||||
|
||||
| Stufe | Werkzeug | Einsatz |
|
||||
| :-- | :-- | :-- |
|
||||
| Lokal, schnell, kostenlos | pix2tex | Erste Erkennung bei klaren Rasterformeln |
|
||||
| Cloud-Referenz, hohe Qualität | Mathpix | Komplexe, mehrzeilige oder lokal unsichere Formeln |
|
||||
| Deterministisch | vorhandenes MathML / TeX | Immer bevorzugen |
|
||||
| Menschliche Bearbeitung | lokales Review-UI | Alle Grenzfälle und unklare Unterschiede |
|
||||
|
||||
Mathpix kann durch `confidence_threshold` und `confidence_rate_threshold` Fehler bei niedriger mathematischer Konfidenz signalisieren. Die Konfidenz ist nützlich für die Priorisierung, aber keine Freigabe: Ein optisch plausibles OCR-Ergebnis kann mathematisch dennoch falsch sein.[^2_7][^2_8]
|
||||
|
||||
Ein praktikables Entscheidungsraster könnte sein:
|
||||
|
||||
```text
|
||||
MathML/TeX vorhanden?
|
||||
Ja → extrahieren, rendern, optional vergleichen
|
||||
Nein → pix2tex OCR
|
||||
|
||||
pix2tex kompiliert nicht?
|
||||
Ja → Mathpix versuchen oder manueller Review
|
||||
Nein → rendern und Bildvergleich
|
||||
|
||||
Bildvergleich sehr gut + OCR-Konfidenz hoch + keine Risikomuster?
|
||||
Ja → automatisch übernehmen
|
||||
Nein → Review-Warteschlange
|
||||
|
||||
Mensch bestätigt?
|
||||
Ja → LaTeX übernehmen
|
||||
Nein → Originalbild beibehalten
|
||||
```
|
||||
|
||||
|
||||
## Rendervergleich als Pflichtprüfung
|
||||
|
||||
Die wichtigste Kontrollstufe ist nicht „LaTeX ist kompilierbar“, sondern:
|
||||
|
||||
> Originalformel und gerenderter LaTeX-Kandidat müssen bei gleicher Geometrie optisch übereinstimmen.
|
||||
|
||||
Hierfür brauchst du eine standardisierte Renderumgebung. Entscheide dich pro Projekt für genau eine Rendering-Engine, beispielsweise:
|
||||
|
||||
- LaTeX → PDF/SVG mit LuaLaTeX oder XeLaTeX und `dvisvgm`,
|
||||
- alternativ LaTeX → SVG mit MathJax,
|
||||
- anschließend SVG/PDF → PNG mit fixer Auflösung und denselben Renderparametern.
|
||||
|
||||
MathJax kann TeX direkt nach SVG transformieren; SVG ist vorteilhaft, weil du es in EPUB und HTML wiederverwenden und verlustarm in PNG für den Vergleich rasterisieren kannst.[^2_9][^2_10]
|
||||
|
||||
Der entscheidende Punkt: Ein Bildvergleich funktioniert erst sinnvoll, wenn du vorab normalisierst:
|
||||
|
||||
1. Transparente oder weiße Ränder an beiden Bildern entfernen.
|
||||
2. Beide Bilder in Graustufen konvertieren.
|
||||
3. Invertieren, falls das Original helle Formel auf dunklem Hintergrund enthält.
|
||||
4. Baseline, Höhe und Breite möglichst anhand sichtbarer Zeichen ausrichten.
|
||||
5. Renderbild skalieren und geringfügig verschieben, bis es die beste Überlappung erreicht.
|
||||
6. Dann mindestens zwei Metriken berechnen: Formähnlichkeit und Pixeldifferenz.
|
||||
7. Bei Abweichung eine Heatmap bzw. Diff-PNG erzeugen.
|
||||
|
||||
ImageMagick kann Differenzbilder erzeugen und Metriken wie RMSE, NCC, SSIM und DSSIM berechnen. Bei NCC bedeutet 1 vollständige Übereinstimmung; SSIM misst strukturelle Ähnlichkeit. Das ist für leicht abweichendes Antialiasing und unterschiedliche Schrift-Renderings besser als ein strikter Pixelvergleich.[^2_11][^2_12][^2_13]
|
||||
|
||||
Ein Beispiel mit ImageMagick 7:
|
||||
|
||||
```bash
|
||||
mkdir -p normalized review
|
||||
|
||||
magick original.png \
|
||||
-alpha off -background white -flatten \
|
||||
-colorspace Gray -trim +repage \
|
||||
normalized/original.png
|
||||
|
||||
magick rendered.png \
|
||||
-alpha off -background white -flatten \
|
||||
-colorspace Gray -trim +repage \
|
||||
normalized/rendered.png
|
||||
|
||||
magick compare \
|
||||
-metric SSIM \
|
||||
normalized/original.png \
|
||||
normalized/rendered.png \
|
||||
review/f-003-001-diff.png
|
||||
```
|
||||
|
||||
In der Praxis sind die Bilder vor diesem Vergleich meist unterschiedlich groß. Deshalb solltest du nicht schlicht beide auf dieselbe Pixelgröße strecken: Das würde geometrische Fehler verschleiern. Besser:
|
||||
|
||||
- Skaliere den Renderkandidaten nur proportional.
|
||||
- Suche innerhalb enger Grenzen nach optimalem Skalierungsfaktor und Versatz.
|
||||
- Speichere die gefundene Transformation als Metadaten.
|
||||
- Bewerte Skalierung außerhalb eines erlaubten Bereichs als Warnsignal.
|
||||
|
||||
Beispielsweise:
|
||||
|
||||
```text
|
||||
erlaubte Skalierung: 0,85 bis 1,15
|
||||
erlaubter horizontaler Versatz: ±12 Pixel
|
||||
erlaubter vertikaler Versatz: ±12 Pixel
|
||||
SSIM für automatische Annahme: mindestens 0,992
|
||||
SSIM für Review: 0,960 bis unter 0,992
|
||||
SSIM unter 0,960: ablehnen oder zwingender Review
|
||||
```
|
||||
|
||||
Diese Werte sind Startwerte, keine universellen Wahrheiten. Du solltest sie an einem manuell geprüften Korpus aus deinen Büchern kalibrieren: etwa 100 bis 300 Formeln, aufgeteilt nach Inline-Formeln, Gleichungen, Matrizen, Summen, Integralen, Chemie, Tabellenformeln und Diagrammnotationen.
|
||||
|
||||
## Semantische Risiken erkennen
|
||||
|
||||
Ein hoher SSIM-Wert allein reicht nicht. Manche Fehler sind optisch klein, mathematisch aber gravierend. Daher sollten bestimmte Muster immer in den Review-Queue gehen:
|
||||
|
||||
- Hoch- und Tiefstellungen, insbesondere `x^2` gegenüber `x_2`.
|
||||
- Minus `-`, Gedankenstrich `–`, Bindestrich `-` und Negationszeichen.
|
||||
- Punkt `.` gegenüber Multiplikationspunkt `\cdot`.
|
||||
- `1`, `l`, `I`, `|` und `\ell`.
|
||||
- `0`, `O`, `o`.
|
||||
- `\nu`, `v`, `\upsilon`.
|
||||
- `\rho`, `p`, `\varrho`.
|
||||
- `\epsilon`, `\varepsilon`.
|
||||
- `\phi`, `\varphi`.
|
||||
- `\le`, `<`, `\leq`, `\ge`, `>`.
|
||||
- `\in`, `\notin`, `\subset`, `\subseteq`.
|
||||
- Vektorpfeile, Hüte, Überstriche und Tilden.
|
||||
- Grenzen von Summen, Produkten und Integralen.
|
||||
- Matrixklammern, Fälle, Ausrichtung und Gleichungssysteme.
|
||||
- Gleichungsnummern und Referenzlabels.
|
||||
- Text in Formeln, etwa `\text{für }`, Einheiten, Variablenbedingungen und Indizes.
|
||||
|
||||
Du kannst den Kandidaten per LaTeX-Parser oder notfalls per Heuristik mit Risikopunkten versehen:
|
||||
|
||||
```python
|
||||
RISK_TOKENS = (
|
||||
r"\frac", r"\sqrt", r"\sum", r"\prod", r"\int",
|
||||
r"\begin{matrix}", r"\begin{pmatrix}", r"\begin{cases}",
|
||||
r"^", r"_", r"\overline", r"\vec", r"\hat",
|
||||
r"\not", r"\le", r"\ge", r"\subset", r"\in",
|
||||
)
|
||||
|
||||
def risk_score(latex: str) -> int:
|
||||
score = 0
|
||||
for token in RISK_TOKENS:
|
||||
score += latex.count(token)
|
||||
if "\n" in latex or r"\\" in latex:
|
||||
score += 2
|
||||
return score
|
||||
```
|
||||
|
||||
Das ist keine semantische Validierung. Es sorgt lediglich dafür, dass komplexe Formeln nicht wegen eines guten Bildvergleichs automatisch durchgewinkt werden.
|
||||
|
||||
## Robustes Manifest
|
||||
|
||||
Lege zu jeder Formel ein JSON-Manifest ab. Es ist der Schlüssel zu Reproduzierbarkeit, Git-Diffs, Review und späteren Verbesserungen deiner OCR-Pipeline.
|
||||
|
||||
```json
|
||||
{
|
||||
"formula_id": "f-003-001-8b7f2e1c",
|
||||
"book_id": "operations-research-01",
|
||||
"chapter_id": "003",
|
||||
"source": {
|
||||
"format": "epub",
|
||||
"xhtml_file": "OEBPS/chapter03.xhtml",
|
||||
"element_xpath": "/html/body/div[^2_4]/p[^2_7]/img[^2_1]",
|
||||
"page": null,
|
||||
"original_asset": "formulas/f-003-001-original.svg",
|
||||
"source_sha256": "..."
|
||||
},
|
||||
"extraction": {
|
||||
"method": "pix2tex",
|
||||
"model_version": "pix2tex-v1",
|
||||
"latex_raw": "\\sum_{i=1}^{n} x_i",
|
||||
"latex_normalized": "\\sum_{i=1}^{n} x_i",
|
||||
"ocr_confidence": null,
|
||||
"created_at": "2026-10-06T22:33:00+02:00"
|
||||
},
|
||||
"validation": {
|
||||
"latex_compiles": true,
|
||||
"renderer": "MathJax-SVG",
|
||||
"normalization": {
|
||||
"scale": 1.018,
|
||||
"offset_x_px": 2,
|
||||
"offset_y_px": -1
|
||||
},
|
||||
"ssim": 0.9961,
|
||||
"rmse": 0.023,
|
||||
"diff_image": "formulas/f-003-001-diff.png",
|
||||
"risk_score": 3
|
||||
},
|
||||
"decision": {
|
||||
"status": "needs_review",
|
||||
"reason": "complex_operator",
|
||||
"reviewer": null,
|
||||
"reviewed_at": null
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Mögliche Statuswerte:
|
||||
|
||||
```text
|
||||
source_tex
|
||||
auto_accepted
|
||||
needs_review
|
||||
accepted_by_human
|
||||
rejected_keep_image
|
||||
corrected_by_human
|
||||
render_failed
|
||||
ocr_failed
|
||||
```
|
||||
|
||||
Der Markdown-Konverter setzt abhängig davon entweder LaTeX oder ein Bild ein:
|
||||
|
||||
```markdown
|
||||
<!-- formula-id: f-003-001-8b7f2e1c | status: accepted_by_human -->
|
||||
\[
|
||||
\sum_{i=1}^{n} x_i
|
||||
\]
|
||||
```
|
||||
|
||||
Oder, bewusst ohne stillschweigende Ersetzung:
|
||||
|
||||
```markdown
|
||||
<!-- formula-id: f-003-001-8b7f2e1c | status: rejected_keep_image -->
|
||||

|
||||
```
|
||||
|
||||
|
||||
## Review-Seite erzeugen
|
||||
|
||||
Für eine schnelle Prüfung ist eine statische HTML-Review-Galerie ideal. Pro Formel zeigst du nebeneinander:
|
||||
|
||||
- Originalbild oder Original-SVG,
|
||||
- gerenderte LaTeX-Fassung,
|
||||
- transparentes Overlay,
|
||||
- Differenzbild,
|
||||
- den LaTeX-Quelltext,
|
||||
- Erkennungsmethode und Modellversion,
|
||||
- OCR-Konfidenz,
|
||||
- SSIM/RMSE,
|
||||
- Risikoscore,
|
||||
- Link zur Kapitel-MD-Datei beziehungsweise PDF-Seite,
|
||||
- Schaltflächen bzw. Statusdatei für „annehmen“, „LaTeX korrigieren“, „Bild behalten“.
|
||||
|
||||
Ein besonders gutes Prüfmittel ist ein Umschalt-Overlay:
|
||||
|
||||
```text
|
||||
Original ↔ Render-Kandidat ↔ Überlagerung ↔ Differenz
|
||||
```
|
||||
|
||||
Bei Überlagerung mit etwa 50 Prozent Transparenz springen falsche Exponenten, verschobene Integrationsgrenzen, fehlende Punkte und vertauschte Klammern sofort ins Auge. Bei komplexen Matrizengleichungen ist das wesentlich zuverlässiger als eine reine Zahl.
|
||||
|
||||
Für lokale Nutzung kannst du das als rein statische HTML-Seite plus JavaScript bauen. Die Entscheidung speicherst du anschließend etwa in `review_decisions.json` oder direkt im jeweiligen Formelmanifest. So brauchst du weder Cloud noch Datenbank und kannst den Stand gut mit Git versionieren.
|
||||
|
||||
## Empfohlene Automationslogik
|
||||
|
||||
Ich würde mit folgenden konservativen Regeln anfangen:
|
||||
|
||||
```text
|
||||
1. Vorhandenes TeX/MathML:
|
||||
automatisch übernehmen;
|
||||
dennoch rendern und protokollieren.
|
||||
|
||||
2. SVG mit eindeutiger MathJax-/KaTeX-Struktur:
|
||||
strukturell nach TeX/MathML extrahieren;
|
||||
nicht optisch per OCR rekonstruieren.
|
||||
|
||||
3. Klar isoliertes Formelbild:
|
||||
pix2tex ausführen;
|
||||
wenn Ergebnis gültig kompiliert, rendern und vergleichen.
|
||||
|
||||
4. Pix2tex unsicher, nicht kompilierbar oder schlechter Vergleich:
|
||||
Mathpix als zweites OCR-System ausführen.
|
||||
|
||||
5. Beide Systeme liefern semantisch denselben normalisierten LaTeX-AST
|
||||
und der Rendervergleich ist sehr gut:
|
||||
automatisch übernehmen, falls kein Risikomuster vorliegt.
|
||||
|
||||
6. Abweichende OCR-Kandidaten, komplexe Struktur, niedrige Konfidenz,
|
||||
schlechter Vergleich oder auffällige Zeichen:
|
||||
zwingend in die Review-Galerie.
|
||||
|
||||
7. Negativ geprüfte Formel:
|
||||
Originalbild im Markdown erhalten;
|
||||
Status und Gründe speichern;
|
||||
niemals „best guess“ ungeprüft veröffentlichen.
|
||||
```
|
||||
|
||||
Die zwei OCR-Modelle liefern bewusst nicht denselben Code. Deshalb solltest du LaTeX nicht als String vergleichen. Normalisiere vor dem Vergleich wenigstens:
|
||||
|
||||
- Leerzeichen,
|
||||
- `\left`/`\right`, falls semantisch entbehrlich,
|
||||
- äquivalente Befehle wie `\leq` und `\le`,
|
||||
- Klammerformatierungen,
|
||||
- überflüssige Gruppierungen.
|
||||
|
||||
Noch besser wäre eine kleine Zwischenrepräsentation bzw. ein LaTeX-AST. Zwei verschiedene, aber äquivalente Schreibweisen sollten als gleich gelten:
|
||||
|
||||
```latex
|
||||
\frac{a}{b}
|
||||
```
|
||||
|
||||
und
|
||||
|
||||
```latex
|
||||
{a \over b}
|
||||
```
|
||||
|
||||
Visuell und mathematisch können sie gleich sein, aber als Strings unterscheiden sie sich.
|
||||
|
||||
## Größe und Layout beim Neubau
|
||||
|
||||
Dein Motiv ist richtig: Semantisches LaTeX statt Formelpixel verbessert Reflow, Schriftgröße, Zoom, Kontrast, responsives EPUB-Layout und konsistente PDF-Typografie erheblich.
|
||||
|
||||
Für Markdown solltest du unterscheiden:
|
||||
|
||||
- Inline-Formeln in $...$, nur wenn sie wirklich in eine Textzeile gehören.
|
||||
- Abgesetzte Formeln in [ ... ].
|
||||
- Nummerierte Gleichungen und Labels als eigene Blockstruktur.
|
||||
- Lange Ausdrücke, Matrizen und Fallunterscheidungen stets als Display-Mathematik.
|
||||
- Originale Gleichungsnummern separat erhalten, statt sie aus Versehen als Formelteil zu OCRen.
|
||||
|
||||
Beispiel:
|
||||
|
||||
```markdown
|
||||
Die Zielfunktion lautet
|
||||
|
||||
\[
|
||||
\min \; z = \sum_{i=1}^{n} c_i x_i
|
||||
\tag{3.7}
|
||||
\]
|
||||
|
||||
unter den Nebenbedingungen
|
||||
|
||||
\[
|
||||
\sum_{i=1}^{n} a_{ji}x_i \le b_j,
|
||||
\qquad j = 1, \ldots, m.
|
||||
\]
|
||||
```
|
||||
|
||||
Damit kann dein EPUB-Renderer die Formel flexibel an die Bildschirmbreite anpassen, und die PDF-Ausgabe kann die mathematische Schriftgröße konsistent an den umgebenden Satz koppeln.
|
||||
|
||||
## Konkrete Toolwahl
|
||||
|
||||
Für deinen Linux-/Python-Stack würde ich so beginnen:
|
||||
|
||||
- `lxml` oder Beautiful Soup für EPUB-XHTML, MathML und SVG-Analyse.
|
||||
- `zipfile` für EPUB-Entpacken und Neubauen.
|
||||
- PyMuPDF/Fitz für PDF-Seiten, Bildextraktion und Formel-Crops.
|
||||
- `pix2tex` als lokaler erster OCR-Pass.
|
||||
- Mathpix nur als optionalen zweiten Pass für schwerere Fälle oder als Qualitätsreferenz. Es kann Bilder, PDFs und EPUBs verarbeiten und liefert LaTeX/MathML/Markdown zurück.[^2_4][^2_3]
|
||||
- MathJax oder LuaLaTeX plus `dvisvgm` als fest definierter TeX-Renderer. MathJax unterstützt die Konvertierung von TeX nach SVG direkt.[^2_10][^2_9]
|
||||
- `cairosvg`, Inkscape oder `rsvg-convert`, um SVG reproduzierbar nach PNG zu rastern.
|
||||
- ImageMagick 7 für Vorverarbeitung, Vergleich und Diff-Bilder. `magick compare` kann mathematische und visuell interpretierbare Differenzen ausgeben.[^2_12][^2_11]
|
||||
- Eine statische HTML-Review-Galerie, statt in der ersten Version eine vollständige Web-App zu bauen.
|
||||
|
||||
Die Qualitätsregel sollte dabei immer konservativ bleiben: Automatisiere Erkennung, Rendering, Vergleich, Sortierung und Dokumentation. Automatisiere die endgültige Akzeptanz nur für sehr einfache, extrem sichere Fälle.
|
||||
|
||||
<span style="display:none">[^2_14][^2_15][^2_16][^2_17][^2_18][^2_19][^2_20][^2_21][^2_22][^2_23][^2_24][^2_25][^2_26][^2_27][^2_28][^2_29][^2_30][^2_31][^2_32][^2_33][^2_34][^2_35][^2_36][^2_37][^2_38][^2_39][^2_40][^2_41][^2_42]</span>
|
||||
|
||||
<div align="center">⁂</div>
|
||||
|
||||
[^2_1]: https://www.boersenverein.de/beratung-service/barrierefreiheit/leitfaden-barrierefreie-epub3-e-books-seite-2/
|
||||
|
||||
[^2_2]: https://ethz.ch/staffnet/de/lehre/accessibility-and-inclusion-in-teaching/accessible-learning-materials/accessible-documents---presentations/latex.html
|
||||
|
||||
[^2_3]: https://mathpix.com/ocr
|
||||
|
||||
[^2_4]: https://mathpix.com/docs/mpxpy/images
|
||||
|
||||
[^2_5]: https://github.com/lukas-blecher/LaTeX-OCR
|
||||
|
||||
[^2_6]: https://lukas-blecher.github.io/LaTeX-OCR/
|
||||
|
||||
[^2_7]: https://docs.mathpix.com/reference/post-v3-text
|
||||
|
||||
[^2_8]: https://apis.io/schemas/mathpix/mathpix-image-result/
|
||||
|
||||
[^2_9]: https://docs.mathjax.org/en/v4.0/web/convert.html
|
||||
|
||||
[^2_10]: https://docs.mathjax.org/en/latest/output/svg.html
|
||||
|
||||
[^2_11]: https://imagemagick.org/compare/
|
||||
|
||||
[^2_12]: https://imagemagick.org/command-line-options/
|
||||
|
||||
[^2_13]: https://www.baeldung.com/linux/image-comparison
|
||||
|
||||
[^2_14]: https://wr.informatik.uni-hamburg.de/\_media/teaching/sommersemester_2021/siw-21latex_und_bibtex_stahl_ausarbeitung-neu.pdf
|
||||
|
||||
[^2_15]: https://www.stochastik.uni-freiburg.de/de/professoren/peter-pfaffelhuber/inhalte/schreiben_math
|
||||
|
||||
[^2_16]: https://arxiv.org/html/2408.04015v1
|
||||
|
||||
[^2_17]: https://mathpix.com/blog
|
||||
|
||||
[^2_18]: https://mathpix.com/
|
||||
|
||||
[^2_19]: https://mathpix.com/blog/files-api
|
||||
|
||||
[^2_20]: https://github.com/topics/latex-ocr
|
||||
|
||||
[^2_21]: https://www.underleaf.ai/learn/latex/accessibility
|
||||
|
||||
[^2_22]: https://github.com/api-evangelist/mathpix
|
||||
|
||||
[^2_23]: https://tex.stackexchange.com/questions/116863/image-equation-to-tex
|
||||
|
||||
[^2_24]: https://mcpmarket.com/tools/skills/mathpix-ocr-latex-pipeline
|
||||
|
||||
[^2_25]: https://man.archlinux.org/man/pdftocairo.1.en
|
||||
|
||||
[^2_26]: https://usage.imagemagick.org/compare/
|
||||
|
||||
[^2_27]: https://man.archlinux.org/man/compare.1.en
|
||||
|
||||
[^2_28]: https://mathjax.github.io/MathJax-demos-web/input/tex2svg.html
|
||||
|
||||
[^2_29]: https://mathjax.github.io/MathJax-demos-web/input/tex-mml2svg.html
|
||||
|
||||
[^2_30]: https://blog.jeffterrace.com/2012/09/comparing-image-comparison-algorithms.html?m=1
|
||||
|
||||
[^2_31]: https://viereck.ch/latex-to-svg/
|
||||
|
||||
[^2_32]: https://tex.stackexchange.com/questions/255470/compile-tex-directly-into-svg-using-the-command-line
|
||||
|
||||
[^2_33]: https://www.simplified.guide/imagemagick/compare-images
|
||||
|
||||
[^2_34]: https://github.com/ImageMagick/ImageMagick/discussions/6814
|
||||
|
||||
[^2_35]: tools.math_formula_ocr
|
||||
|
||||
[^2_36]: projects.textbook.operations_research_trading
|
||||
|
||||
[^2_37]: tools.ebook_conversion
|
||||
|
||||
[^2_38]: tools.markdown.latex_conversion
|
||||
|
||||
[^2_39]: https://www.perplexity.ai/search/7483c59a-1497-4d41-93b2-8f564ddbf224
|
||||
|
||||
[^2_40]: https://www.perplexity.ai/search/b03e509e-2dd2-4821-b2b0-03f4cdc5328a
|
||||
|
||||
[^2_41]: https://www.perplexity.ai/search/7a6c1e3b-efb1-40ca-a9a1-c10ec14ba3e2
|
||||
|
||||
[^2_42]: https://www.perplexity.ai/search/e6f21cb6-7c55-4bcb-8f4f-5af8a75e59a2
|
||||
|
||||
Loading…
Reference in a new issue