Tools,

Disabling Tesseract's dictionary changed nothing. A word list did.

0

lines changed of 3,600, dictionaries off

For printed scans: $0.006 a page

The off switch changes nothing

The docs say it helps on text that is not dictionary words.

Text, 300 lines each Words right Lines changed
Book prose 2,446 of 2,451 0
Part codes, emails, names 911 of 1,006 0
Invoice lines 1,680 of 1,686 0
Codes like T0WN 527 of 803 0

On 72 full invoice pages, 0 of 7,609 words changed.

How I tested it
  • Tesseract 5.5.4, the Homebrew eng model, the LSTM engine, one line at a time at --psm 7.
  • 1,200 made-up lines: prose from Pride and Prejudice, part codes, invoice rows, and words with a digit swapped in.
  • Times New Roman at 26 px, with tilt, blur, noise and JPEG, like a scan.
  • Tesseract's parameter dump showed both flags set to 0.
  • I ran it again at 21 px, and with tessdata_best. Dictionaries off changed 0 lines both times.
  • A word is right when it matches the truth exactly, case and punctuation included. Full pages: my 72 test invoices, at --psm 3.

A list of your codes helps

--user-words takes a file with one word per line. --user-patterns takes shapes, such as \A\A-\d\d\d\d\A for two capitals, a dash, four digits and a capital.

tesseract line.png - --psm 7 -c load_system_dawg=0 -c load_freq_dawg=0
tesseract line.png - --psm 7 --user-words parts.txt
tesseract line.png - --psm 7 --user-patterns patterns.txt
Code words read right, of 1,006
Default
911
--user-patterns
940
--user-words
965
Snap after OCR
985

The list held the 577 codes and names on the lines, plus 1,925 made-up decoys. Neither option broke a word that was right.

In Python, one config string

pytesseract hands the config string to the tesseract command, so both flags go in one string:

import pytesseract
from PIL import Image

img = Image.open("line.png")
off = pytesseract.image_to_string(img, config="--psm 7 -c load_system_dawg=0 -c load_freq_dawg=0")
words = pytesseract.image_to_string(img, config="--psm 7 --user-words parts.txt")

For 0 and O, fix it after OCR

Tesseract read the digit 0 as the letter O, and 1 as I, inside words. The dictionary flags did not change that.

Two scanned test lines: Part 100-H01X qty 37, and Bin T0WN D1LATORY
Codes like T0WN Words right, of 803
Default 527
--user-words 540
Snap after OCR 650

snap(), in 17 lines of Python

It swaps a word for the one list word it can be confused with. Give it the same list you would give --user-words.

# each lookalike group maps to one character
LOOK = str.maketrans("O0Il1S5B8Z2", "00111558822")


def snap(text, known):
    """Swap each word for the one known word it looks like, if exactly one fits."""
    by_key = {}
    for w in known:
        by_key.setdefault(w.translate(LOOK), set()).add(w)
    out = []
    for word in text.split():
        core = word.strip(",.;:")
        match = by_key.get(core.translate(LOOK), set())
        out.append(
            word.replace(core, next(iter(match)))
            if core not in known and len(match) == 1
            else word
        )
    return " ".join(out)
Limits, and what I did not test
  • Real scans. Every line here is made up, in one font.
  • The legacy engine, --oem 0. The Homebrew model has no legacy data.
  • Missing codes. The lists held every code on the test lines, and a real parts list can miss some. Snap leaves those alone.
Sources

Our Actor leaves the dictionaries alone

Our Apify Actor takes no word list or patterns, and keeps Tesseract's dictionary settings as shipped. When it reads a table number a second time, it allows only digits and separators.

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

How do I disable the dictionary in pytesseract?

Pass config="-c load_system_dawg=0 -c load_freq_dawg=0", both flags in one string. On Tesseract 5.5.4 it changed 0 of 3,600 test lines.

Does --user-words work with the LSTM engine?

Yes, on Tesseract 5.5.4. A list of part codes raised code words read right from 911 to 965 of 1,006, and broke none.

Can Tesseract read only the words in my list?

No. The list only nudges. With the parts list on, the 300 book lines came out as before, though only 3 of their 916 different words were on it.