# 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.