Python实现图片与扫描PDF文字识别全攻略

Python实现图片与扫描PDF文字识别全攻略

在数字化转型过程中,企业和开发者经常面临从图片或扫描版PDF中提取文字的需求。传统手动录入方式效率低下且易出错,而基于Python的OCR(光学字符识别)技术可实现自动化处理,显著提升效率。本文将详细介绍如何使用Python库(如Pillow、PyMuPDF、pytesseract)实现图片和扫描PDF的文字识别,并提供可操作的代码示例与优化建议。

一、技术选型与工具准备

1.1 核心库介绍

  • Pillow:Python图像处理库,用于读取和预处理图片(如调整大小、二值化)。
  • PyMuPDF(fitz):轻量级PDF解析库,支持提取扫描PDF中的图像数据。
  • pytesseract:Tesseract OCR的Python封装,支持多语言识别(需安装Tesseract引擎)。
  • OpenCV:可选库,用于复杂图像预处理(如去噪、边缘检测)。

1.2 环境配置

  1. 安装依赖库
    1. pip install pillow pymupdf pytesseract opencv-python
  2. 安装Tesseract OCR引擎
    • Windows:从UB Mannheim下载安装包。
    • macOS:brew install tesseract
    • Linux:sudo apt install tesseract-ocr(或指定语言包如tesseract-ocr-chi-sim)。

二、图片文字识别实现

2.1 基础识别流程

  1. from PIL import Image
  2. import pytesseract
  3. # 读取图片
  4. image = Image.open("example.png")
  5. # 识别文字(默认英文)
  6. text = pytesseract.image_to_string(image)
  7. print(text)
  8. # 指定中文识别(需安装中文语言包)
  9. text_chinese = pytesseract.image_to_string(image, lang="chi_sim")
  10. print(text_chinese)

2.2 图像预处理优化

扫描件或低质量图片需预处理以提高识别率:

  1. import cv2
  2. import numpy as np
  3. def preprocess_image(image_path):
  4. # 读取图片并转为灰度图
  5. img = cv2.imread(image_path)
  6. gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
  7. # 二值化处理
  8. _, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
  9. # 去噪(可选)
  10. denoised = cv2.fastNlMeansDenoising(binary, None, 10, 7, 21)
  11. return denoised
  12. processed_img = preprocess_image("low_quality.png")
  13. text = pytesseract.image_to_string(Image.fromarray(processed_img))
  14. print(text)

2.3 关键参数调优

  • config参数:调整识别模式(如--psm 6假设统一文本块)。
  • lang参数:指定语言包(如eng+chi_sim混合识别)。
  • 示例:
    1. custom_config = r'--oem 3 --psm 6'
    2. text = pytesseract.image_to_string(image, config=custom_config)

三、扫描PDF文字识别实现

3.1 PDF图像提取

扫描PDF本质是图片集合,需先提取图像再识别:

  1. import fitz # PyMuPDF
  2. def extract_images_from_pdf(pdf_path):
  3. doc = fitz.open(pdf_path)
  4. images = []
  5. for page_num in range(len(doc)):
  6. page = doc.load_page(page_num)
  7. images += page.get_images(full=True)
  8. return images
  9. # 提取并保存所有图像(需进一步处理)
  10. pdf_path = "scanned.pdf"
  11. images = extract_images_from_pdf(pdf_path)
  12. for i, img_index in enumerate(images):
  13. xref = img_index[0]
  14. base_image = doc.extract_image(xref)
  15. image_bytes = base_image["image"]
  16. with open(f"page_{i}.png", "wb") as f:
  17. f.write(image_bytes)

3.2 批量识别PDF

结合PyMuPDF与pytesseract实现批量处理:

  1. def pdf_to_text(pdf_path, output_txt):
  2. doc = fitz.open(pdf_path)
  3. full_text = []
  4. for page_num in range(len(doc)):
  5. page = doc.load_page(page_num)
  6. images = page.get_images(full=True)
  7. for img_index, _ in enumerate(images):
  8. xref = images[img_index][0]
  9. base_image = doc.extract_image(xref)
  10. image = Image.open(io.BytesIO(base_image["image"]))
  11. text = pytesseract.image_to_string(image, lang="chi_sim+eng")
  12. full_text.append(text)
  13. with open(output_txt, "w", encoding="utf-8") as f:
  14. f.write("\n".join(full_text))
  15. pdf_to_text("scanned.pdf", "output.txt")

3.3 性能优化技巧

  • 分块处理:对大图按区域分割后识别。
  • 多线程:使用concurrent.futures并行处理多页PDF。
  • 缓存中间结果:避免重复处理相同图像。

四、常见问题与解决方案

4.1 识别率低

  • 原因:图像模糊、字体复杂、语言包缺失。
  • 解决
    • 预处理(二值化、去噪)。
    • 训练自定义Tesseract模型(需标注数据)。
    • 使用商业OCR API(如EasyOCR、PaddleOCR)作为备选。

4.2 处理速度慢

  • 优化
    • 降低图像分辨率(如从300DPI降至150DPI)。
    • 限制识别语言(避免加载多余语言包)。
    • 使用GPU加速(如PaddleOCR支持CUDA)。

4.3 格式混乱

  • 排版修复
    • 使用正则表达式清理多余空格/换行。
    • 结合NLTK进行文本后处理(如分句、纠错)。

五、进阶应用场景

5.1 表格识别

结合camelotpdfplumber提取表格结构:

  1. import pdfplumber
  2. with pdfplumber.open("table.pdf") as pdf:
  3. first_page = pdf.pages[0]
  4. tables = first_page.extract_tables()
  5. for table in tables:
  6. print(table)

5.2 实时摄像头识别

使用OpenCV捕获摄像头画面并实时识别:

  1. import cv2
  2. cap = cv2.VideoCapture(0)
  3. while True:
  4. ret, frame = cap.read()
  5. if not ret:
  6. break
  7. # 预处理
  8. gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
  9. _, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
  10. # 识别
  11. text = pytesseract.image_to_string(binary)
  12. print(text)
  13. if cv2.waitKey(1) & 0xFF == ord("q"):
  14. break
  15. cap.release()

六、总结与建议

Python在OCR领域的应用已非常成熟,通过合理选择库和优化流程,可高效完成图片与扫描PDF的文字识别。开发者需注意:

  1. 预处理优先:80%的识别问题可通过图像预处理解决。
  2. 语言包管理:按需加载语言包以减少资源占用。
  3. 混合方案:复杂场景可结合规则引擎或深度学习模型。

未来,随着Tesseract 5.0+和PaddleOCR等工具的演进,Python在OCR领域的优势将进一步凸显。建议开发者持续关注开源社区更新,并积累标注数据以应对定制化需求。