smart_ocr

Polar Sponsor
爱发电 赞助
.NET 9.0

使用PaddleOCR从图像和扫描文档中提取文本,支持100多种语言。

Smart OCR STell.

功能概述

Smart OCR STell.是一项面向实际任务的技能,主要用于Overview. 此技能可以使用 PaddleOCR - 支持100+语言的 OCR 引擎从图像和扫描文档中提取智能文本;extract text from pho。

核心要点

  • 它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。
  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。
  • 该技能适合需要稳定复用相关能力的场景,可作为自动化工作流的一部分,也便于后续检查、调整和扩展。

使用与执行

从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;

结果检查与注意事项

若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。

智能 OCR 技能

概述

本技能基于领先的 OCR 引擎 PaddleOCR,支持 100 多种语言,可实现图像与扫描文档的智能化文本提取。支持从照片、截图、扫描版 PDF 及手写文档中高精度提取文本。

使用方法

  1. 提供图像或扫描文档
  2. (可选)指定待识别的语言
  3. 我将返回带位置信息与置信度的文本结果

示例提示语:

  • “提取这张截图中的全部文本”
  • “对这份扫描版 PDF 文档执行 OCR”
  • “读取这张名片照片中的文字”
  • “从该图像中提取中文和英文文本”

领域知识

PaddleOCR 基础

from paddleocr import PaddleOCR

# 初始化 OCR 引擎
ocr = PaddleOCR(use_angle_cls=True, lang='en')

# 对图像执行 OCR
result = ocr.ocr('image.png', cls=True)

# 结果结构:[[box, (text, confidence)], ...]
for line in result[0]:
    box = line[0]      # [[x1,y1], [x2,y2], [x3,y3], [x4,y4]]
    text = line[1][0]  # 提取的文本
    conf = line[1][1]  # 置信度分数
    print(f"{text} ({conf:.2f})")

支持的语言

# 常用语言代码
languages = {
    'en': 'English',
    'ch': 'Chinese (Simplified)',
    'cht': 'Chinese (Traditional)',
    'japan': 'Japanese',
    'korean': 'Korean',
    'french': 'French',
    'german': 'German',
    'spanish': 'Spanish',
    'russian': 'Russian',
    'arabic': 'Arabic',
    'hindi': 'Hindi',
    'vi': 'Vietnamese',
    'th': 'Thai',
    # ... 支持 100+ 种语言
}

# 指定特定语言
ocr = PaddleOCR(lang='ch')  # 中文
ocr = PaddleOCR(lang='japan')  # 日文
ocr = PaddleOCR(lang='multilingual')  # 自动检测多语言

配置选项

from paddleocr import PaddleOCR

ocr = PaddleOCR(
    # 检测设置
    det_model_dir=None,         # 自定义检测模型路径
    det_limit_side_len=960,     # 检测时图像最大边长
    det_db_thresh=0.3,          # 二值化阈值
    det_db_box_thresh=0.5,      # 检测框得分阈值
    
    # 识别设置
    rec_model_dir=None,         # 自定义识别模型路径
    rec_char_dict_path=None,    # 自定义字符字典路径
    
    # 角度分类
    use_angle_cls=True,         # 启用角度分类
    cls_model_dir=None,         # 自定义分类模型路径
    
    # 语言
    lang='en',                  # 语言代码
    
    # 性能
    use_gpu=True,               # 若可用则启用 GPU
    gpu_mem=500,                # GPU 显存限制(MB)
    enable_mkldnn=True,         # CPU 优化(Intel MKL-DNN)
    
    # 输出
    show_log=False,             # 屏蔽日志输出
)

处理不同来源的输入

图像文件

# 单张图像
result = ocr.ocr('image.png')

# 多张图像
images = ['img1.png', 'img2.png', 'img3.png']
for img in images:
    result = ocr.ocr(img)
    process_result(result)

PDF 文件(扫描版)

from pdf2image import convert_from_path

def ocr_pdf(pdf_path):
    """OCR 扫描版 PDF 文档。"""
    # 将 PDF 页面转换为图像
    images = convert_from_path(pdf_path)
    
    all_text = []
    for i, img in enumerate(images):
        # 保存临时图像
        temp_path = f'temp_page_{i}.png'
        img.save(temp_path)
        
        # 对图像执行 OCR
        result = ocr.ocr(temp_path)
        
        # 提取文本
        page_text = '\n'.join([line[1][0] for line in result[0]])
        all_text.append(f"--- Page {i+1} ---\n{page_text}")
        
        os.remove(temp_path)
    
    return '\n\n'.join(all_text)

