Extract text from images with Tesseract, translate it, and keep a searchable history of every run — from a single file, a URL, or a live camera feed.
Tesseract's accuracy is dominated by what you hand it. A slightly rotated phone photo of a page, or one with low contrast, can drop from readable to unusable — and no --psm setting recovers it. This project puts the preprocessing pipeline first and makes it measurable: compare runs the same image under every profile and prints confidence side by side, so you pick a profile from evidence rather than guesswork.
$ python cli.py compare scan.jpg --lang eng
profile chars confidence seconds
light ... ... ...
standard ... ... ...
aggressive ... ... ...
document ... ... ...Pick the profile with the highest confidence and a plausible character count — a profile that scores well but returns far fewer characters has thrown away text.
| Profile | Contrast | Denoise | Deskew | Binarize | Resize | Use for |
|---|---|---|---|---|---|---|
light |
yes | yes | no | no | 1.0x | clean screenshots |
standard |
yes | yes | yes | no | 1.2x | general photos |
aggressive |
yes | yes | yes | yes | 1.5x | small or faint text |
document |
yes | yes | yes | yes | 1.0x | scanned pages |
Skew correction uses the projection-profile method: the image is binarised, rotated through a range of candidate angles, and each rotation is collapsed into a horizontal projection of row sums. When text lines sit horizontally the projection swings sharply between dense text rows and empty gaps, so its variance peaks — that angle is the skew.
Verified against synthetic pages with known rotation:
| True skew | Estimated |
|---|---|
| 0.0° | 0.0° |
| +5.0° | +5.0° |
| -8.0° | -8.0° |
| +11.0° | +11.0° |
The Python package is a wrapper — the Tesseract binary must be installed separately.
- Windows: install from UB Mannheim's build, then either add it to
PATHor pass--tesseract "C:\Program Files\Tesseract-OCR\tesseract.exe" - macOS:
brew install tesseract - Linux:
sudo apt install tesseract-ocr
Language packs are separate. For Persian: sudo apt install tesseract-ocr-fas (or tick the language during the Windows install).
git clone https://github.com/MrDanial-Rafiee/ocr-translator.git
cd ocr-translator
pip install -r requirements.txt
python cli.py image examples/sample_image.jpg --lang eng --to fa# One image or a URL
python cli.py image page.jpg --lang eng --to fa --profile document
python cli.py image https://example.com/sign.png --lang eng+fas
# Skip preprocessing entirely
python cli.py image clean_scan.png --profile none
# Which profile suits this image?
python cli.py compare scan.jpg --lang eng
# Live camera
python cli.py camera --ip 192.168.1.3 --lang eng # phone running an IP-webcam app
python cli.py camera --device 0 --lang eng # local webcam
# History and export
python cli.py history --limit 20
python cli.py stats
python cli.py export results.csvfrom ocr_translator import OCRTranslator
ocr = OCRTranslator()
result = ocr.ocr_and_translate("page.jpg", dest_lang="fa", languages=["eng"])
print(result["original_text"])
print(result["translated_text"])
print(result["ocr_confidence"])ocr_and_translate accepts a path, a URL, a PIL.Image, or an OpenCV BGR array — the camera module passes frames straight through.
| Key | Action | Key | Action |
|---|---|---|---|
t |
OCR + translate the frame | f |
face detection |
c |
save the frame | m |
motion detection |
s |
overlay the last OCR text | g |
grayscale |
+ / - |
zoom | e |
edge detection |
h |
recent history | l |
mirror |
d |
statistics | q |
quit |
The camera address defaults to 192.168.1.3:8080 and can be set with --ip / --port or the CAMERA_IP / CAMERA_PORT environment variables.
Every run is recorded, so results are reviewable long after the fact:
ocr_translator_results/
├── results.db SQLite: run history + translation cache
├── json_results/ full result per run, with metadata
├── text_results/ plain text: extracted + translated
└── processed_images/ what Tesseract actually saw
The translation cache is keyed on (text, source language, target language), so re-running the same image never pays for the same translation twice.
├── cli.py command-line entry point
└── ocr_translator/
├── preprocessor.py profiles, contrast/denoise/binarize, projection-profile deskew
├── translator.py Tesseract OCR + translation + confidence
├── storage.py SQLite history, translation cache, CSV export
└── camera.py live IP-webcam / webcam front end
googletransis an unofficial client for a private Google endpoint. It breaks whenever that endpoint changes and is rate-limited without warning. A paid translation API, or a local model such asargos-translate, would make this dependable. This is the weakest link in the project.- Confidence is Tesseract's own word confidence, averaged. It correlates loosely with correctness and should not be read as an accuracy figure.
- No accuracy benchmark. Scoring the profiles against a ground-truth set (character error rate on a labelled corpus) would turn the
compareoutput from relative to absolute. - Deskew searches ±15° in 0.5° steps. Heavily rotated or perspective-distorted photos need a four-point transform, which is not implemented.
- No layout analysis. Multi-column pages and tables come out as running text;
--psm 6assumes a single uniform block. - The camera module needs a display and cannot run headless.
MIT — see LICENSE.