首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 进阶!实现从任何图像中提取文字,轻松提取图片中的文本!

Python 进阶!实现从任何图像中提取文字,轻松提取图片中的文本!

原创
作者头像
小白的大数据之旅
发布2025-11-28 10:34:19
发布2025-11-28 10:34:19
3870
举报

Python 进阶!实现从任何图像中提取文字,轻松提取图片中的文本!

平时工作里是不是经常遇到这种麻烦:别人发的扫描件 PDF、截图里的文字,想复制却只能手动敲?要是文字多,敲到手酸还容易错。今天就教你用 Python 搞定这个问题 —— 不管是普通图片、多语言文字(英语、俄语都能搞),还是 PDF 扫描件,都能自动提取文字,代码直接就能跑,新手也能学会!

一、先搞懂核心工具:我们要用哪些 “帮手”?

在动手前,先明白我们依赖的几个关键工具,缺一不可:

工具 / 库

作用说明

Tesseract OCR

核心的 “文字识别引擎”,开源免费,支持多语言,是整个功能的基础

pytesseract

Python 库,用来 “调用” Tesseract 引擎(相当于 Python 和 Tesseract 之间的桥梁)

Pillow(PIL)

Python 图片处理库,用来打开图片、做预处理(比如转黑白图提高识别率)

pdf2image

Python 库,把 PDF 扫描件转成一张张图片(因为 PDF 扫描件本质是图片打包)

Poppler

辅助工具,pdf2image 依赖它才能转 PDF 为图片,必须装

简单说:Tesseract 负责 “认文字”,pytesseract 负责 “让 Python 指挥 Tesseract”,Pillow 负责 “处理图片”,pdf2image+Poppler 负责 “拆 PDF 扫描件”。

二、环境准备:一步步装工具(Mac/Windows 都讲清)

这一步最关键!少装一个或配置错,后面代码就跑不起来。按系统一步步来,别跳步。

2.1 先装核心引擎:Tesseract OCR

情况 1:Mac 系统

Mac 用户需要先装「Homebrew」(如果没装过),打开终端,复制下面的命令回车:

代码语言:python
复制
# 装Homebrew(如果没装)

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

装完 Homebrew,再装 Tesseract 和多语言包:

代码语言:python
复制
# 装Tesseract核心

brew install tesseract

# 装所有语言包(包括英语、俄语、中文等,一步到位)

brew install tesseract-lang

装完后,终端输tesseract -v,能看到版本号就说明成了。

情况 2:Windows 系统
  1. 下载 Tesseract 安装包:打开这个链接,往下滑找到 “Latest release”,下载带 “64-bit” 的安装包(比如tesseract-ocr-w64-setup-5.3.3.20231005.exe)。
  2. 双击安装:关键步骤—— 安装时一定要勾选 “Add Tesseract to PATH”(让电脑全局能找到 Tesseract),如果没勾,后面要手动配环境变量。
  3. 验证:打开 CMD(命令提示符),输tesseract -v,能看到版本号就成。

如果没勾 Add to PATH,手动配环境变量:

  • 右键 “此电脑”→“属性”→“高级系统设置”→“环境变量”→在 “系统变量” 里找 “Path”→“编辑”→“新建”,把 Tesseract 的安装目录(比如C:Program FilesTesseract-OCR)粘贴进去→一路点 “确定”。
  • 配完要重启 CMD/IDE,不然不生效!

2.2 装 Python 库和 Poppler(处理图片 / PDF)

第一步:装 Python 库

打开终端 / CMD,输下面的命令,装 3 个库:

代码语言:python
复制
pip install pytesseract pillow pdf2image
第二步:装 Poppler(PDF 转图片用)

pdf2image 库需要 Poppler 才能工作,继续按系统装:

系统

安装方法

Mac

终端输brew install poppler,直接搞定

Windows

  1. 下载压缩包:打开这个链接,下载最新的 “poppler-xx.xx.xx_x86_64.tar.xz”2. 解压:把压缩包解压到一个路径(比如C:poppler),记住解压后里面的 “bin” 文件夹路径(比如C:popplerpoppler-24.02.0bin)3. 配环境变量:和 Tesseract 一样,把 “bin” 路径加入系统变量的 “Path”,然后重启 CMD/IDE

