1 of 36

From Pixels to Text

209/07/2025

Evaluating Open-Source OCR Models on Japanese Medical Documents

1

2 of 36

2

2

3 of 36

The Challenge

  • Stringent data privacy regulations
  • Data fragmentation

3

4 of 36

Topic

  • Choosing open-source OCR engines for in-house use
  • Building a Python benchmarking pipeline
  • Results & trade-offs across OCR engines

4

5 of 36

The engines

6 of 36

Paddle

3.0

  • Released May 2025
  • Simplified Chinese, Traditional Chinese, English, and Japanese

6

7 of 36

Yomitoku 1.0

  • Released Oct 2024
  • Japanese

7

8 of 36

Tesseract

5.0

  • Released 2021
  • 100+ languages

8

9 of 36

Candidate OCR Engines

Tesseract

Paddle

Yomitoku

9

01

02

03

10 of 36

How the models are evaluated

10

Text-Level Accuracy

​

Characters, symbols, number error rate

Quantitative

Processing time

​

Time from input to text output.

​

11 of 36

Character Error Rate

S = number of substitutions (wrong character recognized)�

D = number of deletions (a character missing)�

I = number of insertions (extra characters added)�

N = total characters in the reference (ground truth)

​

CER= S+D+I​ / N

​

​

11

12 of 36

How the texts are built to compare with ground truth

Concatenate output texts of the same row from top to bottom

12

13 of 36

How the models are evaluated

13

Layout fidelity

​

Compare detected text regions with ground truth

Qualitative

Content Diff

​

What types of contents differ from ground truth

​

Readability

​

How readable the recognized texts are

​

Developer Experience

​

Ease of setup

Documentation quality

Output for downstream processing

14 of 36

Image 1

15 of 36

Image 1 Result

15

​

Edit Distance

Processing Time

Paddle

​

16.78%

1.76s 🌟

Yomitoku

​

0.97% 🌟

1.93s

Tesseract

​

33.57%

9.87s

16 of 36

Image 2

17 of 36

Image 2 Result

17

​

Edit Distance

Processing Time

Paddle

​

10.95%

6.11s

Yomitoku

​

3.08% 🌟

4.95s 🌟

Tesseract

​

0.19%

14.2s

18 of 36

Image 3

19 of 36

Image 3 Result

19

​

Edit Distance

Processing Time

Paddle

​

27.03%

0.99s 🌟

Yomitoku

​

9.3% 🌟

1.22s

Tesseract

​

78.2%

4.66

20 of 36

Layout Fidelity

20

Tendency to fail to detect texts on the edge

​

Paddle

No major issue

​

​

​

Struggle to locate texts when documents have complicated layout

​

​

​

Yomitoku

Tesseract

21 of 36

Paddle |

Tendency to fail to detect or convert texts on the edge

21

22 of 36

Tesseract |

Struggle to locate where texts when documents have complicated layout

22

23 of 36

Content Diff/ Readability

23

Different versions of the same Chinese character

​

Tendency to fail to convert texts on the edge

Paddle

Some struggle with handling writing, seal, logo

​

​

​

NA

Yomitoku

Tesseract

24 of 36

Paddle |

Tendency to fail to convert texts on the edge

24

25 of 36

Paddle |

Mix up different versions of kanjis

25

26 of 36

Yomitoku |

Struggles with logo, handwriting and when data quality is very low

26

27 of 36

Effect on error rate when we improve image quality

28 of 36

Image 4 Sharpened

kernel = np.array([

[0,-1,0],

[-1,5,-1],

[0,-1,0]

])

sharpened = cv2.filter2D(img, -1, kernel)

28

29 of 36

Image 4 Contrasted

# Improve contrast using CLAHE

# (on L-channel in LAB color space)

lab = cv2.cvtColor(sharpened, cv2.COLOR_BGR2LAB)

l, a, b = cv2.split(lab)

clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8,8))

l2 = clahe.apply(l)

lab = cv2.merge((l2,a,b))

contrast = cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)

29

30 of 36

Image 4 Improved Error Rate

30

​

Original

Sharpened

Contrasted

Paddle

​

27.03%

18.90%↓

20.34%↓

Yomitoku

​

9.3%

8.14%↓ 🌟

6.4%↓ 🌟

Tesseract

​

78.2%

75.87%↓

75.58%↓

31 of 36

Developer Experience

​

Ease of setup

31

⭐️⭐️⭐️

Paddle

⭐️⭐️⭐️

​

​

​

⭐️⭐️

​

No GPU support

​

​

​

Yomitoku

Tesseract

32 of 36

Developer Experience

​

Documentation quality

32

⭐️⭐️⭐️

Paddle

⭐️⭐️

​

​

​

⭐️⭐️⭐️

​

​

​

Yomitoku

Tesseract

33 of 36

Developer Experience

​

Output for downstream processing

33

⭐️⭐️⭐️

​

​

​

​

⭐️⭐️⭐️

​

Paddle

⭐️⭐️⭐️

Shows text detection confidence rate

​

⭐️⭐️⭐️

​

⭐️

hOCR a legacy OCR output format that requires additional styling or processing to render in a browser.

​

⭐️

Page

└─ Block

└─ Paragraph

└─ Line

└─ Word

​

​

Yomitoku

Tesseract

Transparent output with intermediate steps

​

Easy to parse text and position pairing

​

34 of 36

Yomitoku 👑

Merits

Struggles only with poor handwriting and low-quality images.

​

Limited language support.

​

Licensing (CC BY-NC 4.0) does not guarantee commercial use.

Accurate recognition Consistently extracts text with minimal errors, even from complex layouts.

​

Fast processing

​

​

34

Limitations

35 of 36

Paddle

Merits

Layout sensitivity Error rate rises on documents with complex layouts.

​

Language coverage Broader than some models, but still limited.

Reliable output Delivers text recognition with high readability on fairly complex documents.

​

Fast processing

​

Versatile pipelines Supports a wide range of text processing tasks.

​

Open licensing Apache 2.0 license allows unrestricted commercial use.

​

35

Limitations

36 of 36

Tesseract

Merits

Low accuracy Performs poorly on real-world documents.

​

Slow processing Noticeably longer processing times.

Moderate accuracy Performs reliably on high-resolution documents with straightforward consistent text blocks.

​

Extensive language support Covers a wide range of languages.

​

Open licensing Apache 2.0 license permits unrestricted commercial use.

​

​

36

Limitations