PaddleOCR-VL-1.6_Demo/batch_ocr.py

93 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
批量 OCR 识别 — 多进程并行加速
原理:每个进程独立加载一份 pipeline 实例,同时处理不同图片。
适用场景:一次处理多张图片(如文件夹批量 OCR
用法:
python batch_ocr.py <图片目录> [--workers 4] [--threads 10]
"""
import time
import os
import sys
import argparse
from multiprocessing import Pool, cpu_count
from pathlib import Path
def ocr_single(image_path: str, threads: int) -> dict:
"""单张图片 OCR在子进程中执行"""
from paddle import core
core.set_num_threads(threads)
from paddleocr import PaddleOCRVL
pipeline = PaddleOCRVL(pipeline_version="v1.6")
t0 = time.perf_counter()
result = pipeline.predict(image_path)
elapsed = time.perf_counter() - t0
blocks = []
for block in result[0]["parsing_res_list"]:
if block.content.strip():
blocks.append({"label": block.label, "bbox": block.bbox, "content": block.content})
return {
"path": str(image_path),
"elapsed": round(elapsed, 2),
"blocks": blocks,
}
def main():
parser = argparse.ArgumentParser(description="Batch OCR with multiprocessing")
parser.add_argument("dir", type=str, help="图片目录")
parser.add_argument("--workers", type=int, default=4, help="并行进程数 (默认 4)")
parser.add_argument("--threads", type=int, default=None, help="每进程线程数 (默认: 总核心/workers)")
args = parser.parse_args()
image_dir = Path(args.dir)
if not image_dir.is_dir():
print(f"[ERROR] 目录不存在: {args.dir}")
sys.exit(1)
images = list(image_dir.glob("*.png")) + list(image_dir.glob("*.jpg")) + list(image_dir.glob("*.jpeg"))
if not images:
print(f"[ERROR] 目录中没有图片: {args.dir}")
sys.exit(1)
workers = min(args.workers, len(images))
threads = args.threads or max(1, cpu_count() // workers)
print(f"图片数量: {len(images)}")
print(f"并行进程: {workers}")
print(f"每进程线程: {threads}")
print(f"总核心利用: {workers * threads} / {cpu_count()}")
print("=" * 60)
t0 = time.perf_counter()
# 每个子进程独立加载模型 + 推理
with Pool(workers) as pool:
tasks = [(str(img), threads) for img in images]
results = pool.starmap(ocr_single, tasks)
total_elapsed = time.perf_counter() - t0
# 输出结果
print("\n" + "=" * 60)
for r in results:
print(f"\n[文件] {r['path']} ({r['elapsed']:.1f}s)")
for block in r["blocks"]:
print(f" [{block['label']}] {block['content'][:60]}{'...' if len(block['content']) > 60 else ''}")
print("\n" + "=" * 60)
print(f"总图片: {len(images)} | 总耗时: {total_elapsed:.1f}s")
print(f"平均每图: {total_elapsed / len(images):.1f}s")
print(f"单进程串行预计: {sum(r['elapsed'] for r in results):.1f}s")
print(f"并行加速比: {sum(r['elapsed'] for r in results) / total_elapsed:.2f}x")
if __name__ == "__main__":
main()