2.3 验证环境是否 OK

打开 Python 终端(或 IDE 里新建个.py 文件),跑下面的代码:

代码语言:python
复制
from PIL import Image

import pytesseract

# 随便找张有英文的图片,替换成你的图片路径

img_path = "test_en.png"

# 打开图片并识别(默认英语)

text = pytesseract.image_to_string(Image.open(img_path), lang="eng")

print(text)

如果能打印出图片里的英文,说明环境没问题!如果报错,回头查前面的步骤(尤其是环境变量)。

三、入门:单张图片识别(英语 + 多语言)

先从简单的单张图片入手,学会基础用法,再进阶批量处理。

3.1 识别英语图片(默认支持)

代码超简单,注释写得很清楚:

代码语言:python
复制
# 导入需要的库

from PIL import Image  # 处理图片

import pytesseract     # 调用Tesseract

# 1. 定义图片路径(替换成你自己的图片路径,支持png、jpg、jpeg)

image_path = "english_image.jpg"

# 2. 打开图片

img = Image.open(image_path)

# 3. 调用Tesseract识别文字(lang="eng"表示英语,默认也是eng,可省略)

# 这里加了encoding='utf-8',避免中文乱码(虽然这里是英语,但养成习惯)

text = pytesseract.image_to_string(img, lang="eng", encoding='utf-8')

# 4. 打印结果

print("识别到的文字:")

print("-" * 50)  # 分隔线,看起来清楚

print(text)

运行步骤

  1. 找一张有英语的图片(比如截图、扫描件),改名为english_image.jpg,和代码放同一文件夹;
  2. 运行代码,就能看到图片里的英文被提取出来了。

3.2 识别多语言(比如英语 + 俄语)

要识别其他语言,得先确认 “语言代码”,再装对应语言包(Mac 之前装了tesseract-lang,Windows 要手动下)。

第一步:常用语言代码表

记不住没关系,收藏这个表:

语言

Tesseract 语言代码

说明

英语

eng

默认自带,不用额外装

简体中文

chi_sim

需要装语言包

俄语

rus

需要装语言包

日语

jpn

需要装语言包

法语

fra

需要装语言包

德语

deu

需要装语言包

第二步:Windows 手动装语言包(Mac 跳过)
  1. 打开Tesseract 语言包仓库
  2. 搜索语言代码对应的文件,比如俄语搜 “rus”,找到rus.traineddata
  3. 点 “Download” 下载,把文件放到 Tesseract 的tessdata目录(比如C:Program FilesTesseract-OCRtessdata)。
第三步:多语言识别代码

比如识别一张既有英语又有俄语的图片:

代码语言:python
复制
from PIL import Image

import pytesseract

image_path = "eng_rus_image.png"  # 你的双语图片路径

img = Image.open(image_path)

# 关键:lang参数用+连接多个语言代码

text = pytesseract.image_to_string(img, lang="eng+rus", encoding='utf-8')

print("双语识别结果:")

print("-" * 50)

print(text)

运行后,就能同时提取出英语和俄语文字了。

四、进阶:封装 ImageReader 类(批量 + 复用)

写代码不能每次都复制粘贴,我们把识别逻辑封装成一个类,以后用的时候直接调用,支持单张、批量、PDF 处理,还能配置语言和保存结果。

这个类的代码直接能跑,注释写得很详细,你只需要改路径就行:

代码语言:python
复制
import os  # 处理文件/文件夹路径

from PIL import Image  # 处理图片

import pytesseract     # 调用Tesseract

from pdf2image import convert_from_path  # PDF转图片

