图像 OCR

作者:技能派办公效率v1

使用 Tesseract OCR 从图片中提取文字内容,支持扫描件、截图、收据、表单等多种场景。当用户需要从图片中提取文字、识别截图内容、批量处理图片文件、将视觉文档转为可编辑文本时触发。触发词:OCR、图片识别文字、截图提取文字、图片转文字。

下载量
369
点赞
92
价格
¥1.99
精选

技能文档

---
name: image-ocr
title: 图像 OCR
category: 办公效率
description: 使用 Tesseract OCR 从图片中提取文字内容,支持扫描件、截图、收据、表单等多种场景。当用户需要从图片中提取文字、识别截图内容、批量处理图片文件、将视觉文档转为可编辑文本时触发。触发词:OCR、图片识别文字、截图提取文字、图片转文字。
---

# 图像 OCR 技能

## 用途

本技能通过 `pytesseract` Python 库实现从图片文件(JPG、PNG 等)中精准提取文字,适用于扫描件、截图、文字照片、收据、表单及其他包含文字的视觉内容。

## 适用场景

- 从扫描件或照片中提取文字
- 读取截图或图片捕获中的文字
- 批量处理包含文字信息的图片文件
- 将视觉文档转换为机器可读文本
- 从图片中的表单、收据或表格提取结构化数据

## 依赖库

需要以下 Python 库:

```python
import pytesseract
from PIL import Image
import json
import os
```

## 输入要求

- **文件格式**:JPG、JPEG、PNG、WEBP
- **图片质量**:印刷文字建议最低 300 DPI;文字清晰可读
- **文件大小**:每张图片不超过 5MB(超出时需 resize)
- **文字语言**:非英文内容需指定语言以提高准确率

## 输出格式

所有提取内容以 JSON 格式返回,符合以下结构:

```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`:质量问题或潜在错误的提示数组

## 技能工作流

### 步骤1:基础 OCR 文字提取

```python
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()
```

### 步骤2:带置信度的 OCR 提取

```python
import pytesseract
from PIL import Image

def extract_with_confidence(image_path):
    """提取文字并获取逐词置信度分数。"""
    img = Image.open(image_path)

    # 获取包含置信度的详细数据
    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)
    }
```

### 步骤3:完整 JSON 输出

```python
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, ensure_ascii=False))
```

### 步骤4:批量处理多张图片

```python
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, ensure_ascii=False)

    return results
```

## Tesseract 配置选项

### 语言选择

```python
# 指定语言(默认英文)
text = pytesseract.image_to_string(img, lang='eng')

# 多语言
text = pytesseract.image_to_string(img, lang='eng+fra+deu')
```

### 页面分割模式(PSM)

使用 `--psm` 控制 Tesseract 如何分割图片:

```python
# 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` | 原始行 |

## 图片预处理

为提高 OCR 准确率,可对图片进行预处理:

```python
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)
```

### 高级预处理策略

针对困难图片(低对比度、褪色文字、暗背景),可尝试多种预处理方式:

1. **灰度 + 自动对比度** — 适用于大多数图片的基础增强
2. **反色** — 暗背景浅色文字时使用 `ImageOps.invert()`
3. **缩放** — 小图片放大(如 2 倍)后再 OCR 以提高字符识别率
4. **二值化** — 使用 `img.point(lambda p: 255 if p > threshold else 0)` 转为黑白图,可尝试不同阈值(如 100、128)
5. **锐化** — 应用 `ImageFilter.SHARPEN` 增强边缘清晰度

## 多次扫描策略

对于挑战性图片,单次 OCR 可能遗漏文字。可使用多种配置多次扫描:

1. **尝试多种 PSM 模式** — 不同版面分割模式适用于不同布局
2. **尝试多种预处理变体** — 对同一图片的不同预处理版本分别运行 OCR
3. **合并结果** — 汇总所有扫描结果以最大化提取覆盖率

```python
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

```python
# 验证 Tesseract 是否已安装
try:
    pytesseract.get_tesseract_version()
except pytesseract.TesseractNotFoundError:
    print("Tesseract 未安装或不在 PATH 中")
```

**问题**:OCR 质量差

- 预处理图片(灰度、对比度、锐化)
- 根据文档类型选择合适的 PSM 模式
- 确保图片分辨率足够(300+ DPI)

**问题**:输出为空或乱码

- 检查图片是否包含实际文字
- 尝试不同 PSM 模式
- 验证图片是否损坏

## 质量自检

返回结果前验证:

- [ ] 输出为有效 JSON(使用 `json.loads()` 验证)
- [ ] 所有必填字段存在(`success`、`filename`、`extracted_text`、`confidence`、`metadata`)
- [ ] 文字保持逻辑阅读顺序
- [ ] 置信度等级反映实际 OCR 质量
- [ ] warnings 数组包含所有检测到的问题
- [ ] JSON 中特殊字符正确转义

## 局限性

- Tesseract 对印刷文字效果最佳;手写识别能力有限
- 装饰字体、艺术文字或极端风格化文字的准确率会降低
- 数学公式和特殊符号可能无法准确提取
- 无法恢复被涂黑或加水印的文字
- 严重图片退化(模糊、噪点、低分辨率)会降低准确率
- 复杂多栏版面可能需要自定义 PSM 配置

使用说明

# 图像 OCR

使用 Tesseract OCR 从图片中精准提取文字,支持扫描件、截图、收据、表单等多种场景。

## 使用

```text
帮我把这张图片里的文字提取出来
```

```text
批量处理 /photos 目录下所有图片,提取文字并保存为 JSON
```

## 工作原理

1. 接收图片文件(JPG/PNG/WEBP),通过 pytesseract 调用 Tesseract 引擎进行 OCR
2. 支持图片预处理(灰度、增强对比度、锐化)提升识别准确率
3. 对困难图片自动采用多次扫描策略,合并结果最大化覆盖率
4. 以 JSON 格式输出提取文字、置信度、语言检测等元数据

## 依赖

- Python 3
- pytesseract、Pillow
- Tesseract OCR 引擎(需单独安装)

如何安装此技能?

访问技能市场,点击「安装」按钮,按提示将技能包放入 AI 编程助手的 skills 目录即可。

浏览技能市场

支持平台:Qoder · QoderWork · Claude · Codex 等 AI 编程助手