Tools,

Pix2Text, tested on scanned pages and formulas

1,810

of 1,955 words found

Get the commands

Run Pix2Text on a scanned PDF

99 s for 10 pages, Mac CPU, 2 threads

368 MB of models, fetched on the first run

On a Mac, in a folder with scan.pdf:

python3.12 -m venv p2t && source p2t/bin/activate
pip install pix2text "rapidocr<3.10"
p2t predict -l en --file-type pdf --disable-formula --disable-table -i scan.pdf -o out

The text lands in out/output.md. Keep formulas and tables on only for pages that have them.

-l en loads the English text models. The default, en,ch_sim, also reads Chinese.

The rapidocr import error

After a plain pip install pix2text, p2t stopped at once:

ImportError: cannot import name 'resolve_model_key' from 'rapidocr.utils.model_resolver'

pip picked rapidocr 3.10.0, out since October 8. cnstd 1.2.8 imports a name that 3.10.0 does not have. "rapidocr<3.10" gives 3.9.2, and the error is gone.

Turn off formulas for plain text

Same 10 pages, 1,955 words, all with -l en
Switches Words found Time
None (the default) 1,685 184 s
--disable-formula
--disable-table
1,810 99 s
Same, plus --resized-shape 1536 1,755 127 s

These pages hold no math. With formulas on, the output still had 110 bits of LaTeX. "by" came out as $\mathbf{b y}$.

A bigger --resized-shape found fewer words and used 9.1 GB of memory.

Pix2Text vs Tesseract

Same 10 pages, 1,955 words
Tool Words found
Pix2Text 1.1.7, formulas off 1,810
Tesseract 5.5.4 1,877
Our Actor 1,874

Tesseract found 67 more words, in 47 s. Pix2Text joins the lines into Markdown paragraphs. Tesseract keeps the lines of the page.

Printed formulas: 6 of 8 the same

p2t predict -l en --file-type formula -i f1.png

I drew 8 formulas with matplotlib at 200 dpi. 6 came back as the same LaTeX, with spaces and braces ignored. The other 2 were right, in a longer form:

\lim_{x \to 0} \frac{\sin x}{x} = 1
\underset{x \to0} {\operatorname* {l i m}} \, \frac{\operatorname{s i n} x} {x}=1

Each call took about 14 s from a cold start.

What it downloads

The first run fetched 368 MB of models from Hugging Face. It tries hf-mirror.com first. A later run with no network gave the same text.

I checked each model license first. Layout: Apache-2.0. Formulas and tables: MIT. English text: PaddleOCR models, Apache-2.0. The en,ch_sim text model has no license tag, so I did not run it.

-d mps, the Mac GPU, gave the same text in about the same time.

MIT, with AGPL parts

Pix2Text is MIT. pip also installs doclayout-yolo and ultralytics, both AGPL-3.0. Running it on your own files is fine. If you build it into a product or a web service, read the AGPL first.

Need text with nothing to install?

Our Actor takes PDF, JPG and PNG files and returns Markdown, from one web request. On the same 10 pages, inside a PDF, it found 1,874 words.

curl -s -X POST "https://api.apify.com/v2/acts/brasspage~pdf-ocr-to-markdown/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"documentUrls": ["https://api.apify.com/v2/key-value-stores/sTnmNrGoSsi7tLQvs/records/anythingllm-mixed-11-pages.pdf"]}' \
  | jq -r '.[].markdown' > book.md

It costs $0.006 a page.

How I tested it
  • Pages: the 10 scans of OCR in n8n, proofread Wikisource book pages, 1,955 true words. Each page is one color JPEG, 1,920 x 3,079 pixels, at 300 ppi.
  • Pix2Text 1.1.7, cnocr 2.3.3, cnstd 1.2.8, rapidocr 3.9.2 and torch 2.15.0, in a Python 3.12 venv of 1.9 GB, on an Apple Silicon Mac. CPU, 2 threads, lowest priority, other jobs on the Mac.
  • Peak memory: 5.3 GB with formulas off, 6.4 GB with them on.
  • Tesseract 5.5.4 alone: the CLI on the 10 JPEGs, English, default settings.
  • Score: true words found in order, with the scorer of the tessdata test.
  • The Actor: one real run, build 0.1.65, on November 12. Its file holds the same 10 pages plus a typed cover page.
What I did not test
  • The en,ch_sim default, and other languages.
  • Tables, and pages with real math on them.
  • An NVIDIA GPU, Windows and Linux.
  • The Python API, and the pro and plus model versions.
Sources

Two ways to skip the work

Run it yourself. Our Apify Actor turns scanned PDFs into Markdown, tables included.

Try the Actor

Or send us the scan. Tack, our AI, does the job for $29, up to 50 pages. First page free.

Get one page free

Questions people ask

Can Pix2Text OCR a scanned PDF?

Yes. p2t predict --file-type pdf writes Markdown. On 10 scanned book pages, Pix2Text 1.1.7 found 1,810 of 1,955 words with formulas off, and 1,685 with them on.

How do I fix the rapidocr ImportError in Pix2Text?

Install rapidocr below 3.10, with pip install "rapidocr<3.10". rapidocr 3.10.0 has no resolve_model_key, and cnstd 1.2.8 imports it.

Is Pix2Text better than Tesseract?

Not on plain scanned text. Tesseract 5.5.4 found 1,877 of the same 1,955 words. Pix2Text is built for math: it gave back 6 of 8 printed formulas as the same LaTeX.