class ImageReader:

   def __init__(self, lang='eng', output_dir=None):

       """

       初始化ImageReader(创建实例时调用)

       :param lang: 识别语言,默认英语(eng),多语言用+连接(如'eng+rus')

       :param output_dir: 结果保存目录,None则不保存,默认None

       """

       self.lang = lang  # 保存语言参数

       self.output_dir = output_dir  # 保存结果目录

      

       # 如果指定了保存目录,不存在就自动创建

       if self.output_dir and not os.path.exists(self.output_dir):

           os.makedirs(self.output_dir)

           print(f"创建结果保存目录:{self.output_dir}")

   def _preprocess_image(self, image):

       """

       【私有方法】图片预处理:灰度化+二值化,提高识别率(不用手动调用)

       原理:彩色图干扰多,转黑白图后文字更突出

       :param image: PIL.Image对象

       :return: 预处理后的PIL.Image对象

       """

       # 1. 转灰度图(L模式:每个像素0-255,0是黑,255是白)

       gray_img = image.convert('L')

      

       # 2. 二值化:把灰度图变成纯黑白(阈值127,可根据图片调整)

       # 像素值>127设为255(白),否则0(黑),文字更清晰

       threshold = 127

       binary_img = gray_img.point(lambda x: 255 if x > threshold else 0)

      

       return binary_img

   def read_single_image(self, image_path, preprocess=True, save_result=False):

       """

       识别单张图片

       :param image_path: 图片路径(支持png、jpg、jpeg等)

       :param preprocess: 是否预处理图片,默认True(推荐开)

       :param save_result: 是否保存结果到文件,默认False

       :return: 识别到的文字字符串

       """

       # 检查图片是否存在

       if not os.path.exists(image_path):

           raise FileNotFoundError(f"图片找不到:{image_path}")

      

       # 打开图片(捕获异常,避免图片损坏报错)

       try:

           img = Image.open(image_path)

       except Exception as e:

           raise ValueError(f"打开图片失败:{e}")

      

       # 图片预处理(如果开启)

       if preprocess:

           img = self._preprocess_image(img)

      

       # 调用Tesseract识别文字(捕获常见错误)

       try:

           text = pytesseract.image_to_string(img, lang=self.lang, encoding='utf-8')

       except pytesseract.TesseractNotFoundError:

           raise Exception("没找到Tesseract!先装Tesseract并配环境变量")

       except Exception as e:

           raise Exception(f"识别失败:{e}")

      

       # 保存结果(如果开启且指定了目录)

       if save_result and self.output_dir:

           # 取图片文件名(不含后缀),比如"test.png"→"test"

           file_name = os.path.splitext(os.path.basename(image_path))[0]

           # 结果文件路径:保存目录/文件名_result.txt

           result_path = os.path.join(self.output_dir, f"{file_name}_result.txt")

           # 用utf-8编码保存,避免乱码

           with open(result_path, 'w', encoding='utf-8') as f:

               f.write(text)

           print(f"结果已保存到:{result_path}")

      

       return text

   def read_batch_images(self, folder_path, preprocess=True, save_result=True):

       """

       批量识别文件夹下所有图片

       :param folder_path: 图片文件夹路径

       :param preprocess: 是否预处理,默认True

       :param save_result: 是否保存结果,默认True

       :return: 字典,key=图片路径,value=识别结果

       """

       # 检查文件夹是否存在

       if not os.path.isdir(folder_path):

           raise NotADirectoryError(f"文件夹找不到:{folder_path}")

      

       # 支持的图片格式(小写,避免漏判)

       supported_formats = ('.png', '.jpg', '.jpeg', '.bmp', '.tiff')

       # 存储所有结果

       batch_result = {}

      

       # 遍历文件夹里的所有文件

       for file_name in os.listdir(folder_path):

           # 只处理支持的图片格式

           if file_name.lower().endswith(supported_formats):

               file_path = os.path.join(folder_path, file_name)

               print(f"正在处理:{file_path}")

              

               # 调用单张图片识别方法

               try:

                   text = self.read_single_image(

                       file_path, preprocess=preprocess, save_result=save_result

                   )

                   batch_result[file_path] = text

                   print(f"处理完成:{file_name}")

               except Exception as e:

                   batch_result[file_path] = f"处理失败:{e}"

                   print(f"处理失败:{file_name} → {e}")

      

       return batch_result

   def read_pdf_scan(self, pdf_path, dpi=300, preprocess=True, save_result=True):

       """

       识别PDF扫描件(本质是图片组成的PDF)

       :param pdf_path: PDF文件路径

       :param dpi: 转图片的分辨率,dpi越高越清晰,默认300(推荐)

       :param preprocess: 是否预处理,默认True

       :param save_result: 是否保存结果,默认True

       :return: 字典,key=页码(从1开始),value=该页识别结果

       """

       # 检查PDF是否存在

       if not os.path.exists(pdf_path):

           raise FileNotFoundError(f"PDF找不到:{pdf_path}")

      

       # 把PDF转成图片(每页一张),依赖Poppler

       try:

           # dpi=300:分辨率,比默认150更清晰,识别率更高

           pages = convert_from_path(pdf_path, dpi=dpi)

           print(f"PDF共{len(pages)}页,已转成图片")

       except Exception as e:

           raise Exception(f"PDF转图片失败:{e}(可能没装Poppler或没配环境变量)")

      

       # 存储每页结果

       pdf_result = {}

      

       # 遍历每页图片(page_num从1开始)

       for page_num, page_img in enumerate(pages, start=1):

           print(f"正在处理PDF第{page_num}页")

          

           # 图片预处理

           if preprocess:

               page_img = self._preprocess_image(page_img)

          

           # 识别文字

           try:

               text = pytesseract.image_to_string(page_img, lang=self.lang, encoding='utf-8')

               pdf_result[page_num] = text

               print(f"PDF第{page_num}页处理完成")

           except Exception as e:

               pdf_result[page_num] = f"处理失败:{e}"

               print(f"PDF第{page_num}页处理失败:{e}")

      

       # 保存PDF识别结果(合并所有页)

       if save_result and self.output_dir:

           file_name = os.path.splitext(os.path.basename(pdf_path))[0]

           result_path = os.path.join(self.output_dir, f"{file_name}_pdf_result.txt")

           with open(result_path, 'w', encoding='utf-8') as f:

               for page_num, text in pdf_result.items():

                   f.write(f"=== PDF第{page_num}页 ===n")

                   f.write(text)

                   f.write("nn")  # 每页之间空两行,方便阅读

           print(f"PDF结果已保存到:{result_path}")

      

       return pdf_result