URL 与字节流

import requests
from io import BytesIO

# 从 URL 加载
response = requests.get('https://example.com/image.png')
result = ocr.ocr(BytesIO(response.content))

# 从字节流加载
with open('image.png', 'rb') as f:
    img_bytes = f.read()
result = ocr.ocr(BytesIO(img_bytes))

结果处理

def process_ocr_result(result):
    """将 OCR 结果处理为结构化数据。"""
    
    lines = []
    for line in result[0]:
        box = line[0]
        text = line[1][0]
        confidence = line[1][1]
        
        # 计算包围框坐标
        x_coords = [p[0] for p in box]
        y_coords = [p[1] for p in box]
        
        lines.append({
            'text': text,
            'confidence': confidence,
            'bbox': {
                'left': min(x_coords),
                'top': min(y_coords),
                'right': max(x_coords),
                'bottom': max(y_coords),
            },
            'raw_box': box
        })
    
    return lines

# 按位置排序(从上到下、从左到右)
def sort_by_position(lines):
    return sorted(lines, key=lambda x: (x['bbox']['top'], x['bbox']['left']))

文本版式重建

def reconstruct_layout(result, line_threshold=10):
    """根据 OCR 结果重建文本版式。"""
    
    lines = process_ocr_result(result)
    lines = sort_by_position(lines)
    
    # 按逻辑行分组
    text_lines = []
    current_line = []
    current_y = None
    
    for line in lines:
        y = line['bbox']['top']
        
        if current_y is None or abs(y - current_y) < line_threshold:
            current_line.append(line)
            current_y = y
        else:
            # 新起一行
            text_lines.append(' '.join([l['text'] for l in current_line]))
            current_line = [line]
            current_y = y
    
    # 添加最后一行
    if current_line:
        text_lines.append(' '.join([l['text'] for l in current_line]))
    
    return '\n'.join(text_lines)

最佳实践

  1. 图像预处理:OCR 前提升图像质量
  2. 选择正确语言:明确指定语言以提高识别准确率
  3. 处理多栏布局:对各栏分别进行 OCR
  4. 过滤低置信度结果:跳过低于阈值的识别项
  5. 批量处理:高效处理多张图像

常见模式

图像预处理

from PIL import Image, ImageEnhance, ImageFilter

def preprocess_image(image_path):
    """对图像进行预处理以提升 OCR 效果。"""
    img = Image.open(image_path)
    
    # 转为灰度图
    img = img.convert('L')
    
    # 增强对比度
    enhancer = ImageEnhance.Contrast(img)
    img = enhancer.enhance(2.0)
    
    # 锐化
    img = img.filter(ImageFilter.SHARPEN)
    
    # 保存预处理后的图像
    preprocessed_path = 'preprocessed.png'
    img.save(preprocessed_path)
    
    return preprocessed_path

带进度条的批量 OCR

from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor

def batch_ocr(image_paths, max_workers=4):
    """并行处理多张图像的 OCR。"""
    
    results = {}
    
    def process_single(img_path):
        result = ocr.ocr(img_path)
        return img_path, result
    
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = [executor.submit(process_single, p) for p in image_paths]
        
        for future in tqdm(futures, desc="Processing OCR"):
            path, result = future.result()
            results[path] = result
    
    return results

示例

示例 1:名片识别器

from paddleocr import PaddleOCR
import re

def read_business_card(image_path):
    """从名片中提取联系人信息。"""
    
    ocr = PaddleOCR(use_angle_cls=True, lang='en')
    result = ocr.ocr(image_path)
    
    # 提取所有文本
    all_text = []
    for line in result[0]:
        all_text.append(line[1][0])
    
    full_text = '\n'.join(all_text)
    
    # 解析联系人信息
    contact = {
        'name': None,
        'email': None,
        'phone': None,
        'company': None,
        'title': None,
        'raw_text': full_text
    }
    
    # 邮箱匹配
    email_match = re.search(r'[\w.-]+@[\w.-]+\.\w+', full_text)
    if email_match:
        contact['email'] = email_match.group()
    
    # 电话号码匹配
    phone_match = re.search(r'[+\d][\d\s\-()]{8,}', full_text)
    if phone_match:
        contact['phone'] = phone_match.group().strip()
    
    # 姓名通常为字号最大或位于最上方的文本
    if all_text:
        contact['name'] = all_text[0]
    
    return contact

