RapidOCR vs Tesseract: Benchmarked on 14 Scanned Book Pages
Out of the box, Tesseract beat RapidOCR on scanned book spreads and ran 8× faster. With layout handling added, RapidOCR won on characters. Per-page numbers and the script.
The short answer
On 14 scanned pages from a 1959 book, Tesseract beat RapidOCR out of the box: a mean character error rate (CER) of 0.177 against 0.458, at 3.7 seconds a page against 29.5. RapidOCR's text recognition was fine. It lost because it read straight across both pages of each scanned spread, mixing the left and right pages line by line.
With image restoration, spread splitting and column ordering around RapidOCR (my B.L.A.S.T. pipeline), the measured CER was 0.108, lower than Tesseract's on average. Tesseract still won 9 of the 14 pages, got whole words right more often, and ran about 4.5× faster. B.L.A.S.T. only won on average because Tesseract fell apart on two nearly empty pages.
Everything below was run on one laptop CPU on 20 October 2026, with the same scoring code for every engine. The script is at the end. The OCR benchmark results include all four configurations, per-page scores and downloadable data.
data/benchmarks/2026-10-20-ocr/METHOD.md. For the step-by-step layout handling behind the pipeline result, see the scanned-book OCR guide and its pre-flight checklist.What I compared
| Pipeline | Version and settings | Input |
|---|---|---|
| Tesseract | Tesseract 4.1.1, LSTM, -l eng --psm 3 --oem 1 | the raw page image |
| RapidOCR | rapidocr_onnxruntime 1.4.4, default models and settings | the raw page image |
| B.L.A.S.T. | RapidOCR plus image restoration, spread splitting and column ordering | the restored page |
I also ran Tesseract on the restored images B.L.A.S.T. sees, to check the restoration step wasn't the difference. It wasn't: CER 0.187, slightly worse than on the raw images.
The corpus. 14 pages from a scanned copy of The Ideology of Pakistan and its Implementation (Javid Iqbal, 1959), each transcribed by hand. Most PDF pages in that scan are a two-page spread: left page and right page in one image. The set covers body text, a preface, chapter openings, a title page, a table of contents, endnotes, the start of the index, a mostly blank page with a hand-drawn circle on it, and a photo of the cloth back cover.
The scoring. CER is the edit distance between the engine's output and the hand transcription, divided by the transcription's length. WER is the same over words. Reading order is Kendall's tau between the word order in the output and in the transcription (1.0 means the right order). All three come from B.L.A.S.T.'s evaluation harness, used unchanged for every engine.
The machine. Intel Core i5-10210U (4 cores, 8 threads), 10 GB RAM, Ubuntu 22.04 under WSL2, CPU only. Times are for the OCR call alone, without the restoration step.
Results
| Pipeline | Mean CER | Median CER | Mean WER | Reading order (tau) | Seconds / page |
|---|---|---|---|---|---|
| Tesseract 4.1.1 | 0.177 | 0.039 | 0.279 | 0.995 | 3.7 |
| RapidOCR, out of the box | 0.458 | 0.729 | 0.674 | 0.668 | 29.5 |
| B.L.A.S.T. (RapidOCR + layout) | 0.108 | 0.086 | 0.449 | 0.993 | 16.5 |
Lower is better for CER, WER and time. Higher is better for tau. Tau needs at least two lines of text in the transcription, so it is averaged over the 11 or 12 pages that have them.
Page by page, Tesseract vs B.L.A.S.T.
| Page | What's on it | Tesseract CER | B.L.A.S.T. CER |
|---|---|---|---|
| p002 | title page, display type | 0.039 | 0.092 |
| p006 | spread, preface | 0.022 | 0.042 |
| p008 | table of contents | 0.208 | 0.102 |
| p009 | spread, chapter opening (left page blank) | 0.026 | 0.056 |
| p020 | spread, body text | 0.030 | 0.044 |
| p035 | spread, body text | 0.039 | 0.067 |
| p049 | spread, body text | 0.027 | 0.041 |
| p066 | spread, chapter opening (left page blank) | 0.026 | 0.079 |
| p069 | spread, body text | 0.036 | 0.044 |
| p093 | endnotes | 0.179 | 0.117 |
| p094 | spread, endnotes | 0.204 | 0.121 |
| p095 | spread, endnotes and two-column index | 0.056 | 0.115 |
| p096 | index tail, mostly blank, hand-drawn circle | 0.713 | 0.132 |
| p097 | photographed cloth cover | 0.878 | 0.463 |
On ordinary prose, Tesseract wins every time. B.L.A.S.T. wins the table of contents, two of the three endnote pages, and the two pages that are hardly text at all. If you take out p096 and p097, the averages are a tie: 0.074 for Tesseract, 0.077 for B.L.A.S.T.
If you have a set of scanned spreads and want the layout step built and scored against your own pages, that is the document OCR service. The pipeline behind these numbers is B.L.A.S.T..
CER vs WER: which number should you optimize?
CER counts character edits. WER counts whole-word errors. They disagree here, and the disagreement tells you which engine fits your use.
| Pipeline | Mean CER | Mean WER |
|---|---|---|
| Tesseract 4.1.1 | 0.177 | 0.279 |
| B.L.A.S.T. (RapidOCR + layout) | 0.108 | 0.449 |
The spacing example under “Where B.L.A.S.T. still loses” shows why WER is worse despite the lower CER.
That changes the choice:
- If a human reads the output, CER is the closer measure. A missing space is ugly, but the characters are there.
- If search, embeddings or an LLM read the output, WER matters more. A merged token like
Theology,thereforeis a different token, and a hyphen left inside a word breaks exact matching. - If you need both, plan a post-processing pass for spacing and hyphenation. I have not built that pass yet, so the WER numbers above still include those errors.
Why RapidOCR lost out of the box
RapidOCR finds text boxes and recognises each one well. It then returns them roughly top to bottom across the whole image. On a two-page spread, that means line 1 of the left page, then line 1 of the right page, then line 2 of the left page:
What the book says: What came back:
[Left page, line 1] Left page, line 1 Right page, line 1
[Left page, line 2] Left page, line 2 Right page, line 2
... ...
[Right page, line 1]Every word is there, but in the wrong order, so the character and word scores collapse. On the seven spreads with text on both pages, RapidOCR's CER was between 0.73 and 0.77. On the title page, the contents and the two chapter openings, where only one side has text, it was between 0.05 and 0.09. Tesseract's page segmentation (--psm 3) finds the two pages as separate blocks by itself, which is why its reading order scored 0.995 without any help.
So for scanned books, "RapidOCR vs Tesseract" is mostly a question about layout, not recognition.
What fixed it
B.L.A.S.T. puts a layout step between detection and output:
- Split the spread. If the image is wider than 1.1× its height, look for the vertical white gap in the middle 40 to 60% of the width and treat each side as its own page.
- Find columns. Within each page, cut wherever a vertical gap is wider than
max(35px, 1.8 × glyph height). - Rebuild lines. Group boxes into lines with a tolerance scaled to the glyph height, then sort left to right.
- Group blocks. Join consecutive lines into paragraphs where the gap between them is small.
The complete B.L.A.S.T. configuration, including image restoration and layout handling, scored 0.993 for reading order and 0.108 CER, compared with 0.668 and 0.458 for raw RapidOCR. This comparison does not isolate layout handling from the other pipeline changes.
- 60
Before entering on the subject of this - 61
thestructure ofthebeetlewhich dives - 60
chapter, I must make a few preliminary - 61
through the water; in the plumed seed which is - 60
remarks, to show how the struggle for - 61
wafted by the gentlest breeze; in short, we - 60
existencebearsonNatural Selection.It has - 61
see beautiful adaptations everywhere and in - 60
been seen in the last chapter that amongst
- 60
chapter, I must make a few preliminary - 60
remarks, to show how the struggle for - 60
existencebearsonNaturalSelection.Ithas - 60
beenseeninthelastchapterthatamongst - 60
organic beings in a state of nature there is - 60
some individual variability; indeed I am not - 60
aware that this has ever been disputed. It is - 60
immaterial for uswhether a multitude of - 60
doubtful forms be called species or sub-
Where B.L.A.S.T. still loses
Words. B.L.A.S.T.'s WER is 0.449 against Tesseract's 0.279, even though its CER is lower. RapidOCR often drops the space after punctuation and sometimes between words:
Transcription: degree in Theology, therefore, should be high enough to include all the above
B.L.A.S.T.: degree in Theology,therefore,
should be high enough to include all the above
...subjectmay be enabled to carry onadvancedOne missing space turns two right words into one wrong one. It also keeps the line-end hyphen in "philoso-\nphy" and picks up running headers that the transcription leaves out. Each of these is fixable in post-processing, and fixing them is next on the list. Until then, if you need clean words more than clean characters, Tesseract is the better choice on pages like these.
Speed. Tesseract took 3.7 seconds a page; B.L.A.S.T. took 16.5. RapidOCR's detection and recognition models are bigger than Tesseract's LSTM, and on a 4-core laptop CPU that shows.
Tesseract wasn't tuned. I ran one standard configuration and didn't try other page-segmentation modes, a newer Tesseract 5.x build or other language models. A tuned Tesseract might close the gap on the index pages.
Which one should you use?
| Your documents | What I would use | Why |
|---|---|---|
| Clean printed prose, single pages, speed matters | Tesseract 4.1.1 | It won 9 of 14 pages and ran about 4.5x faster than B.L.A.S.T. |
| Scanned books with facing pages, or multi-column pages | Either engine, but only with a layout step | Without a layout step, RapidOCR's spread output is unreadable. B.L.A.S.T. is that step around RapidOCR. |
| Tables of contents, endnotes, sparse or noisy pages | RapidOCR with a layout step | B.L.A.S.T. won the contents page, two endnote pages, and the two nearly blank or photographed pages. |
| Clean words for search or an LLM | Tesseract, or RapidOCR plus a spacing fix | B.L.A.S.T. wins CER but loses WER to missing spaces and hyphenation. |
The corpus is small: 14 pages from one book, one typeface family, English only. Treat these numbers as a reason to test on your own documents, not as a verdict.
--psm 3 run. These results cover 14 English pages from one book, not OCR in general.Run it yourself
This is the script I used. It runs inside the B.L.A.S.T. repository at commit 43590fd (see the B.L.A.S.T. case study) and reuses its gold transcriptions and scoring code.
import statistics, sys, time
from pathlib import Path
import pytesseract
from rapidocr_onnxruntime import RapidOCR
REPO = Path(".") # the B.L.A.S.T. repository root
sys.path.insert(0, str(REPO))
from eval.gold_loader import load_all_gold
from eval.metrics import compute_cer, compute_wer
rapid = RapidOCR()
def tesseract(path):
return pytesseract.image_to_string(path, lang="eng", config="--psm 3 --oem 1")
def rapidocr(path):
result, _ = rapid(path)
return "\n".join(line[1] for line in (result or []))
for name, run in [("tesseract", tesseract), ("rapidocr", rapidocr)]:
cers, wers, secs = [], [], []
for gold in load_all_gold(REPO / "eval" / "gold"):
image = str(REPO / "eval" / "pages" / f"{gold.page_id}.png")
start = time.monotonic()
text = run(image)
secs.append(time.monotonic() - start)
cers.append(compute_cer(gold.flat_text, text))
wers.append(compute_wer(gold.flat_text, text))
print(name, f"CER {statistics.mean(cers):.3f}", f"WER {statistics.mean(wers):.3f}",
f"{statistics.mean(secs):.1f}s/page")The B.L.A.S.T. row comes from the repository's own harness: python eval/run.py --engine rapidocr --no-save.
Frequently Asked Questions
Is RapidOCR more accurate than Tesseract?
Not out of the box on scanned book pages. On 14 pages, Tesseract 4.1.1 scored a mean CER of 0.177 and RapidOCR 0.458, mainly because RapidOCR read across both pages of each spread. With restoration and layout handling, the B.L.A.S.T. pipeline reached 0.108, but Tesseract still won 9 of the 14 pages.
Is RapidOCR faster than Tesseract on CPU?
Not in this test. On a 4-core laptop CPU, Tesseract took 3.7 seconds a page, RapidOCR 29.5 seconds on the full spreads, and the B.L.A.S.T. pipeline 16.5 seconds on split pages.
How do you stop OCR from mixing up two columns or two pages?
Detect the gap between them before you join the text. Split the image at the widest vertical white gap, sort lines within each side top to bottom, then output the left side before the right. Tesseract's automatic page segmentation does this for simple layouts; RapidOCR needs it added.
How is Character Error Rate (CER) calculated?
CER is the Levenshtein edit distance (insertions, deletions and substitutions) between the OCR output and a hand-made transcription, divided by the number of characters in the transcription. 0.10 means about one character in ten needs fixing.
Need this in your product?
I build OCR pipelines for scans, multi-column PDFs and tables, with a benchmark and a script you can rerun on your own pages.
Document OCR