4.2 如何使用这个类?(示例代码)

把上面的类代码保存为ocr_tool.py,然后新建一个main.py,写调用代码:

代码语言:python
复制
# main.py

from ocr_tool import ImageReader  # 导入我们封装的类

if __name__ == "__main__":

   # 1. 初始化ImageReader:识别英语+俄语,结果保存到"ocr_results"文件夹

   # 如果你要识别中文,把lang改成"chi_sim",记得装中文语言包

   reader = ImageReader(lang="eng+rus", output_dir="ocr_results")

   # ------------------- 示例1:识别单张图片 -------------------

   print("=== 示例1:单张图片识别 ===")

   single_img_path = "test_eng_rus.png"  # 你的图片路径

   try:

       # 识别并保存结果

       single_text = reader.read_single_image(single_img_path, save_result=True)

       print("识别结果:")

       print("-" * 50)

       print(single_text)

   except Exception as e:

       print(f"单张图片处理出错:{e}")

   # ------------------- 示例2:批量识别图片 -------------------

   print("n=== 示例2:批量识别图片 ===")

   batch_folder = "test_images"  # 你的图片文件夹路径(里面全是图片)

   try:

       batch_result = reader.read_batch_images(batch_folder)

       # 打印汇总结果(只打印前100个字符,避免输出太长)

       print("n批量处理汇总:")

       for img_path, text in batch_result.items():

           print(f"图片:{os.path.basename(img_path)}")

           print(f"结果:{text[:100]}..." if len(text) > 100 else f"结果:{text}")

           print("-" * 30)

   except Exception as e:

       print(f"批量处理出错:{e}")

   # ------------------- 示例3:识别PDF扫描件 -------------------

   print("n=== 示例3:PDF扫描件识别 ===")

   pdf_path = "test_scan.pdf"  # 你的PDF扫描件路径

   try:

       pdf_result = reader.read_pdf_scan(pdf_path)

       # 打印汇总结果

       print("nPDF处理汇总:")

       for page_num, text in pdf_result.items():

           print(f"第{page_num}页:{text[:100]}..." if len(text) > 100 else f"第{page_num}页:{text}")

           print("-" * 30)

   except Exception as e:

       print(f"PDF处理出错:{e}")

