简介:这是一款基于Python与easyOCR库开发的离线图片文字提取工具包,专为64位Windows环境设计,免去复杂环境配置,面向需要从截图、扫描件或照片中批量识别文字的开发者与办公人员。压缩包共包含4862个文件,以py/pyc源码和字节码、pyd/dll扩展模块与运行库为主,另含头文件、字体、图标等辅助资源,整体约808.61MB,构成开箱即用的离线OCR运行环境。解压后可通过easyOCR的Reader对象调用readtext方法,快速提取中英日韩等多语言文本;使用时可调整检测框精度、最小字体等参数,并配合多线程、多进程提升批量处理速度。包内还针对低质量图像提供了异常捕获等容错示例,目录层次清楚,方便直接嵌入自动化流程或二次开发,适合作为Python桌面工具或服务端OCR模块的基础。相比在线OCR,该方案无需联网、无需预训练模型,数据隐私更好。目前已有1307人学习下载,适合需要本地快速部署OCR能力的数据处理、自动化办公及Python开发者参考。
1. 图片文字提取工具:拿到一张图,怎么把文字抠出来
"图片文字提取工具.zip"解决的是那种"图里全是字,但要字得靠手敲"的窝火场景:课程截图要整理成笔记,发票扫描件要录入报销单,聊天记录要提取成文本文档。在线 OCR 不是不能用,但总有上传隐私和图片数量限制,离线跑才是稳妥的路。这个 zip 基于 easyOCR 封装,解压后不需要写复杂的训练代码,按 README 装好依赖,调用一个脚本就能把图片里的中文、英文、数字一起抠出来,同时拿到文字坐标和置信度。适合处理票据、截图、扫描件的开发者,也适合想快速上手深度学习文字识别的新手。
2. 为什么用 easyOCR 做文字提取:选型理由与运行原理
这一章不打算堆深度学习公式,而是把 easyOCR 的选型理由、运行原理、依赖环境三个问题讲清楚。搞懂这三件事,后面不管是用这个 zip 还是自己重新封装,都能少走弯路。
2.1 从 Tesseract 到 easyOCR:选型对比
OCR 选型不是"哪个库名气大就装哪个",而是要看你手里的图长什么样。很多初学者最早接触的是 Tesseract,它安装简单、文档全,对干净规整的印刷体确实能打;可一旦遇到背景复杂的截图、倾斜的发票、低对比度的扫描件,漏检和乱码就成了常态。我在一个模拟项目X里试过用 Tesseract 处理几十张票据,结果有相当一部分需要人工补字,后来换成 easyOCR 一次出文字,才意识到问题多半不在调优,而是工具选型从一开始就偏了。
这个 zip 选 easyOCR,核心原因是它把深度学习的文本检测和识别封装成了和 Tesseract 一样简单的调用,又不需要自己准备训练数据。easyOCR 对中文的支持通过语言代码直接开启,'ch_sim' 是简体中文,'en' 是英文,识别混合中英文截图时不需要额外下载语言包,也不存在语言包路径配置错误的问题。相比之下,PaddleOCR 的中文识别精度确实不错,但依赖安装相对更重,对只想批量提字的人来说不够轻。下面是这个工具包在选型时常见的对比:
| 方案 | 安装复杂度 | 中文支持 | 复杂背景抗性 | 适用场景 |
|---|---|---|---|---|
| Tesseract | 低 | 需另装语言包 | 一般 | 规整扫描件 |
| easyOCR | 低 | 内置语言代码 | 较好 | 截图、票据、混合中英文 |
| PaddleOCR | 中 | 中文表现深 | 好 | 中文文档流水线 |
从表格能看出,easyOCR 的位置很适合这个 zip 的定位:安装简单,语言切换直观,复杂背景抗性比传统 OCR 好。它的边界也很清晰——如果要做中文文档的流水线、要求极致的识别率,PaddleOCR 可能是更好的终点;但如果只是把一批截图、票据、扫描件里的文字提出来,easyOCR 的开箱体验是最省事的。
2.2 CRAFT 检测 + 识别网络:一张图的处理流程
easyOCR 的底层是两阶段深度学习流程,不是单模型一把梭。第一阶段是文本检测,用的是 CRAFT 算法(Character Region Awareness For Text Detection),它逐像素预测图像里哪些位置是字符区域、哪些是字符与字符之间的连接区域,再把字符连通成文本行,输出文本框的四角坐标。由于检测是像素级的,它对倾斜文字、轻微形变、竖排文字都有不小的容忍度,这正是它比传统整行检测方法更稳的根源。
第二阶段是文本识别。检测阶段框出的每个文本框会被裁剪成小图,送入识别网络——一个由卷积特征提取和序列建模组成的结构——把图像特征转成字符序列,最终输出字符串和置信度。easyOCR 把这两步封装在 reader.readtext() 里,平时用不到内部细节,但理解这两阶段对调参很重要。比如字太小,识别阶段看不清,你会想到用 mag_ratio 把图先放大再识别;背景太花,检测阶段误检多,你会想到调 low_text 而不是去动识别模型。
整个流程可以拆成四步:图像预处理(缩放、归一化)、CRAFT 检测、文本区域裁剪、识别网络解码。对使用者来说,前两步决定"能不能找到字",后两步决定"找到的字准不准"。排查问题时先定位是检测漏了还是识别错了,能省下大量来回试参数的时间。我在处理某图像处理Demo时就是这么定位问题的,先画检测框再判断问题归属,效率比盲目调参高很多。
2.3 依赖与运行环境:CPU 能跑,GPU 更快
zip 解压后一般带一个 requirements.txt,常见内容就是 easyocr、torch、torchvision、opencv-python、numpy、Pillow 这几个。最容易翻车的是 torch 和 torchvision 的版本配对,我一般会建议先把 torch 单独装好,再装 easyocr,别让 pip 自动解析把版本搞乱。没有 NVIDIA 显卡的机器直接装 CPU 版 torch,处理几张图完全扛得住,后面会发现瓶颈通常在图片大小而不是框架本身。
import torch print(torch.__version__) print(torch.cuda.is_available())这段代码用来确认两件事:torch 版本能打印,说明基础框架没坏;cuda.is_available() 返回 False 也不用慌,表示当前机器在用 CPU 推理。CPU 模式不是"阉割版",识别质量和 GPU 一致,只是慢一点。
第一次执行 Reader 时,easyOCR 会自动下载检测模型和识别模型到用户主目录下的 .EasyOCR/model 文件夹。模型文件不大,但依赖网络质量,下载中断会直接导致 Reader 初始化卡住,这个坑在第 4 章有专门说明。办公内网机器常见做法是找一台能联网的机器先跑通一次,再把整个 .EasyOCR 目录拷到目标机器,这样运行时就不再触发下载。
这里还要澄清一个误解:gpu 参数只影响计算速度,不影响识别结果。用 CPU 跑出来的低置信度结果,换 GPU 也不会突然变准,最多是跑得快一点方便反复调参。所以小场景直接 CPU,跑顺手了再考虑显卡优化。这种"模型自动加载"的设计对新手是福音,你不用知道 CRAFT 权重长什么样,也不用关心识别网络的具体结构,只要依赖装对、模型能落盘,工具的复杂度就被压缩到两三次函数调用以内。
2.4 哪些场景不适合直接套用 easyOCR
easyOCR 也不是万能钥匙。纯手写体识别它很吃力,检测阶段能把字框出来,识别阶段大概率输出乱码;艺术字、花体字、带强烈透视畸变的招牌,效果也明显不如印刷体。如果你手里的图是这种类型,更合适的工具是专门的手写体识别方案或者 PaddleOCR 的文本识别模型。这个 zip 定位在印刷体、屏幕字体、票据和扫描件,选材时先判断图片属于哪一类,能省掉后期大量返工。
3. 工具包实战:从图片到文字的完整流程
3.1 解压后先看目录结构
拿到 zip 别急着跑,先花一分钟看清包里的东西。常见目录结构是下面这样,这些文件直接对应工具的入口和输出:
| 文件/目录 | 作用 |
|---|---|
| main.py | 主入口脚本,接收图片路径并输出文字 |
| requirements.txt | 依赖清单 |
| imgs/ | 示例图片目录 |
| output/ | 输出结果目录 |
| README.md | 使用说明和参数解释 |
我一般会先打开 README 看三件事:入口脚本怎么调用、输出文件放在哪、有没有示例命令。有的工具包还带一个 config.py,用来集中管理语言参数和开关。先看目录结构的好处是避免一头扎进代码里改了不该改的地方,也能快速判断这个 zip 到底是纯脚本还是带着完整依赖环境的。
3.2 最简调用:reader 与 readtext 的第一次配合
核心用法就两个对象:Reader 负责加载语言模型,readtext 负责对一张图执行检测和识别。下面是最简版本:
import easyocr import torch gpu = torch.cuda.is_available() # 有显卡用显卡,没有就 CPU reader = easyocr.Reader(['ch_sim', 'en'], gpu=gpu, verbose=False) result = reader.readtext('imgs/example.png', detail=0, paragraph=True) print('\n'.join(result))这段代码的逻辑很直白:Reader 的第一个参数是语言列表,'ch_sim' 表示简体中文,'en' 表示英文;gpu 参数按 torch.cuda.is_available() 的结果自动切换,避免在无显卡机器上报错。readtext 的 detail=0 让结果只保留文字字符串;paragraph=True 会把同一段落的文本框合并,更符合人眼阅读顺序。如果图片是横跨两栏的排版,paragraph 有时会把两栏内容连在一起,这种情况就要关掉 paragraph。
还需要明白 readtext 返回的文字顺序是按检测框在图片中的位置排列的,并不保证严格从左到右、从上到下。想要稳定的阅读顺序,要么用 paragraph 合并,要么拿到坐标后自己按 y 轴和 x 轴排序再输出。
如果你需要坐标和置信度,把 detail 改成 1。返回的每一项是三元组:第一个元素是文本框四角坐标,第二个是文字,第三个是置信度。画框、过滤噪声、导出 CSV 都依赖这个结构。
3.3 参数调优:detail、paragraph、mag_ratio 怎么用
readtext 的参数不多,但每个都直接对应两阶段流程。我一般会在丢给工具包跑之前先瞄一眼图:字小不小、背景花不花、有没有倾斜。不同情况调不同参数,常用参数作用如下:
| 参数 | 作用 | 常见取值 |
|---|---|---|
| detail | 0 只输出文字,1 输出坐标+文字+置信度 | 0 或 1 |
| paragraph | True 合并同段文本框 | True/False |
| text_threshold | 识别阈值,结果乱码多时调高 | 0.5~0.7 |
| low_text | 文本区域判定阈值,背景杂乱时调高 | 0.2~0.4 |
| link_threshold | 字符连接阈值 | 0.2~0.4 |
| mag_ratio | 图片放大倍率,小字不清晰时调高 | 1.0~2.0 |
实际使用中我的习惯是:字小或分辨率低,把 mag_ratio 调到 2.0,让识别网络看清细节;背景有底纹水印,调高 low_text 和 text_threshold,宁可少识别几个字,也别把底纹当文字。下面是一个组合调参示例:
items = reader.readtext( 'imgs/small_text.png', detail=1, paragraph=False, text_threshold=0.6, low_text=0.3, link_threshold=0.3, mag_ratio=1.5, )这里 text_threshold 是识别阶段的硬阈值,调高会过滤掉低置信度输出,对艺术字、变形字有效;low_text 是检测阶段的候选阈值,调高能减少误检,但也会把浅色文字漏掉。mag_ratio 是参数里玄学成分最高的一个——小字放 1.5~2.0,大字保持 1.0 反而更快更准。初次跑陌生图片,我建议保持默认值跑一遍,再根据输出的坐标框判断该调哪个阈值,不要一上来就把参数全改一遍。
3.4 中文识别与多语言切换:语言代码与编码坑
easyOCR 的语言靠代码切换,常见的有 'ch_sim'(简体中文)、'ch_tra'(繁体中文)、'en'(英文)、'jp'(日文)。语言一次可以传多个,但每多一个语言,初始加载的权重就多一份,内存占用和首次加载时间都会上升。只处理简体中文加英文数字,Reader(['ch_sim', 'en']) 就够了,不要顺手加 'ch_tra'。
简繁混排的情况确实存在,比如老合同、旧报纸扫描件。这时我会把 ch_sim 和 ch_tra 都传进去,让模型在简体字识别失败时还有繁体字符表兜底:
reader = easyocr.Reader(['ch_sim', 'ch_tra', 'en'], gpu=gpu) result = reader.readtext('mixed.png', detail=0)输出到文本文件时要留意编码。Windows 记事本默认可能用 GBK,直接写中文结果再用 Excel 打开就会乱码,我一般显式用 UTF-8 写文件:
with open('output/result.txt', 'w', encoding='utf-8') as f: f.write('\n'.join(result))注意:保存结果文件时编码务必写 utf-8,否则在 Windows 上用 Excel 打开会看到乱码。
还有一个容易忽略的点:easyOCR 对英文输出可能默认带空格间隔,这是后处理逻辑,不是识别错误。如果结果要用来做关键词匹配,先 strip 再合并连续空格,能少很多不必要的校对工作。
3.5 结果可视化:把识别框画回原图
识别完顺手把框画回原图,是排查问题最快的手段。你不仅能看到文字内容,还能看到检测框的位置是否贴合每个字符。代码如下:
import cv2 img = cv2.imread('imgs/example.png') for box, text, conf in items: pts = box.astype(int).reshape(-1, 2) cv2.polylines(img, [pts], isClosed=True, color=(0, 255, 0), thickness=2) cv2.imwrite('output/annotated.png', img)box 是 easyOCR 返回的四角坐标,用 astype(int) 转成整数后直接画线。画完看一眼就知道检测阶段有没有漏字、有没有把背景底纹当成文本区域。这一步和我后面说的"抽样对照原图"是同一种思路,只不过把结果可视化提前到了每一步。
4. easyOCR 常见问题排查:五个容易翻车的安装与识别雷区
4.1 安装时 torch 版本冲突,import 直接报错
现象:pip install easyocr 后,import easyocr 直接报错,提示找不到 torch 模块,或者冒出 CUDA 相关异常堆栈。
原因:pip 自动解析依赖时把 torch 和 torchvision 装成了不匹配的版本,也可能装成了 GPU 版 torch 但机器没有可用显卡,运行时触发 CUDA 校验失败。报错出现在 import 阶段而不是运行阶段,是这类问题的典型特征。
解决:先把 torch 和 torchvision 卸干净,再按本机条件重装。没有 NVIDIA 显卡就装 CPU 版:
pip uninstall -y torch torchvision pip install torch torchvision装完跑python -c "import torch; print(torch.__version__)",能打印版本号就说明基础环境稳了。不要试图靠几句告警在 CUDA 环境里硬跑,问题只会推迟到识别阶段才爆发。
4.2 模型下载失败,Reader 初始化卡住
现象:第一次执行 Reader(...) 时长时间卡在 Downloading model,或者下载到一半报 urllib.error.URLError,重跑又从 0% 开始。
原因:easyOCR 首次使用要从模型源下载检测模型和识别模型到本地目录,网络不稳定或源连接不畅时会中断,而且下载逻辑的断点续传能力有限。这个坑在隔离环境里尤其常见,经常有人误以为是代码进了死循环。
解决:先确认模型目录路径,再手动把模型文件放进去:
import easyocr, os model_dir = os.path.expanduser('~/.EasyOCR/model') print(model_dir)把下载好的模型文件按当前版本约定的文件名放进这个目录,Reader 会优先读本地文件。手动放文件时要注意文件名和哈希一致,文件名不对它还是会重新下载。常见做法是在一台网络正常的机器上先跑通 Reader,再把整个 .EasyOCR 目录拷到目标机器。
4.3 明明是中文,识别出来全是乱码
现象:图片内容全是中文,输出却是一串字母、拼音或者方框乱码,甚至一个中文字符都没有。
原因:九成情况是 Reader 只写了 ['en'],英文模型里没有中文字符表,中文区域自然识别成英文噪声;还有一成是图片繁体居多,而模型只加载了简体。
解决:把语言列表改成 ['ch_sim'],简繁混合就 ['ch_sim', 'ch_tra']。这是图片文字提取工具里最容易踩也最好解决的坑,多数人只是漏看了 README 里的语言参数说明。改完语言后重新执行 Reader,加载时间会比第一次长,因为多加载了一份中文字符模型。
4.4 CPU 模式跑一张大图要十几秒
现象:一张几 MB 的截图,识别一次要十几秒甚至半分钟,CPU 占用拉满,误以为程序死掉了。
原因:CRAFT 检测是在整张图分辨率下逐像素计算的,图片越大计算量越大。很多人以为是 easyOCR 不行,实际上只是没做缩放预处理,直接拿手机原图喂进去了。
解决:识别前把图片宽边压缩到 1600~2000 像素,速度能快一倍以上:
import cv2 img = cv2.imread('big.png') h, w = img.shape[:2] scale = 1600 / w if w > 1600 else 1.0 img = cv2.resize(img, (int(w * scale), int(h * scale)))压缩会损失小字清晰度,小字多的图不要压得太狠,可以压到 2000px 后用 mag_ratio=1.5 补偿。如果图片本身是 A4 扫描件,先切边再识别,效果通常比盲目放大更好。
4.5 底纹、水印被当成文字识别出来
现象:图片背景有印章、水印、防伪底纹,输出里混进一堆像文字但不是内容的噪声,比如"请勿复印"水印被反复输出。
原因:检测阶段把背景纹理当成了文本候选区域,尤其 low_text 设得偏低时,纹理边缘和字符边缘在像素特征上很接近,CRAFT 很难区分。
解决:先做图像预处理提高对比度或转灰度,再调高检测阈值:
items = reader.readtext('stamp.png', low_text=0.4, text_threshold=0.7)如果背景是红色印章,常见做法是用 OpenCV 把红色通道过滤掉再识别,效果比调阈值更干净。阈值只是后手,预处理才是根治手段。调完还有噪声,就回到 3.5 的可视化步骤看检测框,问题基本一目了然。
5. 进阶技巧:批量提字、按置信度过滤与结果校验
5.1 批量跑一个目录并导出 CSV
import easyocr, torch, pathlib, csv reader = easyocr.Reader(['ch_sim', 'en'], gpu=torch.cuda.is_available()) rows = [] for img_path in pathlib.Path('imgs').glob('*.png'): for box, text, conf in reader.readtext(str(img_path)): rows.append([img_path.name, conf, text]) with open('output/result.csv', 'w', newline='', encoding='utf-8-sig') as f: csv.writer(f).writerows(rows)encoding 用 utf-8-sig 是为了让 Excel 打开 CSV 不乱码,批量跑完直接双击就能看。文件名、置信度、文字三个字段足够对接后续流程。
5.2 用置信度过滤噪声
rows = [r for r in rows if r[1] >= 0.4]0.4 是一个比较稳的起点,低于它的结果大多是底纹噪声或变形严重的艺术字。过滤后结果更干净,适合直接入库或关键词匹配。
5.3 和原图对照校验
批量处理不能只相信输出。我一般会从 imgs/ 里随机抽 10% 的图片,把识别结果和原图挨着看一遍,重点看置信度在 0.4~0.6 之间、容易被漏掉的短文本。如果抽检发现某一类图片系统性出错,就回到预处理环节专门处理,而不是继续调阈值。
我第一次跑批量发票时忘了加置信度过滤,CSV 里混了一堆印章噪声,核对花的时间比手工录入还长。从那以后,我每次批量都会强制走一遍"压缩大图 → 置信度过滤 → 抽样对照原图"的流程。希望帮到你。
本文还有配套的精品资源,点击获取