# scan2html — Offline Document OCR Pipeline
Полностью офлайн-конвейер обработки отсканированных документов:
разрезание изображений на страницы → OCR → структурированный Markdown.
---
## Цель проекта
Преобразование больших технических документов (JPEG/TIFF/PNG), полученных после печати и сканирования, в структурированный Markdown с формулами LaTeX, пригодный для:
- просмотра в браузере (HTML + MathJax)
- анализа LLM
- конвертации в LaTeX/PDF
**Полностью offline.** Без облачных сервисов.
---
## Pipeline
```
JPEG/TIFF/PNG (многостраничный скан)
│
▼
src/image_split.py ← Stage 1: разрезание
│ --slice / --slice-auto
│ --pre-rotate, --border
│ --post-crop
│
▼
JPEG страницы
│
▼
src/image_to_latex.py ← Stage 2: OCR + Markdown
│ --ocr-engine paddle|surya
│ --llm, --vlm (optional)
│
├─ PP-StructureV3 / Surya 2 (OCR)
├─ fixups (VaR, V^2)
├─ LLM corrector (Qwen2.5-7B, local)
├─ VLM corrector (Qwen3.8 Max, API)
│
▼
.md + .json + .html
```
---
## Параметры
### Stage 1: `src/image_split.py`
| Параметр | Описание | По умолчанию |
|----------|----------|:---:|
| `--input` / `-i` | Путь к входному изображению | required |
| `--slice` / `-s` | Сетка `:` | — |
| `--slice-auto` / `-a` | Автоопределение сетки | — |
| `--output-dir` / `-o` | Каталог для страниц | `.` |
| `--pre-rotate` / `-r` | Поворот: 90, 180, 270 | — |
| `--border` / `-b` | Белая рамка (px) | 50 |
| `--post-crop` / `--no-post-crop` | Обрезка по контенту | ON |
Пример:
```bash
python -m src.image_split -i scan.jpg -s 3:3 -b 10 -o pages/
python -m src.image_split -i scan.jpg --slice-auto
```
### Stage 2: `src/image_to_latex.py`
| Параметр | Описание | По умолчанию |
|----------|----------|:---:|
| `--input` / `-i` | Изображение страницы | required |
| `--output-dir` / `-o` | Каталог вывода | рядом с `--input` |
| `--lang` / `-l` | Язык OCR | `en` |
| `--ocr-engine` | `paddle` или `surya` | `paddle` |
| `--llm` | Локальный LLM-корректор (Qwen2.5-7B) | OFF |
| `--vlm` | Vision LM корректор (Qwen3.8 Max, API) | OFF |
Пример:
```bash
# Базовый OCR
python -m src.image_to_latex -i page.jpg
# С LLM-коррекцией
python -m src.image_to_latex -i page.jpg -l ru --llm
# С VLM-коррекцией (нужен OPENCODE_API_KEY в .env)
python -m src.image_to_latex -i page.jpg --vlm
# Surya 2
python -m src.image_to_latex -i page.jpg --ocr-engine surya
```
---
## Результат
Для каждого входного изображения генерируется:
| Файл | Формат | Описание |
|------|--------|----------|
| `page_01.md` | Markdown | Текст + `$$`-формулы + `##`-заголовки |
| `page_01.json` | JSON | Полный дамп OCR-движка (bbox, confidence, labels) |
Дополнительно (при включённых опциях):
- `.tex` — LaTeX-документ (скомпилировать в PDF)
- `.html` — HTML с MathJax-рендерингом формул
---
## Качество OCR
| Движок | Русский текст | Формулы | Скорость |
|--------|:---:|:---:|:---:|
| PaddleOCR (PP-StructV3) | ~85% | ✅ отлично | ~140s |
| + LLM (Qwen2.5-7B) | ~95% | ✅ | +5 min |
| + VLM (Qwen3.8 Max) | ~98% | ✅✅ | +10s/блок |
| Surya 2 | ~95% | ✅ отлично | ~430s |
---
## Архитектура
```
src/
image_split.py — CLI Stage 1
image_to_latex.py — CLI Stage 2
split/slicer.py — разрезание, post-crop
ocr/
paddle_engine.py — PP-StructureV3
surya_engine.py — Surya 2
postprocess/
fixups.py — OCR-ошибки (VaR)
corrector.py — Corrector protocol
llm_corrector.py — Qwen2.5-7B (local)
vlm_corrector.py — Qwen3.8 Max (API)
markdown/generator.py — Markdown + валидация
latex/
surya2html.py — Surya JSON → HTML
tex2html.py — TeX → HTML
```
---
## Не входит в проект
- GUI
- Docker
- PDF (на вход)
- LLM/RAG
- Поиск по документам
- Многопоточность
- Автоматический deskew / denoise
---
## Лицензия
MIT. Модели PaddleOCR — Apache 2.0, Surya 2 — OpenRAIL-M.