运行步骤

  1. 准备好测试文件:一张双语图片(test_eng_rus.png)、一个图片文件夹(test_images)、一个 PDF 扫描件(test_scan.pdf);
  2. 运行main.py,就能看到结果,同时在ocr_results文件夹里找到保存的文本文件。

五、优化:提高识别准确率的小技巧

有时候识别结果会有乱码或错字,主要是图片质量问题,试试这些优化方法:

5.1 优化图片预处理

我们的类里已经有 “灰度化 + 二值化”,但可以根据图片调整参数:

  • 调整二值化阈值:如果图片偏暗,把_preprocess_image里的threshold改小(比如 100);如果偏亮,改大(比如 150)。
  • 降噪:如果图片有杂点,加一步降噪,比如用 Pillow 的filter
代码语言:python
复制
from PIL import ImageFilter  # 导入滤镜模块

def _preprocess_image(self, image):

   gray_img = image.convert('L')

   # 加一步高斯模糊降噪(可选,根据图片情况用)

   blurred_img = gray_img.filter(ImageFilter.GaussianBlur(radius=0.5))

   # 再二值化

   threshold = 127

   binary_img = blurred_img.point(lambda x: 255 if x > threshold else 0)

   return binary_img

5.2 提高图片分辨率

  • 普通图片:用图片编辑工具放大(比如 Photoshop、在线工具),保持清晰度。
  • PDF 扫描件:转图片时把dpi设高,比如dpi=600(但会变慢,300 足够日常用)。

5.3 选择更精准的语言包

比如识别中文,用chi_sim(简体)而不是chi_tra(繁体);识别俄语用rus,别用其他相近语言的代码。

六、常见问题与解决方法(避坑指南)

这部分是重点!新手最容易踩这些坑,收藏好:

常见错误 / 问题

可能原因

解决方法

TesseractNotFoundError

  1. 没装 Tesseract;2. 装了但没配环境变量
  1. 按前面步骤装 Tesseract;2. 配环境变量后重启 IDE;3. 手动指定路径:pytesseract.pytesseract.tesseract_cmd = r'C:Program FilesTesseract-OCRtesseract.exe'(Windows)

PopplerNotInstalledError

没装 Poppler 或没配环境变量

  1. 按步骤装 Poppler;2. 配环境变量后重启 IDE;3. 转 PDF 时指定 Poppler 路径:pages = convert_from_path(pdf_path, poppler_path=r'C:popplerbin')(Windows)

多语言识别没效果(全是英语)

  1. 没装对应语言包;2. lang 参数写错
  1. Windows:下语言包放 tessdata;Mac:brew install tesseract-lang;2. 查语言代码表,比如俄语是rus不是russian

识别结果是乱码 / 空白

  1. 图片模糊 / 分辨率低;2. 编码问题
  1. 做图片预处理(灰度化 + 二值化);2. 保存结果时用encoding='utf-8';3. 提高图片分辨率

打开图片报错 “cannot identify image file”

图片损坏或格式不支持

  1. 用图片工具打开验证是否完好;2. 转成 png/jpg 格式再试

环境变量配置后还是报错

没重启 IDE 或终端

环境变量修改后,必须重启 PyCharm、VS Code 等 IDE,或者重启 CMD,不然不生效

七、OCR 相关面试题与回答技巧

如果面试时被问到相关问题,这么回答,显得你有实战经验:

面试题 1:你用 Python 做过图像文字提取吗?具体用了哪些工具?

回答:做过。核心用的是开源的 Tesseract OCR 引擎,Python 这边用 pytesseract 库调用 Tesseract,用 Pillow 处理图片(打开、预处理)。如果要处理 PDF 扫描件,会用 pdf2image 把 PDF 转成图片,这个库需要依赖 Poppler 工具。流程是:先装工具并配置环境,然后预处理图片(灰度化、二值化),再调用 Tesseract 识别,最后输出结果。我还封装过一个 ImageReader 类,支持单张、批量、PDF 处理,方便复用。