card_info = read_business_card('business_card.jpg')
print(f"Name: {card_info['name']}")
print(f"Email: {card_info['email']}")
print(f"Phone: {card_info['phone']}")

示例 2:收据扫描器

from paddleocr import PaddleOCR
import re

def scan_receipt(image_path):
    """从收据中提取商品明细与总金额。"""
    
    ocr = PaddleOCR(use_angle_cls=True, lang='en')
    result = ocr.ocr(image_path)
    
    lines = []
    for line in result[0]:
        text = line[1][0]
        y_pos = line[0][0][1]
        lines.append({'text': text, 'y': y_pos})
    
    # 按垂直位置排序
    lines.sort(key=lambda x: x['y'])
    
    receipt = {
        'items': [],
        'subtotal': None,
        'tax': None,
        'total': None
    }
    
    for line in lines:
        text = line['text']
        
        # 查找总金额
        if 'total' in text.lower():
            amount = re.search(r'\$?([\d,]+\.?\d*)', text)
            if amount:
                if 'sub' in text.lower():
                    receipt['subtotal'] = float(amount.group(1).replace(',', ''))
                else:
                    receipt['total'] = float(amount.group(1).replace(',', ''))
        
        # 查找税额
        elif 'tax' in text.lower():
            amount = re.search(r'\$?([\d,]+\.?\d*)', text)
            if amount:
                receipt['tax'] = float(amount.group(1).replace(',', ''))
        
        # 查找商品项(含价格的行)
        else:
            item_match = re.search(r'(.+?)\s+\$?([\d,]+\.?\d+)$', text)
            if item_match:
                receipt['items'].append({
                    'name': item_match.group(1).strip(),
                    'price': float(item_match.group(2).replace(',', ''))
                })
    
    return receipt

receipt_data = scan_receipt('receipt.jpg')
print(f"Items: {len(receipt_data['items'])}")
print(f"Total: ${receipt_data['total']}")

示例 3:多语言文档

from paddleocr import PaddleOCR

def ocr_multilingual(image_path, languages=['en', 'ch']):
    """OCR 多语言混合文档。"""
    
    all_results = {}
    
    for lang in languages:
        ocr = PaddleOCR(use_angle_cls=True, lang=lang)
        result = ocr.ocr(image_path)
        
        texts = []
        for line in result[0]:
            texts.append({
                'text': line[1][0],
                'confidence': line[1][1]
            })
        
        all_results[lang] = texts
    
    # 合并结果,保留每段文本的最高置信度
    merged = {}
    for lang, texts in all_results.items():
        for item in texts:
            text = item['text']
            conf = item['confidence']
            
            if text not in merged or merged[text]['confidence'] < conf:
                merged[text] = {'confidence': conf, 'language': lang}
    
    return merged

result = ocr_multilingual('bilingual_document.png')
for text, info in result.items():
    print(f"[{info['language']}] {text} ({info['confidence']:.2f})")

局限性

  • 手写文本识别准确率存在波动
  • 极小字号文本可能无法识别
  • 复杂背景会降低识别准确率
  • 旋转文本需启用角度分类功能
  • 推荐使用 GPU 以获得最佳性能

安装

# CPU 版本
pip install paddlepaddle paddleocr

# GPU 版本(CUDA 11.x)
pip install paddlepaddle-gpu paddleocr

# 额外依赖
pip install pdf2image Pillow

资源

相关专题

更多
Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

2026.10.22

0

11

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

2026.10.22

0

10

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

2026.10.22

0

15

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

2026.10.22

0

10

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

2026.10.22

0

25

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

2026.10.22

0

15

Golangci-lint安装与入门教程
Golangci-lint安装与入门教程

本专题讲解Golangci-lint的安装、初始化、基础命令和首次代码检查,覆盖本地环境、Docker及多平台用法,帮助Go开发者快速上手。

2026.10.22

0

15

PHP2Shell高危漏洞修复教程
PHP2Shell高危漏洞修复教程

PHP2Shell漏洞是什么,哪些PHP版本和运行环境会受到影响,服务器应该如何检测与修复?本专题提供版本自查脚本、Linux与Docker升级命令、PHP-FPM和Apache排查步骤,以及修复验证、临时缓解和应急响应方案。

2026.10.22

0

12

剧云人物设定与关系管理教程
剧云人物设定与关系管理教程

本专题介绍剧云人物设定与关系管理,讲解角色小传、性格职业、人物目标、背景资料和关系网络的创建及维护方法。

2026.10.22

0

16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习