Publish AI, ML & data-science insights to a global community of data professionals.

Parse Scanned PDFs for RAG with EasyOCR: Free OCR Gives You Words, Not a Document

Enterprise Document Intelligence [Vol.1 #5quinquies] – Same 1974 scanned PDF, two engines. EasyOCR recovers text. Docling recovers text + sections + figures. The structural gap makes one output usable downstream and the other one a flat string.

Photo by Aakash Chary, via Pexels.

This article is a parsing companion in Enterprise Document Intelligence, the series that builds an enterprise RAG system from four bricks. Article 5 (document parsing) built the parser with PyMuPDF (fitz), which returns empty on a scanned page with no text layer. This companion swaps the engine for EasyOCR, a free OCR package that recovers that text. It is the one case in this family where the new engine gives you less, not more: it recovers the text and nothing around it, and that gap is the lesson.本文是企业文档智能系列中的解析伴侣,该系列从四个模块构建企业RAG系统。第5篇文章(文档解析)使用PyMuPDF(fitz)构建解析器,但在没有文本层的扫描页面上返回空结果。本伴侣将引擎替换为EasyOCR,一个免费的OCR包,用于恢复文本。这是该系列中唯一一个新引擎提供更少而非更多信息的情况:它只恢复文本,而不恢复其周围内容,这一差距正是本文的教训。

where this companion sits: it extends Article 5 (document parsing), inside Part II (the four bricks), with a different parsing engine – Image by author本伴侣的位置:它扩展了第5篇文章(文档解析),属于第二部分(四个模块),使用不同的解析引擎——作者提供的图片

Scanned PDFs are not solved by “just throw OCR at it”. The OCR step recovers text; that’s necessary but not sufficient for an enterprise RAG pipeline. What the pipeline also needs is everything around the text: where the page boundaries are, which lines are section headings, what is a figure, what is a table row vs a free paragraph. “Traditional OCR” (the term of art for text-detection + text-recognition engines like EasyOCR, Tesseract, PaddleOCR) gives you the text. It gives you nothing else. The rest is the layout problem, and the layout problem is the harder half.扫描PDF并非“直接扔给OCR”就能解决。OCR步骤恢复文本;这对企业RAG管道来说是必要但不充分的。管道还需要文本周围的一切:页面边界在哪里,哪些行是章节标题,什么是图形,什么是表格行与自由段落。“传统OCR”(指文本检测+文本识别引擎,如EasyOCR、Tesseract、PaddleOCR)只提供文本,不提供其他任何内容。其余的是布局问题,而布局问题才是更困难的一半。

This article runs that distinction concretely. The traditional-OCR engine is EasyOCR: the simplest, fastest, free, JaidedAI’s text-detection + recognition library (Apache 2.0, declared in the project’s LICENSE file). The layout-aware engine is Docling (Article 5ter; MIT license, declared in the project’s LICENSE file). Both can OCR a scanned page. They differ on what they do with the result. The whole article is a setup for the head-to-head on a real public-domain 1974 scan in section 5.本文具体展示了这一区别。传统OCR引擎是EasyOCR:最简单、最快、免费,JaidedAI的文本检测+识别库(Apache 2.0,在项目的LICENSE文件中声明)。布局感知引擎是Docling(第5ter篇文章;MIT许可证,在项目的LICENSE文件中声明)。两者都能对扫描页面进行OCR。它们的区别在于对结果的处理方式。整篇文章是为第5节中真实公共领域1974年扫描的正面比较做铺垫。

EasyOCR is the OCR floor: line_df only, no layout. The rest of the family adds structure – Image by authorEasyOCR是OCR的基础:只有line_df,没有布局。系列中的其他引擎在此基础上添加结构——作者提供的图片

1. What “traditional OCR” does (and doesn’t)1. “传统OCR”能做什么(以及不能做什么)

Traditional OCR reads pixels and returns text rectangles. Everything else, sections, tables, figures, reading order, is a separate layout problem the engine refuses to look at. The two models behind it are text detection (find rectangular regions of the image that contain text) and text recognition (read each region’s pixels and return characters with a confidence score). The output is a flat list of (bbox, text, confidence) per detected region.传统OCR读取像素并返回文本矩形。其他所有内容——章节、表格、图形、阅读顺序——都是引擎拒绝处理的独立布局问题。其背后的两个模型是文本检测(找到图像中包含文本的矩形区域)和文本识别(读取每个区域的像素并返回字符及置信度分数)。输出是每个检测区域的(边界框、文本、置信度)平面列表。

That is everything EasyOCR (or Tesseract, or PaddleOCR) does. The engine reads pixels and returns text rectangles. A two-column page comes back as a flat list of left-and-right text boxes intermixed by y-coordinate; the engine does not know there are two columns. A table comes back as a grid of disconnected cells the engine cannot tell apart from regular paragraphs. A figure caption is just another text box. The page header, page footer, marginalia all show up as boxes too.这就是EasyOCR(或Tesseract、PaddleOCR)所做的全部。引擎读取像素并返回文本矩形。双栏页面返回的是按y坐标混合的左右文本框平面列表;引擎不知道存在两栏。表格返回为断开连接的单元格网格,引擎无法将其与普通段落区分。图形标题只是另一个文本框。页眉、页脚、旁注也都显示为文本框。

Anything that needs “this text is a section heading” or “these four boxes are one table row” needs a second model on top, a layout model. The layout model reads the OCR output plus the page image and classifies each region (heading, paragraph, table cell, figure, caption, footer…) and groups them into a reading order. That is what Article 5bis (Azure DI), Article 5ter (Docling), and Article 5quater (vision LLM) all add over the OCR step. Without one, you have “OCR output”, not “a parsed document”.任何需要“这段文本是章节标题”或“这四个框是一个表格行”的内容都需要在其上叠加第二个模型,即布局模型。布局模型读取OCR输出和页面图像,对每个区域进行分类(标题、段落、表格单元格、图形、标题、页脚……),并将它们分组为阅读顺序。这就是第5bis篇(Azure DI)、第5ter篇(Docling)和第5quater篇(视觉LLM)在OCR步骤之上添加的内容。没有布局模型,你得到的是“OCR输出”,而不是“解析后的文档”。

2. EasyOCR: the canonical traditional OCR2. EasyOCR:经典的传统OCR

EasyOCR is the cleanest demonstration of “traditional OCR” as a class. The library is small (~150 MB of model weights cached on first call), free, CPU-only by default, local. The whole library API is two calls: build a Reader for the languages you need, then hand readtext an image. Each detection comes back as a triple: the polygon around the text, the recognised string, and the recogniser’s own confidence.EasyOCR是“传统OCR”类别最清晰的示例。该库体积小(首次调用时缓存约150 MB的模型权重),免费,默认仅CPU,本地运行。整个库API只有两个调用:为所需语言构建一个Reader,然后将图像传递给readtext。每个检测返回一个三元组:文本周围的多边形、识别出的字符串以及识别器自身的置信度。

import easyocr
import fitz
import numpy as np

reader = easyocr.Reader(["en"], gpu=False)        # first call downloads ~150 MB

# render page 1 of a scanned PDF to a numpy array EasyOCR can read
page = fitz.open("data/contracts/scanned_amendment.pdf")[0]
pix = page.get_pixmap(matrix=fitz.Matrix(2.0, 2.0))   # 2x zoom = ~144 DPI
img = np.frombuffer(pix.samples, dtype=np.uint8).reshape(
    pix.height, pix.width, pix.n,
)

# the recogniser: one image in, one triple per detected text region out
detections = reader.readtext(img)
for quad, text, conf in detections:
    # quad = [[x0,y0], [x1,y0], [x1,y1], [x0,y1]]  in pixel coords
    print(round(conf, 2), text)

parse_pdf_easyocr wraps that loop. It walks every page of the PDF, renders each to a numpy array, calls readtext, converts the pixel-space polygons back to PDF coordinates, and packs the detections into the same dict-of-tables contract as the other parsers, same line_df, same parsing_summary, same downstream consumers, except that only those two keys carry data. Every other slot (page_df, image_df, toc_df, span_df, object_registry, cross_ref_df) comes back as an empty DataFrame. That isn’t a missing-feature bug; it’s exactly what “traditional OCR” means.parse_pdf_easyocr封装了该循环。它遍历PDF的每一页,将每页渲染为numpy数组,调用readtext,将像素空间的多边形转换回PDF坐标,并将检测结果打包成与其他解析器相同的dict-of-tables契约,相同的line_df、相同的parsing_summary、相同的下游消费者,只是只有这两个键携带数据。其他所有槽位(page_df、image_df、toc_df、span_df、object_registry、cross_ref_df)都返回空DataFrame。这不是功能缺失的bug;这正是“传统OCR”的含义。

parsed = parse_pdf_easyocr(
    "data/contracts/scanned_amendment.pdf",
    languages=("en",),         # add "fr", "de", ... for multilingual scans
    render_scale=2.0,          # 2.0 = ~144 DPI ; raise for small fonts
    gpu=False,                 # CPU-only by default ; set True if CUDA available
    confidence_threshold=0.0,  # filter low-confidence detections if needed
)

parsed["line_df"]              # text + bbox + confidence per detection
parsed["parsing_summary"]      # method, page count, line count, render scale
# Every other key (page_df, image_df, toc_df, span_df, object_registry,
# cross_ref_df) is an empty DataFrame ; EasyOCR has nothing to put there.

The signature kwargs are the only knobs:签名kwargs是唯一的调节旋钮:

  • languages: tuple of ISO-639-1 codes (en, fr, de, zh, …). A multilingual corpus loads one Reader per language set; the @lru_cache in get_easyocr_reader keeps a handful of these in memory across calls.languages:ISO-639-1代码元组(en、fr、de、zh等)。多语言语料库为每种语言集加载一个Reader;get_easyocr_reader中的@lru_cache在调用之间保留少量此类Reader在内存中。
  • render_scale: how many pixels per PDF unit when rasterising each page. 1.0 is native (~72 DPI, often too small). 2.0 is the sweet spot for body text. Raise to 3.0 for tiny fonts; lower if you’re memory-bound.render_scale:每页栅格化时每个PDF单位的像素数。1.0是原生(约72 DPI,通常太小)。2.0是正文文本的最佳点。对于小字体提高到3.0;如果内存受限则降低。
  • gpu: CPU is the default so the module works on any machine. CUDA gives a 3-5x speedup on text-heavy pages.gpu:默认使用CPU,以便模块在任何机器上工作。CUDA在文本密集页面上提供3-5倍加速。
  • confidence_threshold: drop low-confidence detections. 0.0 keeps everything (the column is preserved so downstream code can filter), 0.3 cuts most noise on degraded scans.confidence_threshold:丢弃低置信度检测。0.0保留所有内容(保留列以便下游代码过滤),0.3可消除退化扫描上的大部分噪声。

3. What line_df looks like3. line_df的样子

Sample rows from the NIST FIPS 199 cover (US Government work, public domain in the US, see NIST copyright statement), one per detected text region: the page coordinate, the OCR’d text, and the recogniser’s own confidence score. That is the whole output.来自NIST FIPS 199封面的示例行(美国政府作品,美国公共领域,见NIST版权声明),每个检测到的文本区域一行:页面坐标、OCR文本和识别器自身的置信度分数。这就是全部输出。

Same column shape as fitz’s line_df, plus a confidence column EasyOCR adds for free – Image by author与fitz的line_df相同的列形状,加上EasyOCR免费添加的置信度列——作者提供的图片

The shape is deliberately small:形状故意保持小巧:

  • text + bbox: the recogniser’s payload, one row per detected text region.text + bbox:识别器的负载,每个检测到的文本区域一行。
  • confidence: float between 0 and 1, EasyOCR’s self-score. Useful both as a filter (drop below 0.3 on noisy scans) and as a feedback signal (Article 8’s generation can flag low-confidence passages to the user).confidence:0到1之间的浮点数,EasyOCR的自我评分。既可用作过滤器(在噪声扫描上丢弃低于0.3的),也可用作反馈信号(第8篇文章的生成可以标记低置信度段落给用户)。
  • character_count: kept for symmetry with the other parsers; on EasyOCR it’s just len(text).character_count:为与其他解析器保持对称而保留;在EasyOCR上只是len(text)。
  • No column / reading-order column. A two-column page comes back as a flat list, left-and-right boxes intermixed by y-coordinate.没有列/阅读顺序列。双栏页面返回为平面列表,左右框按y坐标混合。

Every other key in the returned dict (page_df, image_df, toc_df, span_df, object_registry, cross_ref_df) is an empty DataFrame. A consumer that calls parsed["image_df"] does not crash; it iterates an empty frame.返回字典中的其他所有键(page_df、image_df、toc_df、span_df、object_registry、cross_ref_df)都是空DataFrame。调用parsed["image_df"]的消费者不会崩溃;它会迭代一个空框架。

4. What traditional OCR misses, the layout gap, item by item4. 传统OCR遗漏的内容:布局差距,逐项说明

Five structural artefacts that the RAG pipeline needs and that traditional OCR cannot produce, regardless of how big the recognition model is. Each one breaks a downstream operation the rest of the series relies on.RAG管道需要的五种结构产物,传统OCR无法生成,无论识别模型有多大。每一种都会破坏系列其余部分依赖的下游操作。

  • TOC / sections. Cross-reference resolution (Article 11) and section-scoped corpus retrieval (Article 17) both rely on toc_df. EasyOCR returns zero rows. The dispatcher cannot route “answer in Section 3.2” questions because Section 3.2 has no boundary.目录/章节。交叉引用解析(第11篇文章)和章节范围语料库检索(第17篇文章)都依赖toc_df。EasyOCR返回零行。调度器无法路由“在3.2节中回答”的问题,因为3.2节没有边界。
  • Individual figures inside the page. A scanned 30-page contract may contain six chart screenshots embedded in the body text. EasyOCR treats the whole page as one image and returns text from around the figures; the figures themselves never become rows. A downstream pipeline that needs to retrieve “the chart on page 14” has no handle.页面内的单个图形。一份30页的扫描合同可能包含嵌入正文的六个图表截图。EasyOCR将整个页面视为一张图像,并返回图形周围的文本;图形本身永远不会成为行。需要检索“第14页上的图表”的下游管道没有句柄。
  • Reading order on multi-column / multi-zone pages. A two-column scientific paper page comes back top-to-bottom across both columns intermixed: left-line-1, right-line-1, left-line-2, right-line-2… Generation reads garbage. Sidebars, footnotes, marginalia all leak into the main flow.多栏/多区域页面的阅读顺序。双栏科学论文页面按从上到下跨两栏混合返回:左栏第1行、右栏第1行、左栏第2行、右栏第2行……生成的内容读起来像垃圾。侧边栏、脚注、旁注都泄漏到主流程中。
  • Table cells. A scanned schedule of charges or premium table comes back as a flat list of disconnected text boxes (the row labels in one column, the values in another, the unit headers somewhere else). The relationship “this value belongs to this label” is lost. Article 5 (document parsing) opens on exactly this failure mode (“the parser walked the table cell by cell and joined them into a flat string”). Layout-aware engines run a separate TableFormer-style model to reconstruct rows × columns × headers.表格单元格。扫描的费用表或保费表返回为断开连接的文本框平面列表(一列中的行标签,另一列中的值,某处的单位标题)。“这个值属于这个标签”的关系丢失了。第5篇文章(文档解析)正是以这种失败模式开篇(“解析器逐个单元格遍历表格并将它们连接成平面字符串”)。布局感知引擎运行一个单独的TableFormer风格模型来重建行×列×标题。
  • Font / weight / size signals. OCR recovers character shape, not its typographic encoding. “This line is in bold 18pt” is information the layout engine reads from the page rendering; EasyOCR throws it away. Headings, emphasis, footnotes lose the cue that would have classified them.字体/粗细/大小信号。OCR恢复字符形状,而不是其排版编码。“这一行是粗体18磅”是布局引擎从页面渲染中读取的信息;EasyOCR丢弃了它。标题、强调、脚注失去了本可对其进行分类的线索。

Take the third one, reading order, because it is the one that quietly corrupts an answer. EasyOCR returns text boxes sorted by their y-coordinate. On a two-column page the two columns sit at the same heights, so the boxes come back interleaved: first line of the left column, first line of the right column, second line of the left, and so on. The prose reads as a zigzag, and generation quotes the zigzag.以第三个问题——阅读顺序为例,因为它会悄悄破坏答案。EasyOCR按y坐标排序返回文本框。在双栏页面上,两栏位于相同高度,因此框交错返回:左栏第一行、右栏第一行、左栏第二行,依此类推。文本读起来像锯齿形,生成的内容引用了锯齿形。

with no layout model, boxes come back sorted by y, so a two-column page interleaves into a zigzag – Image by author没有布局模型时,框按y坐标排序返回,因此双栏页面交错成锯齿形——作者提供的图片

The single sentence: the OCR step recovers text, the layout step recovers what makes the text usable. Article 5ter (Docling) and Article 5bis (Azure DI) add the layout step on top of the same OCR. Article 5quater (vision LLM) folds the two into one call. EasyOCR stops at the OCR step.一句话总结:OCR步骤恢复文本,布局步骤恢复使文本可用的内容。第5ter篇(Docling)和第5bis篇(Azure DI)在相同OCR之上添加了布局步骤。第5quater篇(视觉LLM)将两者合并为一次调用。EasyOCR止步于OCR步骤。

5. EasyOCR vs Docling on a real scanned PDF5. EasyOCR与Docling在真实扫描PDF上的对比

On the same 1974 scan, Docling extracts more characters (5,423 vs 4,952), the page boundaries, eleven TOC entries, and four figure regions. EasyOCR extracts text rectangles and stops. The two engines agree at the character level, both OCR with the same recogniser-class accuracy, but Docling’s layout pass turns the OCR output into a document.在同一份1974年扫描件上,Docling提取了更多字符(5,423 vs 4,952)、页面边界、11个目录条目和4个图形区域。EasyOCR提取文本矩形并停止。两个引擎在字符级别一致,都以相同的识别器类精度进行OCR,但Docling的布局传递将OCR输出转化为文档。

The interesting comparison is not against fitz (fitz returns zero on a scan) but against the next engine up: Docling, the local layout-aware parser from Article 5ter. The comparison is cleaner than it looks: Docling’s default OCR backend is EasyOCR itself. Same recognizer reading the same pixels; the difference is everything Docling builds around it.有趣的比较不是针对fitz(fitz在扫描件上返回零),而是针对下一个引擎:Docling,来自第5ter篇的本地布局感知解析器。这个比较比看起来更清晰:Docling的默认OCR后端就是EasyOCR本身。相同的识别器读取相同的像素;区别在于Docling围绕它构建的一切。

The test case is a real public-domain scan: pages 1–5 of karg74.pdf, the 1974 USAF MULTICS Security Evaluation (Karger & Schell, ESD-TR-74-193 Vol. II). NIST hosts it in their Early Computer Security Papers archive; the work is in the public domain as the output of US Air Force officers. The PDF has Adobe’s “Paper Capture” OCR layer baked in, but we ignore it, both engines re-OCR from page images, which is the realistic scenario when the embedded OCR (when present) is unreliable.测试用例是真实的公共领域扫描件:karg74.pdf的第1-5页,1974年美国空军MULTICS安全评估(Karger & Schell, ESD-TR-74-193 Vol. II)。NIST将其托管在早期计算机安全论文档案中;作为美国空军军官的产出,该作品属于公共领域。PDF嵌入了Adobe的“Paper Capture”OCR层,但我们忽略它,两个引擎都从页面图像重新OCR,这是当嵌入式OCR(如果存在)不可靠时的现实场景。

The real comparison. Both re-OCR the page images; Docling adds layout – Image by author真正的比较。两者都重新OCR页面图像;Docling添加了布局——作者提供的图片

The two columns tell different stories.两列讲述了不同的故事。

EasyOCR (left). Faster (59.7 s vs 134.4 s, no layout model to load and run), ships the recogniser’s confidence as a column (mean 0.81 on this scan), produces more row-level detections (346 boxes) because every text region in the page becomes one row. Zero structure: no page_df, no toc_df, no image_df. The output is text in bbox form, nothing else.EasyOCR(左)。更快(59.7秒 vs 134.4秒,无需加载和运行布局模型),将识别器的置信度作为一列输出(此扫描件平均0.81),产生更多行级检测(346个框),因为页面中的每个文本区域都成为一行。零结构:没有page_df,没有toc_df,没有image_df。输出是边界框形式的文本,仅此而已。

Docling (right). Slower (2.3× more compute), joins detections into 105 lines/paragraphs rather than 346 boxes, no confidence column. The structural gain is real: 5 page_df rows, 11 toc_df entries (Docling’s layout model classifies headings as sections), 4 image_df rows (figures detected inside the page as separate objects). On a PDF with tables, the gap widens further, Docling’s TableFormer recognises rows × columns × headers, which EasyOCR cannot do at all. Article 5ter develops the table case in full.Docling(右)。更慢(2.3倍计算量),将检测合并为105行/段落而非346个框,没有置信度列。结构增益是真实的:5行page_df,11个toc_df条目(Docling的布局模型将标题分类为章节),4行image_df(页面内检测到的图形作为独立对象)。在包含表格的PDF上,差距进一步扩大,Docling的TableFormer识别行×列×标题,这是EasyOCR完全无法做到的。第5ter篇详细阐述了表格案例。

Both engines OCR with similar character-level error rates on this 1974 scan (Karger → “Karger” by EasyOCR, “Karger” by Docling on the cleanest page; degraded regions yield similar noise on both, “Laboralory”, “und” instead of “and”). The OCR engine inside Docling (EasyOCR or OnnxTR depending on install) is not magically more accurate than calling EasyOCR directly. What Docling adds is how it organises the OCR output, not how it OCRs.两个引擎在这份1974年扫描件上的字符级错误率相似(最清晰页面上EasyOCR将“Karger”识别为“Karger”,Docling识别为“Karger”;退化区域两者产生相似噪声,如“Laboralory”、“und”代替“and”)。Docling内部的OCR引擎(取决于安装的是EasyOCR还是OnnxTR)并不比直接调用EasyOCR更准确。Docling增加的是如何组织OCR输出,而不是如何OCR。

For enterprise RAG, the right call is Docling almost always. The 2.3× compute is paid once at ingestion (the parse cache from Article 5 (document parsing) reuses results forever); the structural gain (TOC, figures, table cells, reading order) is paid back on every downstream query. The one thing Docling does not ship is EasyOCR’s row-level confidence signal, which is rarely worth giving up sections + figures + tables.对于企业RAG,几乎总是选择Docling。2.3倍的计算量在摄取时一次性支付(第5篇文章的解析缓存永久重用结果);结构增益(目录、图形、表格单元格、阅读顺序)在每次下游查询中回报。Docling没有提供的是EasyOCR的行级置信度信号,但为了章节+图形+表格,很少值得放弃。

6. When traditional OCR still earns its keep6. 传统OCR何时仍有用武之地

EasyOCR is the emergency package of the family: less visibility into the document, simpler dependencies, faster to deploy when the constraint is operational rather than pedagogical. Four narrow cases keep the door open.EasyOCR是该系列的应急包:对文档的可见性较低,依赖更简单,当约束是操作而非教学时部署更快。四个狭窄的案例为其保留了空间。

  • Receipt-class documents. A 1-page invoice or receipt with no headings, no sections, no figures, no tables-with-merged-cells. Layout is trivial; the recogniser is the whole job. Adding Docling’s 2× compute buys structure the document doesn’t have.收据类文档。一页发票或收据,没有标题、章节、图形、合并单元格的表格。布局微不足道;识别器就是全部工作。添加Docling的2倍计算量购买的是文档本身不存在的结构。
  • Per-region confidence as a generation feedback signal. Generation (Article 8) can read the row’s confidence from the cited passage and warn the user when the answer rests on a 0.3-confidence bit of OCR. Docling does not ship that column. For pipelines where this signal is load-bearing, EasyOCR (or running EasyOCR alongside Docling) is the answer.按区域置信度作为生成反馈信号。生成(第8篇文章)可以读取引用段落的行置信度,并在答案依赖于0.3置信度的OCR时警告用户。Docling不提供该列。对于此信号至关重要的管道,EasyOCR(或与Docling并行运行EasyOCR)是答案。
  • Non-Latin scripts at scale. EasyOCR ships pretrained models for 80+ languages including Chinese, Japanese, Korean, Arabic, Hindi, Cyrillic. Docling’s OCR stack is more limited in non-Latin coverage at the time of writing.大规模非拉丁文字。EasyOCR为80多种语言提供预训练模型,包括中文、日文、韩文、阿拉伯文、印地文、西里尔文。Docling的OCR栈在非拉丁文覆盖方面目前较为有限。
  • Operational constraints that block Docling. Corp SSL inspection breaks the HuggingFace model download. Windows blocks symlinks without Developer Mode. The production image has a strict dependency budget. Air-gapped deployment with no way to ship 3 GB of layout weights. In every one of these, EasyOCR’s 150 MB cached model + CPU inference goes through where Docling does not. You see less of the document, but you see something.阻止Docling的操作约束。企业SSL检查破坏HuggingFace模型下载。Windows在没有开发者模式的情况下阻止符号链接。生产镜像有严格的依赖预算。无法传输3 GB布局权重的气隙部署。在所有这些情况下,EasyOCR的150 MB缓存模型+CPU推理可以工作,而Docling不行。你对文档的可见性较低,但至少能看到一些东西。

Outside these cases: default to Docling on scans, Azure DI on regulated-cloud-OK shops, vision LLM when the document has handwriting / signatures / a non-textual semantic layer. The adaptive-parsing dispatcher (Article 10) routes automatically.在这些情况之外:扫描件默认使用Docling,受监管云环境使用Azure DI,文档包含手写/签名/非文本语义层时使用视觉LLM。自适应解析调度器(第10篇文章)自动路由。

7. Conclusion7. 结论

OCR recovers characters. Layout recovers what makes the characters useful, sections, figures, table cells, reading order. The default engine for scans is the one that does both. The full Article-5 family lines up by the same axis:OCR恢复字符。布局恢复使字符有用的内容:章节、图形、表格单元格、阅读顺序。扫描件的默认引擎是两者都做的那个。完整的第5系列按同一轴排列:

EasyOCR sits at the OCR floor (line_df only); every other engine in the family adds a layout step on top – Image by authorEasyOCR位于OCR基础层(仅line_df);系列中的每个其他引擎在其上添加布局步骤——作者提供的图片

EasyOCR is the OCR floor, what you get when you stop at recognising characters and never ask “and where are they on the page?” The question matters. “Where on the page” makes the difference between a list of text boxes and a parsed document. The dispatcher of Article 10 (adaptive parsing) picks the right engine per page; this article exists so the dispatcher knows what it gives up when it picks the cheap one.EasyOCR是OCR的基础层,是你在识别字符后停止并从不问“它们在页面上的位置?”时得到的结果。这个问题很重要。“在页面上的位置”决定了文本框列表和解析文档之间的区别。第10篇文章(自适应解析)的调度器为每页选择正确的引擎;本文的存在是为了让调度器知道当它选择便宜的引擎时放弃了什么。

8. Sources and further reading8. 来源与进一步阅读

EasyOCR is the most reachable traditional OCR engine in 2026; PaddleOCR (Baidu) and Tesseract (Google, decades-old) sit beside it in the same family. The layout step on top is what separates “OCR” from “document parsing”; Docling (Article 5ter) and Azure DI (Article 5bis) both add it, on local hardware and in the cloud respectively. The right cross-reading is the layout literature (Smock et al. 2022 for table structure, Auer et al. 2024 for the full layout cascade) and the alternative OCR engines for non-Latin scripts.EasyOCR是2026年最易接触的传统OCR引擎;PaddleOCR(百度)和Tesseract(谷歌,数十年历史)属于同一家族。其上的布局步骤将“OCR”与“文档解析”区分开来;Docling(第5ter篇)和Azure DI(第5bis篇)都添加了它,分别在本地硬件和云端。正确的交叉阅读是布局文献(Smock等人2022年关于表格结构,Auer等人2024年关于完整布局级联)以及非拉丁文字的替代OCR引擎。

Same direction as the article:与文章方向相同:

  • JaidedAI, EasyOCR. The library this article documents, including the 80+ language model packs.JaidedAI, EasyOCR。本文记录的库,包括80多种语言模型包。
  • PaddleOCR (Baidu). Same-class traditional OCR engine; better Chinese coverage, similar layout blindness.PaddleOCR(百度)。同类传统OCR引擎;中文覆盖更好,类似的布局盲点。
  • Tesseract OCR. The decades-old reference, still widely deployed; same architectural shape as EasyOCR (detection + recognition, no layout).Tesseract OCR。数十年历史的参考,仍广泛部署;与EasyOCR相同的架构形状(检测+识别,无布局)。

Different angle, different context:不同角度,不同背景:

  • Auer et al., Docling Technical Report, IBM Research 2024 (arXiv:2408.09869). The layout-aware cascade that turns OCR output into a parsed document; the comparison point in section 5 of this article.Auer等人,Docling技术报告,IBM Research 2024(arXiv:2408.09869)。将OCR输出转化为解析文档的布局感知级联;本文第5节的比较点。
  • Smock, Pesala, Abraham, PubTables-1M / Table Transformer (TATR), CVPR 2022 (arXiv:2110.00061). The research lineage behind cell-level table extraction, the single biggest capability EasyOCR lacks.Smock, Pesala, Abraham, PubTables-1M / Table Transformer (TATR), CVPR 2022(arXiv:2110.00061)。单元格级表格提取的研究谱系,这是EasyOCR最缺乏的能力。

Earlier in the series:系列早期文章:


Towards Data Science is a community publication. Submit your insights to reach our global audience and earn through the TDS Author Payment Program.

Write for TDS

Related Articles

Some areas of this page may shift around if you resize the browser window. Be sure to check heading and document order.