面试题 2:Tesseract 怎么支持多语言?比如英语和中文同时识别。

回答:首先 Tesseract 默认只有英语包,其他语言需要单独装。Mac 用brew install tesseract-lang就能装所有语言包;Windows 要去 GitHub 的 tessdata 仓库下载对应语言的 traineddata 文件(比如中文是 chi_sim.traineddata),放到 Tesseract 的 tessdata 目录。然后调用时指定 lang 参数,多语言用 + 连接,比如lang='eng+chi_sim',这样就能同时识别英语和中文了。

面试题 3:如何提高 OCR 的识别准确率?

回答:主要从图片预处理和工具配置入手。比如:1. 图片预处理,把彩色图转灰度图、二值化,减少干扰;2. 提高图片分辨率,比如 PDF 转图片时设 dpi=300;3. 选择精准的语言包,避免用错代码;4. 如果图片有杂点,加高斯模糊降噪;5. 确保 Tesseract 和语言包是最新版本,修复旧版本的 bug。这些方法能解决大部分日常场景的准确率问题。

面试题 4:PDF 扫描件和普通 PDF 有什么区别?怎么处理 PDF 扫描件的文字提取?

回答:普通 PDF 是文本型的,能直接复制文字;PDF 扫描件是图像型的,本质是把图片打包成 PDF,不能直接读文字。处理流程是:先用 pdf2image 库把 PDF 的每一页转成图片,这个库需要 Poppler 支持;转图片时设合适的 dpi(比如 300)提高清晰度;然后对每张图片做预处理(灰度化、二值化);再用 pytesseract 识别文字;最后把所有页的结果合并,按页码保存。

八、总结与扩展

到这里,你已经掌握了 Python 提取图像文字的核心技能:从环境配置到单张 / 批量 / PDF 处理,还能解决常见问题。这个方案的优点是开源免费、支持多语言、代码可复用,适合日常办公、数据分析等场景。

如果需要更高级的功能,可以试试这些扩展方向:

  1. 结合 OpenCV:做更复杂的预处理,比如图片倾斜矫正、去除水印;
  2. 调用商业 OCR API:如果 Tesseract 满足不了(比如识别手写体),可以用百度 AI、阿里云的 OCR API,准确率更高;
  3. 做 GUI 工具:用 PyQt 或 Tkinter 做个界面,让不懂代码的人也能拖放图片识别;
  4. 批量处理文件夹下的所有 PDF:在 ImageReader 类里加个read_batch_pdfs方法,遍历文件夹里的 PDF 文件。

快去试试吧!把代码跑起来,处理你手边的扫描件或截图,省下手动敲字的时间~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Python 进阶!实现从任何图像中提取文字,轻松提取图片中的文本!
    • 一、先搞懂核心工具:我们要用哪些 “帮手”?
    • 二、环境准备:一步步装工具(Mac/Windows 都讲清)
      • 2.1 先装核心引擎:Tesseract OCR
      • 2.2 装 Python 库和 Poppler(处理图片 / PDF)
      • 2.3 验证环境是否 OK
    • 三、入门:单张图片识别(英语 + 多语言)
      • 3.1 识别英语图片(默认支持)
      • 3.2 识别多语言(比如英语 + 俄语)
    • 四、进阶:封装 ImageReader 类(批量 + 复用)
      • 4.2 如何使用这个类?(示例代码)
    • 五、优化:提高识别准确率的小技巧
      • 5.1 优化图片预处理
      • 5.2 提高图片分辨率
      • 5.3 选择更精准的语言包
    • 六、常见问题与解决方法(避坑指南)
    • 七、OCR 相关面试题与回答技巧
      • 面试题 1:你用 Python 做过图像文字提取吗?具体用了哪些工具?
      • 面试题 2:Tesseract 怎么支持多语言?比如英语和中文同时识别。
      • 面试题 3:如何提高 OCR 的识别准确率?
      • 面试题 4:PDF 扫描件和普通 PDF 有什么区别?怎么处理 PDF 扫描件的文字提取?
    • 八、总结与扩展
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档