使用 Python 和 Tesseract OCR 从图像中提取文本内容
图像 OCR 技能是一项面向实际任务的技能,主要用于此技能可以使用 CCR 的 Pytersecract Python 库从图像文件( JPG, PNG 等) 中提取准确的文本;它适合扫描文档。
从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;
若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。
该技能通过 pytesseract Python 库调用 Tesseract OCR 引擎,实现对图像文件(JPG、PNG 等)中文字的高精度提取。适用于扫描文档、截图、含文字的照片、收据、表单以及其他包含文本的视觉内容。
需安装以下 Python 库:
import pytesseract from PIL import Image import json import os
所有提取结果必须以符合以下 Schema 的合法 JSON 格式返回:
{
"success": true,
"filename": "example.jpg",
"extracted_text": "从图像中完整提取的原始文本...",
"confidence": "high|medium|low",
"metadata": {
"language_detected": "en",
"text_regions": 3,
"has_tables": false,
"has_handwriting": false
},
"warnings": [
"右下角文字部分被遮挡",
"页眉区域检测到对比度偏低"
]
}
success:布尔值,表示文字提取是否成功完成filename:原始图像文件名extracted_text:按阅读顺序(自上而下、自左向右)组织的完整文本内容confidence:基于图像质量与文字清晰度得出的整体 OCR 置信度等级metadata.language_detected:ISO 639-1 语言代码metadata.text_regions:识别出的独立文本块数量metadata.has_tables:是否检测到表格类数据结构metadata.has_handwriting:是否检测到手写文字warnings:记录的质量问题或潜在错误列表import pytesseract
from PIL import Image
def extract_text_from_image(image_path):
"""使用 Tesseract OCR 从单张图像中提取文字。"""
img = Image.open(image_path)
text = pytesseract.image_to_string(img)
return text.strip()
import pytesseract
from PIL import Image
def extract_with_confidence(image_path):
"""提取文字并返回逐词置信度分数。"""
img = Image.open(image_path)
# 获取包含置信度的详细 OCR 数据
data = pytesseract.image_to_data(img, output_type=pytesseract.Output.DICT)
words = []
confidences = []
for i, word in enumerate(data['text']):
if word.strip(): # 跳过空字符串
words.append(word)
confidences.append(data['conf'][i])
# 计算平均置信度
avg_confidence = sum(c for c in confidences if c > 0) / len([c for c in confidences if c > 0]) if confidences else 0
return {
'text': ' '.join(words),
'average_confidence': avg_confidence,
'word_count': len(words)
}
import pytesseract
from PIL import Image
import json
import os
def ocr_to_json(image_path):
"""执行 OCR 并以 JSON 格式返回结果。"""
filename = os.path.basename(image_path)
warnings = []
try:
img = Image.open(image_path)
# 获取详细 OCR 数据
data = pytesseract.image_to_data(img, output_type=pytesseract.Output.DICT)
# 提取文本并保留结构
text = pytesseract.image_to_string(img)
# 计算置信度
confidences = [c for c in data['conf'] if c > 0]
avg_conf = sum(confidences) / len(confidences) if confidences else 0
# 判定置信度等级
if avg_conf >= 80:
confidence = "high"
elif avg_conf >= 50:
confidence = "medium"
else:
confidence = "low"
warnings.append(f"OCR 置信度偏低:{avg_conf:.1f}%")
# 统计文本区域(块)数量
block_nums = set(data['block_num'])
text_regions = len([b for b in block_nums if b > 0])
result = {
"success": True,
"filename": filename,
"extracted_text": text.strip(),
"confidence": confidence,
"metadata": {
"language_detected": "en",
"text_regions": text_regions,
"has_tables": False,
"has_handwriting": False
},
"warnings": warnings
}
except Exception as e:
result = {
"success": False,
"filename": filename,
"extracted_text": "",
"confidence": "low",
"metadata": {
"language_detected": "unknown",
"text_regions": 0,
"has_tables": False,
"has_handwriting": False
},
"warnings": [f"OCR 执行失败:{str(e)}"]
}
return result
# 使用示例
result = ocr_to_json("document.jpg")
print(json.dumps(result, indent=2))
import pytesseract
from PIL import Image
import json
import os
from pathlib import Path
def process_image_directory(directory_path, output_file):
"""处理目录下所有图像并保存结果。"""
image_extensions = {'.jpg', '.jpeg', '.png', '.webp'}
results = []
for file_path in sorted(Path(directory_path).iterdir()):
if file_path.suffix.lower() in image_extensions:
result = ocr_to_json(str(file_path))
results.append(result)
print(f"已处理:{file_path.name}")
# 保存结果
with open(output_file, 'w') as f:
json.dump(results, f, indent=2)
return results
# 指定语言(默认为英文) text = pytesseract.image_to_string(img, lang='eng') # 多语言支持 text = pytesseract.image_to_string(img, lang='eng+fra+deu')
使用 --psm 参数控制 Tesseract 对图像的分割方式:
# PSM 3:全自动页面分割(默认) text = pytesseract.image_to_string(img, config='--psm 3') # PSM 4:假设为单列变长文本 text = pytesseract.image_to_string(img, config='--psm 4') # PSM 6:假设为统一文本块 text = pytesseract.image_to_string(img, config='--psm 6') # PSM 11:稀疏文本 — 尽可能多地查找文本 text = pytesseract.image_to_string(img, config='--psm 11')
常用 PSM 值说明:
0:仅执行方向与文字类型检测(OSD)3:全自动页面分割(默认)4:单列变长文本6:统一文本块7:单行文本11:稀疏文本13:原始行(Raw line)为提升 OCR 准确率,建议对图像进行预处理:
from PIL import Image, ImageFilter, ImageOps
def preprocess_image(image_path):
"""对图像进行预处理以提升 OCR 效果。"""
img = Image.open(image_path)
# 转为灰度图
img = img.convert('L')
# 提升对比度
img = ImageOps.autocontrast(img)
# 应用轻微锐化
img = img.filter(ImageFilter.SHARPEN)
return img
# 使用预处理后的图像执行 OCR
img = preprocess_image("document.jpg")
text = pytesseract.image_to_string(img)
对于低对比度、褪色文字或深色背景等困难图像,可尝试多种预处理方法:
ImageOps.invert()img.point(lambda p: 255 if p > threshold else 0) 进行二值化,尝试不同阈值(如 100、128)ImageFilter.SHARPEN 以增强边缘清晰度对于复杂图像,单次 OCR 可能遗漏部分文字。建议采用多轮 OCR,结合不同配置提升覆盖率:
尝试多种 PSM 模式 —— 不同页面分割模式适用于不同版式(例如:--psm 6 适合文本块,--psm 4 适合多列,--psm 11 适合稀疏文本)
尝试多种预处理变体 —— 对同一图像的不同预处理版本分别运行 OCR
合并结果 —— 汇总各轮 OCR 输出,最大化文本覆盖范围
def multi_pass_ocr(image_path):
"""使用多种策略执行 OCR 并合并结果。"""
img = Image.open(image_path)
gray = ImageOps.grayscale(img)
# 生成预处理变体
variants = [
ImageOps.autocontrast(gray),
ImageOps.invert(ImageOps.autocontrast(gray)),
gray.filter(ImageFilter.SHARPEN),
]
# 待尝试的 PSM 模式
psm_modes = ['--psm 6', '--psm 4', '--psm 11']
all_text = []
for variant in variants:
for psm in psm_modes:
try:
text = pytesseract.image_to_string(variant, config=psm)
if text.strip():
all_text.append(text)
except Exception:
pass
# 合并所有提取到的文本
return "\n".join(all_text)
该方法可显著提升收据、褪色文档及质量参差不齐图像的文字提取效果。
问题:未找到 Tesseract
# 验证 Tesseract 是否已安装
try:
pytesseract.get_tesseract_version()
except pytesseract.TesseractNotFoundError:
print("Tesseract 未安装或未加入系统 PATH")
问题:OCR 质量差
问题:输出为空或乱码
返回结果前,请确保完成以下校验:
json.loads() 验证)success、filename、extracted_text、confidence、metadata)warnings 数组已包含所有检测到的问题相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 134.1万人学习
共49课时 | 82.6万人学习
最新文章