An OCR benchmark on 14 scanned pages
On 14 scanned two-page spreads, B.L.A.S.T. had the lowest mean CER (0.108). Raw Tesseract won 9 of 14 pages against B.L.A.S.T., had lower word error, and ran 4.5× faster. Raw RapidOCR scored 0.458 CER. These are results from one CPU evaluation, with restoration excluded from timing.
Character error rate on each page (lower is better)
- Tesseract 4.1.1, raw
- B.L.A.S.T.
- p002Tesseract 0.039, B.L.A.S.T. 0.092.
- p006Tesseract 0.022, B.L.A.S.T. 0.042.
- p008Tesseract 0.208, B.L.A.S.T. 0.102.
- p009Tesseract 0.026, B.L.A.S.T. 0.056.
- p020Tesseract 0.030, B.L.A.S.T. 0.044.
- p035Tesseract 0.039, B.L.A.S.T. 0.067.
- p049Tesseract 0.027, B.L.A.S.T. 0.041.
- p066Tesseract 0.026, B.L.A.S.T. 0.079.
- p069Tesseract 0.036, B.L.A.S.T. 0.044.
- p093Tesseract 0.179, B.L.A.S.T. 0.117.
- p094Tesseract 0.204, B.L.A.S.T. 0.121.
- p095Tesseract 0.056, B.L.A.S.T. 0.115.
- p096nearly blank index pageTesseract 0.713, B.L.A.S.T. 0.132, nearly blank index page.
- p097photographed cloth coverTesseract 0.878, B.L.A.S.T. 0.463, photographed cloth cover.
Need to know how your own scans fare? Send a brief with sample pages →
What this benchmark measures
The corpus is eval/pages and eval/gold at OCR repository commit 43590fd. METHOD.md describes 14 scanned two-page spreads. Every configuration uses the same gold text and scoring functions. I report page-level means, rather than pooling all characters into a single score.
- CER: character edit distance divided by gold-text length.
- WER: the equivalent edit-distance score over words.
- Kendall tau: reading-order rank correlation. Null scores are excluded; the table shows each configuration's valid page count.
- Seconds per page: time around the OCR call only. Restoration for B and C is excluded, so these are not end-to-end processing times.
The README records an Intel Core i5-10210U, 10 GB RAM and WSL2 Ubuntu 22.04, CPU only. Runs were sequential in the same session. This is a small corpus, not evidence of performance across other languages, handwriting, cloud services or different hardware. Tesseract was not tuned; its settings were fixed before the results.
Four tested configurations
- A: Tesseract on raw images
- Tesseract 4.1.1, LSTM,
-l eng --psm 3 --oem 1. - B: Tesseract on restored images
- The same settings, after B.L.A.S.T.'s
restore_page_imagein standard mode. - C: B.L.A.S.T. with RapidOCR
- The production path through
eval.run.run_one_page, with restoration and layout handling. - D: RapidOCR on raw images
rapidocr_onnxruntime1.4.4 defaults, joining lines in the order the library returns them.
A to C were pre-registered. D was added after A to C were seen, on the same benchmark date. It is published here alongside them.
Aggregate results
All figures below come from the committed result JSON. Medians for error rates and tau are calculated from the per-page rows. Scroll the table horizontally to compare every metric.
| Configuration | Mean CER | Median CER | Mean WER | Median WER | Mean τ | Median τ | τ pages | Mean s/page | Median s/page |
|---|---|---|---|---|---|---|---|---|---|
| A: Tesseract 4.1.1 · raw | 0.177 | 0.039 | 0.279 | 0.140 | 0.995 | 1.000 | 12 | 3.7 | 3.6 |
| B: Tesseract 4.1.1 · restored | 0.187 | 0.046 | 0.290 | 0.157 | 0.996 | 1.000 | 12 | 3.1 | 3.1 |
| C: B.L.A.S.T. · RapidOCR + layout | 0.108 | 0.085 | 0.449 | 0.336 | 0.993 | 1.000 | 12 | 16.5 | 15.6 |
| D: RapidOCR 1.4.4 · raw defaults | 0.458 | 0.700 | 0.674 | 0.863 | 0.668 | 0.512 | 11 | 29.5 | 32.1 |
Per-page performance and the sparse-page effect
Tesseract wins 9 of 14 head-to-head CER comparisons with B.L.A.S.T. This table compares A and C; the JSON download includes every page for all configurations.
| Page | Tesseract CER | B.L.A.S.T. CER | Lower CER |
|---|---|---|---|
| p002 | 0.039 | 0.092 | Tesseract |
| p006 | 0.022 | 0.042 | Tesseract |
| p008 | 0.208 | 0.102 | B.L.A.S.T. |
| p009 | 0.026 | 0.056 | Tesseract |
| p020 | 0.030 | 0.044 | Tesseract |
| p035 | 0.039 | 0.067 | Tesseract |
| p049 | 0.027 | 0.041 | Tesseract |
| p066 | 0.026 | 0.079 | Tesseract |
| p069 | 0.036 | 0.044 | Tesseract |
| p093 | 0.179 | 0.117 | B.L.A.S.T. |
| p094 | 0.204 | 0.121 | B.L.A.S.T. |
| p095 | 0.056 | 0.115 | Tesseract |
| p096 | 0.713 | 0.132 | B.L.A.S.T. |
| p097 | 0.878 | 0.463 | B.L.A.S.T. |
The companion write-up describes p096 as an index tail with mostly blank space and a hand-drawn circle, and p097 as a photographed cloth cover. Their high Tesseract error strongly affects the mean. Excluding those pages gives mean CER 0.074 for Tesseract and 0.077 for B.L.A.S.T. The aggregate alone hides that change in the comparison.
Lower character error does not mean cleaner words
B.L.A.S.T.'s mean WER is 0.449, against Tesseract's 0.279. In the original comparison, I show missing spaces after punctuation, words run together, retained line-end hyphens and running headers. A small character change can turn otherwise correct words into incorrect tokens.
Tesseract averaged 3.7 seconds per page; B.L.A.S.T. averaged 16.5; raw RapidOCR averaged 29.5. The 4.5× Tesseract speed advantage over B.L.A.S.T. is the ratio of the unrounded means. Choose against your output requirements, especially if the text will feed search or an AI assistant.
Download and reproduce the results
Download all configurations as JSON, or get one configuration: A, B, C, D. Each response includes the source path and OCR commit. The download contains measurements, not the scan images or gold transcriptions.
Site sources: data/benchmarks/2026-10-20-ocr/README.md, METHOD.md, result_A.json through result_D.json, and run_bench.py. The README does not state a dataset license. Read the OCR repository at 43590fd for the corpus and evaluation harness.
To rerun the saved script, check out that OCR commit, install its dependencies and Tesseract, then copy run_bench.py from the site source. Change its machine-specific REPO path to your OCR checkout. Run each configuration separately:
python run_bench.py A
python run_bench.py B
python run_bench.py C
python run_bench.py DThe endpoint reads imported JSON without rerunning OCR. Query selection runs at request time so ?config=C is preserved, with public cache headers for each URL.
What to test on your own documents
- Separate single pages, facing-page spreads and multi-column layouts.
- Include contents, notes, sparse pages and the pages your first engine handles badly.
- Identify tables, handwriting and language requirements instead of assuming these results cover them.
- Hand-transcribe a representative sample and keep its scoring rules fixed.
- Check CER, WER and reading order together, then review the exported text.
- Measure end-to-end latency including rendering, restoration and export on your target machine.
For the layout approach, read the scanned-book OCR guide and the B.L.A.S.T. case study.
Frequently asked questions
Is RapidOCR more accurate than Tesseract on scanned books?
Not by default in this test. Raw RapidOCR had mean CER 0.458, versus 0.177 for raw Tesseract. B.L.A.S.T., which adds restoration and layout handling to RapidOCR, reached 0.108. This is one small corpus, not a general ranking.
Why is B.L.A.S.T.'s CER lower but its WER higher?
B.L.A.S.T. had mean WER 0.449 versus Tesseract's 0.279. The companion write-up shows missing spaces after punctuation and between words, retained line-end hyphens and running headers. Character accuracy alone does not establish that the words are ready for search or retrieval.
Was RapidOCR part of the pre-registered comparison?
The B.L.A.S.T. pipeline using RapidOCR was configuration C in the pre-registered A to C comparison. Raw RapidOCR defaults, configuration D, were added after those results were seen. METHOD.md records this distinction explicitly.
Does this compare Tesseract 5 or cloud OCR?
No. The Tesseract configuration uses version 4.1.1 with English, PSM 3 and OEM 1. All runs used the same CPU machine. These results do not establish how newer versions, other settings, GPUs or cloud services would perform.
Test the pages you actually need to process
I build document OCR pipelines around your layouts and output requirements. Send sample pages and describe what the extracted text needs to support.