Реализация распознавания формул и уравнений с изображений
Распознавание математических формул — задача сложнее обычного OCR: формулы имеют двумерную структуру (дроби, степени, индексы, суммирование), специальные символы (∫, ∑, ∂, ∞) и требуют понимания контекста для правильной интерпретации. Выход — LaTeX или MathML разметка.
Pix2Tex: LaTeX OCR из изображений
from pix2tex.cli import LatexOCR
from PIL import Image
class FormulaRecognizer:
def __init__(self):
# Pix2Tex — специализированная модель для формул
self.model = LatexOCR()
def recognize(self, image_path: str) -> dict:
img = Image.open(image_path)
latex = self.model(img)
return {
'latex': latex,
'rendered': self._latex_to_mathml(latex)
}
def _latex_to_mathml(self, latex: str) -> str:
try:
import latex2mathml.converter
return latex2mathml.converter.convert(latex)
except Exception:
return ''
# Использование
recognizer = FormulaRecognizer()
result = recognizer.recognize('equation.png')
print(result['latex']) # \frac{d}{dx}\left(x^2\right) = 2x
Альтернатива: Mathpix API
Mathpix — коммерческий сервис с лучшим качеством распознавания на сложных многострочных формулах и текстах смешанного содержания:
import requests
import base64
import json
class MathpixOCR:
def __init__(self, app_id: str, app_key: str):
self.app_id = app_id
self.app_key = app_key
self.url = 'https://api.mathpix.com/v3/text'
def recognize_formula(self, image_path: str) -> dict:
with open(image_path, 'rb') as f:
image_b64 = base64.b64encode(f.read()).decode()
response = requests.post(
self.url,
headers={
'app_id': self.app_id,
'app_key': self.app_key,
'Content-Type': 'application/json'
},
json={
'src': f'data:image/jpeg;base64,{image_b64}',
'formats': ['text', 'latex_styled', 'mathml'],
'math_inline_delimiters': ['$', '$'],
'math_display_delimiters': ['$$', '$$']
}
)
data = response.json()
return {
'latex': data.get('latex_styled', ''),
'text': data.get('text', ''),
'mathml': data.get('mathml', ''),
'confidence': data.get('confidence', 0)
}
Собственная модель на базе TrOCR
Для специфических нотаций (химические формулы, физические обозначения):
from transformers import VisionEncoderDecoderModel, TrOCRProcessor
# Дообучение TrOCR на датасете формул
# Датасет: im2latex-100k, HME100K (рукописные формулы)
model = VisionEncoderDecoderModel.from_pretrained(
'microsoft/trocr-base-stage1'
)
processor = TrOCRProcessor.from_pretrained('microsoft/trocr-base-stage1')
# Fine-tuning на latex_pairs: [(image, latex_string), ...]
Сегментация формул в документе
Прежде чем распознавать формулы, нужно их найти в документе. Два подхода:
Детектор формул: YOLOv8 дообученный на датасете документов с размеченными формулами (inline и display). mAP > 0.90 на тестовом наборе.
PDF через PyMuPDF: извлечение блоков с формулами через анализ PDF-структуры (для digitally created PDF).
Валидация через компиляцию LaTeX
import subprocess
import tempfile
import os
def validate_latex(latex: str) -> bool:
"""Проверка корректности распознанной формулы через pdflatex"""
template = r"""
\documentclass{article}
\usepackage{amsmath}
\begin{document}
$""" + latex + r"""$
\end{document}
"""
with tempfile.NamedTemporaryFile(suffix='.tex', mode='w',
delete=False) as f:
f.write(template)
tex_path = f.name
try:
result = subprocess.run(
['pdflatex', '-interaction=nonstopmode', tex_path],
capture_output=True, timeout=10
)
return result.returncode == 0
except Exception:
return False
finally:
os.unlink(tex_path)
| Метрика | Pix2Tex | Mathpix |
|---|---|---|
| BLEU на im2latex-100k | 87.3 | 93+ |
| Точность на рукописных формулах | 72% | 85% |
| Скорость | 0.5 сек | 1–2 сек (API) |
| Задача | Срок |
|---|---|
| Integration pix2tex / Mathpix API | 1–2 недели |
| Детекция + распознавание в PDF/Word | 3–5 недель |
| Кастомная модель для нотации | 5–8 недель |







