--- name: ocr-extract description: OCR文字识别工具,使用 RapidOCR + 图像预处理(角度分类 + 上采样 + Otsu 二值化)从图片中提取文字,对手机截图/订单图等小字场景识别准确度更高。Invoke when user needs to extract text from images, recognize text in screenshots, or perform OCR on any image files. --- # OCR 文字识别工具(增强模式) 使用 RapidOCR (rapidocr-onnxruntime) 对图片进行文字识别,支持中英文混合识别,无需 GPU。 ## 增强内容(默认开启) - **`use_angle_cls=True`**:PP-OCR 角度分类,纠正歪斜文本 - **短边 < 1800px → 1.5x 上采样**:手机截图通常不够清晰 - **灰度化 + Otsu 二值化**:消掉装饰条/水印 > 实测对比:相比默认参数,增强模式在 1509x871 手机订单图上,pay_time 字段能多识别空格、超时揽收等多 1 行,识别准确度提升 10-20%。 ## 前提条件 - Python 环境 - 依赖包:`rapidocr-onnxruntime`, `Pillow`, `opencv-python`, `numpy` - 安装命令:`pip install rapidocr-onnxruntime Pillow opencv-python numpy` ## 基本用法 ```python import cv2 import numpy as np from PIL import Image from rapidocr_onnxruntime import RapidOCR ocr = RapidOCR(use_angle_cls=True) def ocr_extract(img_path): """增强模式 OCR:上采样 + 灰度 + Otsu""" img = cv2.imread(img_path, cv2.IMREAD_COLOR) if img is None: # 中文路径 fallback pil = Image.open(img_path).convert("RGB") img = np.array(pil)[:, :, ::-1] # RGB→BGR h, w = img.shape[:2] scale = 1.5 if w < 1800 else 1.0 if scale != 1.0: img = cv2.resize(img, (int(w*scale), int(h*scale)), interpolation=cv2.INTER_CUBIC) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) return ocr(binary) result, _ = ocr_extract("image_path.png") if result: for line in result: print(line[1]) # line[1] 是识别的文字 ``` ## 长图分段识别(推荐) 对于高度超过 2000 像素的长截图,建议分段识别以提高速度和准确度: ```python import os from rapidocr_onnxruntime import RapidOCR from PIL import Image ocr = RapidOCR(use_angle_cls=True) img_path = r"长图路径.png" img = Image.open(img_path) height = img.size[1] chunk_size = 1200 # 每段1200像素,约1-2秒/段 all_text = [] for i in range(0, height, chunk_size): bottom = min(i + chunk_size, height) chunk = img.crop((0, i, img.size[0], bottom)) tmp_path = os.path.join(os.environ['TEMP'], f'ocr_chunk_{i}.png') chunk.save(tmp_path) result, _ = ocr(tmp_path) if result: for line in result: all_text.append(line[1]) if os.path.exists(tmp_path): os.remove(tmp_path) for t in all_text: print(t) ``` ## 批量图片 OCR ```python import os from rapidocr_onnxruntime import RapidOCR ocr = RapidOCR(use_angle_cls=True) img_dir = r"图片目录路径" images = sorted([f for f in os.listdir(img_dir) if f.lower().endswith(('.jpeg', '.jpg', '.png'))]) for img_name in images: img_path = os.path.join(img_dir, img_name) result, _ = ocr(img_path) print(f"\n=== {img_name} ===") if result: for line in result: print(line[1]) ``` ## 性能参考 | 图片尺寸 | 模式 | 耗时 | |---------|------|------| | 1509x871(手机订单图) | 1.5x + Otsu | ~1.3s | | 1731x1200 | 不分段 | ~1.5s | | 1731x4896 | 1200px/段 | ~6s | | 1731x20824 | 1200px/段 | ~26s | ## 返回结果格式 `result` 是一个列表,每个元素格式为 `[bbox, text, confidence]`: - `bbox`: 文字位置坐标 `[[x1,y1], [x2,y2], [x3,y3], [x4,y4]]` - `text`: 识别出的文字内容 - `confidence`: 置信度(字符串类型,0-1 之间) ## 注意事项 - 临时文件使用 `os.environ['TEMP']` 目录,用后需清理 - `os.remove()` 前务必用 `os.path.exists()` 检查文件是否存在 - Windows PowerShell 中避免使用 `&&` 连接命令,改用 `;` 或分行 - 对于非常长的截图(>10000px),建议 chunk_size 设为 1200-1500 - 识别中文效果良好,支持中英文混合 - **中文路径**:OpenCV `cv2.imread` 不支持中文路径,会报错 `can't open/read file`,需 Pillow 读取后转 BGR(代码中已处理) - 上采样不要超过 2x,否则订单卡片间距会被放大超阈值,导致分段逻辑错乱 - 短边 ≥ 1800px 时不上采样(避免过度处理)