新闻详情

新闻详情

首页 / 资讯中心 / 详情

开源OCR实战:Tesseract与PaddleOCR提取图片和PDF文字

发布时间:2026/10/2 5:46:55来源:尧图网络
开源OCR实战:Tesseract与PaddleOCR提取图片和PDF文字
1. 为什么我又把OCR这件事翻出来折腾了一遍日常办公里最让人抓狂的场景之一就是拿到一份扫描版PDF或者一张截图里面的文字明明看得清清楚楚但就是选不中、复制不了。想改一个字得对着屏幕手敲想引用一段话得逐字校对。这种时候一个靠谱的OCR工具就是救命稻草。我最早接触OCR是好几年前那时候用的还是某商业软件的试用版识别几页就提示要付费而且中文识别率感人标点符号经常乱飞。后来陆续试过在线OCR服务、手机App、各种桌面端工具要么有页数限制要么要上传到别人服务器要么识别完排版全乱。直到我开始用开源OCR方案才算真正把这件事掌握在自己手里。这篇文章要聊的就是怎么用开源OCR工具把图片和PDF里的文字快速、准确地提取出来。核心关键词就几个OCR、开源、PDF、图片、文字提取。不管你是完全没接触过OCR的新手还是用过一些工具但觉得不够顺手的老用户下面这些内容都能直接拿去用。我会从方案选型讲到实操步骤再到踩过的坑和排查技巧尽量把每个环节都说透。先说结论目前开源OCR领域最成熟、最省心的组合是Tesseract OCR引擎加上一个顺手的调用方式命令行或者Python脚本如果对中文识别要求更高可以上PaddleOCR。这两个都是完全开源、本地运行、不依赖网络的方案。下面我会把两条路线都讲清楚你根据自己的需求选。2. 开源OCR方案怎么选Tesseract还是PaddleOCR2.1 两个主流开源OCR引擎的定位差异Tesseract的历史可以追溯到上世纪八十年代后来由惠普开源再后来由Google接手维护。它的最大优势是成熟稳定、语言包丰富、跨平台支持好。Windows、macOS、Linux上都能跑安装包也不大。缺点是默认状态下对中文的识别效果一般尤其是排版复杂或者字体特殊的场景需要做一些预处理和参数调优。PaddleOCR是百度飞桨团队开源的一套OCR工具库底层用的是深度学习模型。它在中文识别上的表现明显优于Tesseract尤其是对自然场景文字、倾斜文字、手写体的识别能力更强。而且它自带方向分类、版面分析等功能开箱即用的效果就很好。缺点是对硬件有一定要求虽然CPU也能跑但如果有GPU会快很多另外安装过程比Tesseract稍微复杂一点。我自己的使用策略是这样的如果只是偶尔提取一些印刷体文档、截图里的文字Tesseract足够了装起来快用起来简单。如果需要批量处理大量中文文档或者对识别准确率要求很高那就上PaddleOCR。两者并不冲突可以都装着按场景切换。2.2 不同场景下的选型建议为了让你更直观地做决定我整理了一个对比表格对比维度Tesseract OCRPaddleOCR中文识别准确率中等需调优高开箱即用英文识别准确率高高安装难度低中等运行速度CPU快中等运行速度GPU不支持快语言包支持100种语言80种语言版面分析弱强手写体识别差较好适合场景印刷体文档、截图复杂版面、批量处理如果你只是想把一张截图里的几行字提出来Tesseract命令行一行命令就搞定。如果你要处理几百页的扫描PDF而且里面有表格、多栏排版PaddleOCR会更省心。还有一个选择维度是是否需要保留排版。Tesseract默认输出的是纯文本段落结构会丢失。PaddleOCR可以输出带坐标信息的结构化结果方便你后续还原版面。如果你只是要文字内容不需要保留格式两者都行。如果你要把识别结果还原成Word或者保持原来的段落结构PaddleOCR更有优势。2.3 为什么我不推荐在线OCR服务顺便说一句很多人第一反应是用在线OCR服务觉得方便。但有几个问题第一隐私。你把合同、身份证、内部文档上传到别人服务器风险不用我多说。第二限制。免费版通常有页数或文件大小限制批量处理很麻烦。第三稳定性。服务说关就关接口说变就变你依赖它就有断档的风险。开源本地方案虽然前期配置花点时间但一次搞定之后就是一劳永逸。3. Tesseract OCR从安装到出结果完整实操流程3.1 Windows下的安装与配置Windows上安装Tesseract最简单的方式是下载官方编译好的安装包。你可以在GitHub的UB-Mannheim仓库找到最新的Windows安装程序。下载后双击安装注意在安装向导里勾选Additional language data把中文语言包一起装上。默认安装路径是C:\Program Files\Tesseract-OCR记住这个路径后面配置环境变量要用。安装完成后需要把Tesseract的安装目录添加到系统环境变量Path里。具体操作右键“此电脑”-属性-高级系统设置-环境变量-在系统变量里找到Path-编辑-新建-填入C:\Program Files\Tesseract-OCR-确定保存。然后打开命令提示符输入tesseract --version如果能看到版本号输出说明安装配置成功。语言包方面中文需要chi_sim简体和chi_tra繁体两个文件。如果你安装时没勾选可以单独下载语言包文件放到Tesseract安装目录下的tessdata文件夹里。下载地址在Tesseract的GitHub仓库的tessdata目录下找到对应的.traineddata文件下载即可。3.2 macOS和Linux下的安装macOS上用Homebrew安装最方便brew install tesseract brew install tesseract-lang第二条命令会安装所有语言包包括中文。安装完成后同样用tesseract --version验证。Linux以Ubuntu为例sudo apt update sudo apt install tesseract-ocr sudo apt install tesseract-ocr-chi-sim sudo apt install tesseract-ocr-chi-tra如果你需要其他语言把chi-sim换成对应的语言代码即可。3.3 命令行直接提取图片文字安装配置好之后最基本的用法是这样的tesseract input.png output -l chi_sim这条命令的意思是识别input.png里的文字结果保存到output.txt使用简体中文语言包。如果你同时有中英文混排的内容可以这样写tesseract input.png output -l chi_simengTesseract会自动在两种语言之间切换识别。实测下来中英文混排的场景用chi_simeng比单用chi_sim效果好很多因为纯中文语言包对英文字母的识别率会下降。对于PDF文件Tesseract本身不直接支持PDF输入需要先把PDF转成图片。可以用ImageMagick或者pdftoppm来做这件事pdftoppm -png -r 300 input.pdf page这条命令会把PDF的每一页转成300 DPI的PNG图片文件名依次是page-1.png、page-2.png等等。然后对每一张图片跑Tesseract就行了。300 DPI是我实测下来比较合适的值再低会影响识别率再高文件会很大但识别率提升有限。3.4 用Python批量处理图片和PDF如果你要批量处理写个Python脚本会方便很多。先安装依赖pip install pytesseract pillow pdf2image然后是一个批量处理的脚本示例import pytesseract from PIL import Image from pdf2image import convert_from_path import os # Windows下需要指定tesseract路径 # pytesseract.pytesseract.tesseract_cmd rC:\Program Files\Tesseract-OCR\tesseract.exe def ocr_image(image_path, langchi_simeng): img Image.open(image_path) text pytesseract.image_to_string(img, langlang) return text def ocr_pdf(pdf_path, langchi_simeng, dpi300): images convert_from_path(pdf_path, dpidpi) all_text [] for i, img in enumerate(images): text pytesseract.image_to_string(img, langlang) all_text.append(f--- 第{i1}页 ---\n{text}) return \n.join(all_text) # 批量处理文件夹里的图片 def batch_ocr(folder_path, output_file): results [] for filename in sorted(os.listdir(folder_path)): if filename.lower().endswith((.png, .jpg, .jpeg, .tiff, .bmp)): filepath os.path.join(folder_path, filename) text ocr_image(filepath) results.append(f {filename} \n{text}) with open(output_file, w, encodingutf-8) as f: f.write(\n\n.join(results)) if __name__ __main__: batch_ocr(./images, ./output.txt)这个脚本可以直接拿去用把图片放在images文件夹里运行后结果会输出到output.txt。PDF的处理同理调用ocr_pdf函数就行。3.5 提升识别率的关键参数调优Tesseract的默认配置不一定适合所有场景有几个参数值得调整页面分割模式PSM这个参数控制Tesseract如何分析页面结构。常用的值有--psm 3默认值自动分析页面布局--psm 6假设页面是一整块统一的文本--psm 4假设页面是单列可变大小的文本--psm 11稀疏文本适合从复杂背景中提取零散文字如果你识别的是截图或者单栏文档--psm 6通常比默认值效果好。如果是多栏排版--psm 3更合适。OCR引擎模式OEM--oem 3是默认值使用基于LSTM的神经网络引擎。除非有特殊需求否则保持默认就行。字符白名单如果你知道图片里只有数字和英文字母可以限制识别范围来提升准确率tesseract input.png output -l eng --psm 6 -c tessedit_char_whitelist0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz这个技巧在处理票据、验证码之类的场景特别有用。4. PaddleOCR上手中文识别效果更好的选择4.1 安装与环境准备PaddleOCR的安装分两步先装PaddlePaddle框架再装PaddleOCR库。以CPU版本为例pip install paddlepaddle pip install paddleocr如果你有NVIDIA显卡并且配置了CUDA可以安装GPU版本pip install paddlepaddle-gpu pip install paddleocr安装完成后第一次运行时会自动下载模型文件大约几百MB需要联网。下载完成后就可以离线使用了。4.2 三行代码完成图片文字提取PaddleOCR的Python API设计得很简洁from paddleocr import PaddleOCR ocr PaddleOCR(use_angle_clsTrue, langch) result ocr.ocr(test.png, clsTrue) for line in result[0]: print(line[1][0])use_angle_clsTrue表示启用方向分类可以自动纠正旋转的文字。langch指定中文模型。result里包含了每个文本框的坐标和识别文字line[1][0]就是识别出来的文本内容。4.3 批量处理PDF的完整方案PaddleOCR处理PDF的思路和Tesseract一样先把PDF转成图片再逐页识别。下面是一个完整的脚本from paddleocr import PaddleOCR from pdf2image import convert_from_path import os ocr PaddleOCR(use_angle_clsTrue, langch) def process_pdf(pdf_path, output_txt): images convert_from_path(pdf_path, dpi300) all_text [] for i, img in enumerate(images): img.save(f_temp_page_{i}.png) result ocr.ocr(f_temp_page_{i}.png, clsTrue) page_text \n.join([line[1][0] for line in result[0]]) if result[0] else all_text.append(f--- 第{i1}页 ---\n{page_text}) os.remove(f_temp_page_{i}.png) with open(output_txt, w, encodingutf-8) as f: f.write(\n\n.join(all_text)) print(f完成结果已保存到{output_txt}) process_pdf(document.pdf, result.txt)这个脚本会逐页处理PDF把每页的识别结果按页分隔保存。实测下来PaddleOCR对中文文档的识别准确率明显高于Tesseract尤其是对宋体、黑体之外的字体以及稍微模糊的扫描件。4.4 处理特殊场景的注意事项PaddleOCR虽然开箱即用效果好但有几个点需要注意内存占用处理高分辨率图片时PaddleOCR会占用较多内存。如果遇到内存不足的情况可以在初始化时设置rec_image_shape参数来限制输入尺寸或者先把图片缩小再识别。首次加载慢第一次运行时会加载模型可能需要几秒钟。如果你要处理大量文件建议把OCR对象初始化一次然后重复使用不要每次识别都重新创建。竖排文字PaddleOCR对竖排中文的支持有限如果遇到竖排文档可能需要先用图像处理库把图片旋转90度再识别。表格识别PaddleOCR有专门的表格识别模型PP-Structure如果你需要提取表格内容并保留结构可以研究一下这个模块。不过表格识别比纯文字识别复杂得多准确率也受表格样式影响较大。5. 图片预处理让识别率再上一个台阶5.1 为什么预处理很重要OCR引擎再强如果输入的图片质量差识别结果也好不到哪去。我踩过的坑里至少有一半的问题出在图片本身分辨率太低、对比度不够、有噪点、倾斜、阴影等等。花几分钟做预处理识别率可能从70%提升到95%以上。5.2 常用预处理操作及代码用OpenCV和Pillow可以做大部分预处理工作。先安装pip install opencv-python pillow灰度化彩色信息对文字识别没有帮助转成灰度图可以减少干扰import cv2 img cv2.imread(input.png) gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)二值化把灰度图转成黑白两色让文字和背景的对比更明显_, binary cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU)Otsu方法会自动计算最佳阈值适合大多数场景。去噪中值滤波可以去掉椒盐噪声denoised cv2.medianBlur(gray, 3)倾斜校正如果扫描件是歪的可以用霍夫变换检测直线角度然后旋转import numpy as np def deskew(image): coords np.column_stack(np.where(image 0)) angle cv2.minAreaRect(coords)[-1] if angle -45: angle -(90 angle) else: angle -angle (h, w) image.shape[:2] center (w // 2, h // 2) M cv2.getRotationMatrix2D(center, angle, 1.0) rotated cv2.warpAffine(image, M, (w, h), flagscv2.INTER_CUBIC, borderModecv2.BORDER_REPLICATE) return rotated放大如果图片分辨率太低可以先放大再识别。但要注意简单的插值放大不会增加信息量效果有限。更好的做法是用超分辨率模型不过那就复杂了。实际经验是如果原图DPI低于150识别率会明显下降建议重新扫描或者用更高的DPI重新截图。5.3 预处理流程的推荐顺序我一般按这个顺序做预处理灰度化 - 去噪 - 二值化 - 倾斜校正 - 缩放。不是每一步都必须做根据图片实际情况取舍。比如截图通常不需要去噪和倾斜校正但扫描件往往需要全套。注意二值化不是万能的。如果原图背景复杂或者有渐变强行二值化可能丢失文字细节。这种情况下保持灰度图直接识别反而效果更好。建议两种方式都试一下对比结果。6. 常见问题与排查技巧实录6.1 识别结果乱码或空白这是最常见的问题原因通常有几个语言包没装对。检查tessdata目录下是否有chi_sim.traineddata文件。如果没有去下载对应的语言包放进去。PaddleOCR的话检查初始化时的lang参数是否正确。图片路径或格式问题。Tesseract对某些格式支持不好比如WebP。建议统一转成PNG或TIFF再识别。图片质量太差。如果图片模糊、对比度低任何OCR引擎都无能为力。先做预处理或者重新获取更清晰的图片。PSM参数不合适。试试不同的--psm值有时候换个模式结果就完全不一样。6.2 中文识别率低怎么办Tesseract的中文识别率确实不如PaddleOCR但通过以下方法可以改善使用chi_simeng而不是纯chi_sim设置--psm 6假设统一文本块做二值化预处理如果还是不行换PaddleOCRPaddleOCR中文识别率低的情况比较少见如果遇到检查图片是否分辨率太低或者文字太小。PaddleOCR对小于20像素高的文字识别率会下降可以尝试放大图片。6.3 处理速度太慢的优化思路降低DPI300 DPI是精度和速度的平衡点如果对精度要求不高可以降到200 DPI。限制识别区域如果图片中只有部分区域有文字可以先裁剪出文字区域再识别减少处理面积。使用GPUPaddleOCR支持GPU加速如果有NVIDIA显卡安装GPU版本后速度可以提升5到10倍。并行处理批量处理时可以用多进程Python的multiprocessing库可以轻松实现。调整模型PaddleOCR提供了不同大小的模型默认用的是中等大小的模型。如果对速度要求高可以换用轻量级模型。6.4 常见问题速查表问题现象可能原因解决方法输出为空语言包缺失安装对应语言包中文变乱码未指定中文语言加-l chi_sim参数识别率低图片质量差预处理灰度、二值化、去噪速度慢DPI过高或图片过大降低DPI或裁剪区域段落结构丢失OCR引擎限制用PaddleOCR的结构化输出PDF无法直接识别Tesseract不支持PDF输入先转图片再识别竖排文字识别错乱引擎不支持竖排旋转图片后识别表格内容混乱未做版面分析使用PP-Structure表格识别6.5 几个我踩过的坑坑一路径里有中文或空格。Tesseract命令行对中文路径支持不好容易报错。解决办法是把文件放到纯英文路径下或者用Python调用时用os.path处理路径。坑二PDF转图片时DPI设太低。我一开始用默认的150 DPI识别率惨不忍睹。后来改成300 DPI效果立竿见影。如果原PDF是扫描件建议用400 DPI。坑三忘了关PaddleOCR的日志输出。PaddleOCR默认会打印很多日志信息批量处理时刷屏很烦。可以在初始化时设置show_logFalse来关闭。坑四Tesseract的--psm参数位置放错。这个参数必须放在输出文件名之后放在前面会被当成输入文件处理。正确的顺序是tesseract input output -l chi_sim --psm 6。坑五PaddleOCR首次运行下载模型超时。如果网络环境不好模型下载可能失败。可以手动下载模型文件放到指定目录或者设置镜像源加速下载。7. 把OCR集成到日常工作流里7.1 批量处理文件夹的自动化脚本如果你经常需要处理大量图片或PDF可以写一个带监控功能的脚本自动处理指定文件夹里的新文件import time import os from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler from paddleocr import PaddleOCR class OCRHandler(FileSystemEventHandler): def __init__(self, output_dir): self.ocr PaddleOCR(use_angle_clsTrue, langch, show_logFalse) self.output_dir output_dir def on_created(self, event): if event.is_directory: return if event.src_path.lower().endswith((.png, .jpg, .jpeg, .bmp, .tiff)): print(f检测到新文件{event.src_path}) result self.ocr.ocr(event.src_path, clsTrue) text \n.join([line[1][0] for line in result[0]]) if result[0] else base_name os.path.splitext(os.path.basename(event.src_path))[0] output_path os.path.join(self.output_dir, f{base_name}.txt) with open(output_path, w, encodingutf-8) as f: f.write(text) print(f识别完成{output_path}) observer Observer() observer.schedule(OCRHandler(./output), ./watch, recursiveFalse) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()这个脚本会监控watch文件夹一旦有新图片放进去就自动识别结果保存到output文件夹。配合截图工具的自动保存功能可以实现“截图即识别”的体验。7.2 与笔记软件联动我自己的做法是截图后自动OCR然后把文字追加到当天的笔记文件里。这样平时看到有用的内容截个图就自动归档了后面搜索笔记就能找到。实现方式是在上面的脚本里加一段追加写入的逻辑把识别结果按时间戳追加到指定文件。7.3 处理特殊格式的注意事项验证码识别验证码通常有干扰线、扭曲、粘连普通OCR效果很差。如果确实需要可以针对性地做图像预处理去干扰线、字符分割但这不是本文的重点而且验证码识别的合规性需要特别注意不要用于不当用途。公式识别普通OCR对数学公式的识别基本不可用。如果需要提取公式要用专门的公式识别工具比如LaTeX-OCR这类项目。手写体识别Tesseract对手写体基本无能为力PaddleOCR稍好但也有限。手写体识别目前仍然是个难题如果要求高可能需要用专门的手写识别模型。多语言混排中英日韩混排的文档建议用PaddleOCR的多语言模型或者分别用不同语言包识别后合并结果。8. 一些实际使用中的体会用开源OCR处理文档这件事我从最开始的手忙脚乱到现在基本能稳定输出中间经历了大概两三个月的摸索期。最大的感受是没有万能方案只有适合当前场景的方案。Tesseract和PaddleOCR各有优劣关键是根据你的具体需求来选。另一个体会是预处理的重要性怎么强调都不为过。同样一张图做不做二值化识别率可能差30%以上。花几分钟调一下对比度和阈值比换引擎的效果还明显。还有一点不要追求100%的准确率。OCR本质上是一个概率问题再好的引擎也会有出错的时候。重要的是建立一个校验机制比如识别完后快速扫一遍或者对关键字段做二次确认。对于批量处理可以先用小样本测试确认效果后再全量跑。最后说一个实用技巧如果你经常需要识别同一种版式的文档比如某种固定的票据或表格可以针对这个版式做模板匹配先定位关键区域再识别准确率会比整页识别高很多。这个思路在处理结构化文档时特别有效。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

T型结与Wilkinson功分器:原理、实测对比与选型指南 2026/10/2 7:33:13

T型结与Wilkinson功分器:原理、实测对比与选型指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
ROS2机械臂MPC轨迹规划:基于MoveIt 2的规划器插件开发指南 2026/10/2 7:33:13

ROS2机械臂MPC轨迹规划:基于MoveIt 2的规划器插件开发指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Vue3+Vite+Electron桌面应用开发实战与避坑指南 2026/10/2 7:33:13

Vue3+Vite+Electron桌面应用开发实战与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
开关电源EMC整改:PCB布局与变压器绕组协同优化 2026/10/2 7:33:13

开关电源EMC整改:PCB布局与变压器绕组协同优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
单片机系统六步硬件排查法:从上电失败到现场抽风 2026/10/2 7:33:13

单片机系统六步硬件排查法:从上电失败到现场抽风

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
STM32定时器时间基准详解:从时钟树到PSC/ARR配置 2026/10/2 7:33:06

STM32定时器时间基准详解:从时钟树到PSC/ARR配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