VisionParse
VisionParse is a small, practical toolkit for turning messy image-based documents into useful text and data. It wraps the pieces that usually end up scattered across notebooks: OCR, image preprocessing, YOLO/object detection, price extraction, and optional LLM cleanup.
It started life as a set of computer-vision experiments. This package gives those ideas a proper home: import-safe modules, a CLI, tests, PyPI metadata, and GitHub Actions.
The heart of the project is still research-minded: use free/local OCR first, keep text localized with bounding boxes, preserve the page/menu layout as much as possible, and only bring in heavier YOLO or LLM tools when they genuinely help.
pip install visionparse-free-ocr
import visionparse
What it does
- Runs OCR with Tesseract, EasyOCR, Keras OCR, or Google Vision.
- Preprocesses images before OCR: resize, grayscale, denoise, threshold, contrast, crop.
- Runs YOLO detections and returns clean bounding boxes.
- Groups localized OCR words into lines and blocks so aligned text stays aligned.
- Extracts prices from noisy OCR text.
- Turns menu-like OCR into lightweight structured items.
- Optionally asks an LLM/LangChain flow to clean up the structure.
- Provides one document pipeline and one CLI so the pieces fit together.
Installation
The base install is intentionally light:
pip install visionparse-free-ocr
For OCR with Tesseract:
pip install "visionparse-free-ocr[ocr]"
You still need the Tesseract system binary installed. On Windows, install Tesseract and either add it to PATH or pass the path when create the engine.
For YOLO detection:
pip install "visionparse-free-ocr[yolo]"
For the full kitchen sink:
pip install "visionparse-free-ocr[all]"
Extras are split this way because object detection, EasyOCR, Keras OCR, and Google Vision pull in heavier dependencies.
Quick start
Extract prices from text
from visionparse import extract_prices
text = "Chicken Biryani £8.99\nFamily Platter 24.50\nMango Lassi Rs. 450"
for price in extract_prices(text):
print(price.raw, price.amount, price.currency)
Parse menu-like OCR text
from visionparse import extract_menu_items
ocr_text = """
Starters
Samosa £3.50
Chicken Pakora £5.99
Mains
Lamb Karahi £12.95
"""
items = extract_menu_items(ocr_text)
for item in items:
print(item.name, item.prices, item.category)
OCR an image with Tesseract
from visionparse.ocr.engine import TesseractOCR
ocr = TesseractOCR(
languages="eng",
config="--oem 3 --psm 6",
tesseract_cmd=r"C:\Program Files\Tesseract-OCR\tesseract.exe",
)
result = ocr.read("menu.jpg")
print(result.text)
Run the document pipeline
from visionparse.pipelines.document_pipeline import DocumentPipeline
pipeline = DocumentPipeline(ocr_engine="tesseract")
result = pipeline.run("menu.jpg")
print(result.text)
print(result.layout_text) # layout-preserving text when OCR boxes are available
print([price.raw for price in result.prices])
print([item.to_dict() for item in result.items])
Preserve layout from localized OCR
from visionparse.ocr.localization import TextToken, group_tokens_into_lines, render_aligned_text
tokens = [
TextToken("Burger", (10, 10, 70, 25)),
TextToken("£7.99", (180, 10, 230, 25)),
TextToken("Fries", (10, 45, 55, 60)),
TextToken("£2.50", (180, 45, 230, 60)),
]
lines = group_tokens_into_lines(tokens)
print(render_aligned_text(lines, char_width=10))
Use YOLO regions before OCR
from visionparse.detection.yolo import YoloDetector
from visionparse.pipelines.document_pipeline import DocumentPipeline
detector = YoloDetector("models/menu-sections.pt", confidence=0.25)
pipeline = DocumentPipeline(ocr_engine="tesseract", detector=detector)
result = pipeline.run("menu.jpg")
for region in result.regions:
print(region.box, region.text[:120])
See docs/model-card.md.
Darknet/OpenCV YOLO is also supported:
from visionparse.detection.yolo import OpenCVDarknetYoloDetector
detector = OpenCVDarknetYoloDetector(
weights_path="models/yolov3.weights",
# config_path and names_path default to the packaged yolov3.cfg/coco.names
)
detections = detector.detect("menu.jpg")
Command line
After installation, the visionparse command is available.
OCR:
visionparse ocr menu.jpg --engine tesseract --lang eng --pretty
Extract prices from a string:
visionparse prices "Burger £7.99 Fries 2.50" --pretty
Extract prices from a file:
visionparse prices --file ocr-output.txt --pretty
Run the full parser:
visionparse parse menu.jpg --engine tesseract --pretty
Run the parser with YOLO regions:
visionparse parse menu.jpg --engine tesseract --yolo-model models/menu-sections.pt --pretty
Run YOLO only:
visionparse detect menu.jpg --model models/menu-sections.pt --pretty
Run Darknet YOLO with the packaged config/labels and your local weights:
visionparse detect menu.jpg --backend darknet --model models/yolov3.weights --pretty
Save an annotated detection image:
visionparse detect menu.jpg --model models/menu-sections.pt --output annotated.jpg
OCR engines
Tesseract
Good default when wanted a local, lightweight OCR engine. Install the Python extra and the system binary:
pip install "visionparse-free-ocr[ocr]"
from visionparse.ocr.engine import TesseractOCR
ocr = TesseractOCR(languages="eng+ara", config="--oem 3 --psm 6")
print(ocr.read("receipt.jpg").text)
If Tesseract is installed in a custom location:
ocr = TesseractOCR(tesseract_cmd=r"C:\Program Files\Tesseract-OCR\tesseract.exe")
You can also set:
set TESSERACT_CMD=C:\Program Files\Tesseract-OCR\tesseract.exe
EasyOCR
pip install "visionparse-free-ocr[easyocr]"
from visionparse.ocr.engine import EasyOCR
ocr = EasyOCR(languages=("en",))
result = ocr.read("shop-sign.jpg")
Keras OCR
pip install "visionparse-free-ocr[keras]"
from visionparse.ocr.engine import KerasOCR
ocr = KerasOCR()
result = ocr.read("menu.jpg")
Google Vision
pip install "visionparse-free-ocr[google]"
Use Application Default Credentials, or pass a service-account file at runtime.
from visionparse.ocr.engine import GoogleVisionOCR
ocr = GoogleVisionOCR(credentials_path="local-only-service-account.json")
print(ocr.read("invoice.jpg").text)
LLM/LangChain cleanup
The regular parser is deterministic and does not need an API key. If needed LLM cleanup, install the LLM extra and use an environment variable:
pip install "visionparse-free-ocr[llm]"
set OPENAI_API_KEY=your-key-here
from visionparse.extraction.structured_text import structure_with_llm
cleaned = structure_with_llm(raw_ocr_text, model="gpt-4o-mini")
print(cleaned)
The code reads from OPENAI_API_KEY at runtime.
Research notes, examples, and benchmarks
Includes:
docs/research.md— project findings and outcomes from the OCR/layout experiments.docs/model-card.md— how the fine-tuned YOLO model should be handled.examples/— free OCR and YOLO+OCR usage scripts.benchmarks/— lightweight text/layout benchmarks plus an optional local image OCR runner.
python benchmarks/run_benchmarks.py --images .visionparse_private_legacy
Package layout
visionparse/
├── detection/
│ └── yolo.py
├── ocr/
│ ├── engine.py
│ └── preprocessing.py
├── extraction/
│ ├── prices.py
│ └── structured_text.py
├── pipelines/
│ └── document_pipeline.py
├── models/
├── cli.py
└── tests/
Development
python -m pip install -e ".[dev]"
python -m pytest
python -m build
twine check dist/*
The tests avoid heavyweight OCR/model dependencies. They check the parser, price extraction, and import safety first; model-specific tests can be added later with fixtures.
License
MIT.
Metadata
Release files for visionparse-free-ocr 0.1.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| visionparse_free_ocr-0.1.2.1.tar.gz | 38.3 kB | Without provenance | Details for visionparse_free_ocr-0.1.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| visionparse_free_ocr-0.1.2.1-py3-none-any.whl | Python 3 | none | any | Details for visionparse_free_ocr-0.1.2.1-py3-none-any.whl |
Total release size: 72.0 kB
Release files / visionparse_free_ocr-0.1.2.1.tar.gz
| Download URL | visionparse_free_ocr-0.1.2.1.tar.gz |
|---|---|
| Size | 38.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
899d54682d69e62b05798ad9690e99a01be944455daca8e9d7ac486883682295
|
|
BLAKE2b-256 checksum How to use checksums |
018045d394d08ac526e8fd845c2cfc487b2c768553cd02b8870ba54e0452a5aa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / visionparse_free_ocr-0.1.2.1-py3-none-any.whl
| Download URL | visionparse_free_ocr-0.1.2.1-py3-none-any.whl |
|---|---|
| Size | 33.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ad7ed1bf8bb442cd82ad363474ee7015363738f60404fd0b9021b0c755e638a7
|
|
BLAKE2b-256 checksum How to use checksums |
acd219d4f42c13cf93bd861078800af182ff8658bc9662bfc681793fd9ff2540
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for visionparse-free-ocr 0.1.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.