opencr-skill
by @topdu
Extract text from images, documents and scanned PDFs using OpenOCR - supports text detection, recognition, universal VLM recognition, and document parsing with layout analysis
clawhub install opencr-skillπ About This Skill
name: openocr-skills description: Extract text from images, documents and scanned PDFs using OpenOCR - supports text detection, recognition, universal VLM recognition, and document parsing with layout analysis author: openocr version: "0.1.4" tags: [ocr, text-detection, text-recognition, document-parsing, vlm, unirec, layout-analysis, formula, table] tools: [computer, code_execution, file_operations] library: name: OpenOCR url: https://github.com/Topdu/OpenOCR stars: 1k+
OpenOCR Skill
Overview
This skill enables intelligent text extraction, document parsing, and universal recognition using OpenOCR - an accurate and efficient general OCR system. It provides a unified interface for text detection, text recognition, end-to-end OCR, VLM-based universal recognition (text/formulas/tables), and document parsing with layout analysis. Supports Chinese, English, and more.
How to Use
1. Provide the image, scanned document, or PDF 2. Optionally specify the task type (det/rec/ocr/unirec/doc) 3. I'll extract text, formulas, tables, or full document structure
Example prompts:
Domain Knowledge
OpenOCR Fundamentals
from openocr import OpenOCRInitialize with a specific task
engine = OpenOCR(task='ocr')Run OCR on an image (callable interface)
results, time_dicts = engine(image_path='image.jpg')Results contain detected boxes with recognized text
for result in results:
for line in result:
box = line[0] # Bounding box coordinates
text = line[1][0] # Recognized text
conf = line[1][1] # Confidence score
print(f"{text} ({conf:.2f})")
Supported Tasks
# Available task types
tasks = {
'det': 'Text Detection - detect text regions with bounding boxes',
'rec': 'Text Recognition - recognize text from cropped images',
'ocr': 'End-to-End OCR - detection + recognition pipeline',
'unirec': 'Universal Recognition - VLM-based text/formula/table recognition (0.1B params)',
'doc': 'Document Parsing - layout analysis + universal recognition (0.1B params)',
}Task selection via parameter
det_engine = OpenOCR(task='det')
rec_engine = OpenOCR(task='rec')
ocr_engine = OpenOCR(task='ocr')
unirec_engine = OpenOCR(task='unirec')
doc_engine = OpenOCR(task='doc')
Configuration Options
from openocr import OpenOCR=== Text Detection ===
detector = OpenOCR(
task='det',
backend='onnx', # 'onnx' (default) or 'torch'
onnx_det_model_path=None, # Custom detection model (auto-downloads if None)
use_gpu='auto', # 'auto', 'true', or 'false'
)=== Text Recognition ===
recognizer = OpenOCR(
task='rec',
mode='mobile', # 'mobile' (fast) or 'server' (accurate)
backend='onnx', # 'onnx' (default) or 'torch'
onnx_rec_model_path=None, # Custom recognition model
use_gpu='auto',
)=== End-to-End OCR ===
ocr = OpenOCR(
task='ocr',
mode='mobile', # 'mobile' or 'server'
backend='onnx', # 'onnx' or 'torch'
onnx_det_model_path=None, # Custom detection model
onnx_rec_model_path=None, # Custom recognition model
drop_score=0.5, # Confidence threshold for filtering
det_box_type='quad', # 'quad' or 'poly' (for curved text)
use_gpu='auto',
)=== Universal Recognition (UniRec) ===
unirec = OpenOCR(
task='unirec',
unirec_encoder_path=None, # Custom encoder ONNX model
unirec_decoder_path=None, # Custom decoder ONNX model
tokenizer_mapping_path=None, # Custom tokenizer mapping JSON
max_length=2048, # Max generation length
auto_download=True, # Auto-download missing models
use_gpu='auto',
)=== Document Parsing (OpenDoc) ===
doc = OpenOCR(
task='doc',
layout_model_path=None, # Custom layout detection model (PP-DocLayoutV2)
unirec_encoder_path=None, # Custom UniRec encoder
unirec_decoder_path=None, # Custom UniRec decoder
tokenizer_mapping_path=None, # Custom tokenizer mapping
layout_threshold=0.5, # Layout detection threshold
use_layout_detection=True, # Enable layout analysis
max_parallel_blocks=4, # Max parallel VLM blocks
auto_download=True, # Auto-download missing models
use_gpu='auto',
)
Task-Specific Usage
#### Text Detection
from openocr import OpenOCRdetector = OpenOCR(task='det', backend='onnx')
Detect text regions
results = detector(image_path='image.jpg')boxes = results[0]['boxes'] # np.ndarray of bounding boxes
elapse = results[0]['elapse'] # Processing time in seconds
print(f"Found {len(boxes)} text regions in {elapse:.3f}s")
for box in boxes:
print(f" Box: {box.tolist()}")
#### Text Recognition
from openocr import OpenOCRMobile mode (fast, ONNX)
recognizer = OpenOCR(task='rec', mode='mobile', backend='onnx')Server mode (accurate, requires torch)
recognizer = OpenOCR(task='rec', mode='server', backend='torch')
results = recognizer(image_path='word.jpg', batch_num=1)
text = results[0]['text'] # Recognized text string
score = results[0]['score'] # Confidence score
elapse = results[0]['elapse'] # Processing time
print(f"Text: {text}, Score: {score:.3f}, Time: {elapse:.3f}s")
#### End-to-End OCR
from openocr import OpenOCRocr = OpenOCR(task='ocr', mode='mobile', backend='onnx')
Run OCR with visualization
results, time_dicts = ocr(
image_path='image.jpg',
save_dir='./output',
is_visualize=True,
rec_batch_num=6,
)Process results
for result in results:
for line in result:
box, (text, confidence) = line[0], line[1]
print(f"{text} ({confidence:.2f})")
#### Universal Recognition (UniRec)
from openocr import OpenOCRunirec = OpenOCR(task='unirec')
Image input
result_text, generated_ids = unirec(image_path='formula.jpg', max_length=2048)
print(f"Result: {result_text}")PDF input (returns list of tuples, one per page)
results = unirec(image_path='document.pdf', max_length=2048)
for page_text, page_ids in results:
print(f"Page: {page_text[:100]}...")
#### Document Parsing (OpenDoc)
from openocr import OpenOCRdoc = OpenOCR(task='doc', use_layout_detection=True)
Parse a document image
result = doc(image_path='document.jpg')Save outputs in multiple formats
doc.save_to_markdown(result, './output')
doc.save_to_json(result, './output')
doc.save_visualization(result, './output')Parse a PDF (returns list of dicts, one per page)
results = doc(image_path='document.pdf')
for page_result in results:
doc.save_to_markdown(page_result, './output')
Command-Line Interface
# Text Detection
openocr --task det --input_path image.jpg --is_visText Recognition
openocr --task rec --input_path word.jpg --mode server --backend torchEnd-to-End OCR
openocr --task ocr --input_path image.jpg --is_vis --output_path ./resultsUniversal Recognition
openocr --task unirec --input_path formula.jpg --max_length 2048Document Parsing
openocr --task doc --input_path document.pdf \
--use_layout_detection --save_vis --save_json --save_markdownLaunch Gradio Demos
openocr --task launch_openocr_demo --share --server_port 7860
openocr --task launch_unirec_demo --share --server_port 7861
openocr --task launch_opendoc_demo --share --server_port 7862
Processing Different Sources
#### Image Files
from openocr import OpenOCRocr = OpenOCR(task='ocr')
Single image
results, _ = ocr(image_path='image.jpg')Directory of images
results, _ = ocr(image_path='./images/', save_dir='./output', is_visualize=True)
#### PDF Files
from openocr import OpenOCRUniRec handles PDFs natively
unirec = OpenOCR(task='unirec')
results = unirec(image_path='document.pdf', max_length=2048)OpenDoc handles PDFs natively with layout analysis
doc = OpenOCR(task='doc', use_layout_detection=True)
results = doc(image_path='document.pdf')Save each page
for page_result in results:
doc.save_to_markdown(page_result, './output')
doc.save_to_json(page_result, './output')
#### Numpy Array Input
import cv2
from openocr import OpenOCRocr = OpenOCR(task='ocr')
Read image as numpy array
img = cv2.imread('image.jpg')Pass numpy array directly
results, _ = ocr(img_numpy=img)
Result Formats
# Detection result format
det_result = [{'boxes': np.ndarray, 'elapse': float}]Recognition result format
rec_result = [{'text': str, 'score': float, 'elapse': float}]OCR result format (detection + recognition)
ocr_result = (results_list, time_dicts)
results_list: [[[box, (text, confidence)], ...], ...]
UniRec result format
Image: (text: str, generated_ids: list)
PDF: [(text: str, generated_ids: list), ...] # one per page
Doc result format
Image: dict with layout blocks and recognized content
PDF: [dict, ...] # one per page
Best Practices
1. Choose the Right Task: Use ocr for general text, unirec for formulas/tables, doc for full documents
2. Use Mobile Mode for Speed: mode='mobile' is much faster; use mode='server' only when accuracy is critical
3. Use ONNX Backend: Default ONNX backend works on CPU without extra dependencies
4. Set Appropriate Thresholds: Adjust drop_score (OCR) and layout_threshold (Doc) for your use case
5. Enable Layout Detection: For documents with mixed content (text + formulas + tables), always enable use_layout_detection
6. Batch Processing: Use rec_batch_num to control recognition batch size for throughput optimization
7. GPU Acceleration: Install onnxruntime-gpu or PyTorch with CUDA for significant speedup
Common Patterns
Full Document Processing Pipeline
from openocr import OpenOCR
import osdef process_documents(input_dir, output_dir):
"""Process all documents in a directory."""
doc = OpenOCR(task='doc', use_layout_detection=True)
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if filename.lower().endswith(('.jpg', '.png', '.pdf', '.bmp')):
filepath = os.path.join(input_dir, filename)
print(f"Processing: {filename}")
result = doc(image_path=filepath)
# Handle PDF (list) vs image (dict)
if isinstance(result, list):
for page_result in result:
doc.save_to_markdown(page_result, output_dir)
doc.save_to_json(page_result, output_dir)
else:
doc.save_to_markdown(result, output_dir)
doc.save_to_json(result, output_dir)
print(f"All results saved to {output_dir}")
process_documents('./docs', './output')
OCR with Custom Post-Processing
from openocr import OpenOCR
import redef extract_structured_text(image_path, drop_score=0.5):
"""Extract and structure text from an image."""
ocr = OpenOCR(task='ocr', drop_score=drop_score)
results, _ = ocr(image_path=image_path)
lines = []
for result in results:
for line in result:
box = line[0]
text = line[1][0]
confidence = line[1][1]
# Calculate bounding box center
y_center = sum(p[1] for p in box) / 4
lines.append({
'text': text,
'confidence': confidence,
'y_center': y_center,
'box': box,
})
# Sort by vertical position (top to bottom)
lines.sort(key=lambda x: x['y_center'])
return lines
result = extract_structured_text('page.jpg')
for line in result:
print(f"{line['text']} ({line['confidence']:.2f})")
Formula Recognition
from openocr import OpenOCRdef recognize_formula(image_path):
"""Recognize mathematical formula from image."""
unirec = OpenOCR(task='unirec')
text, ids = unirec(image_path=image_path, max_length=2048)
# UniRec outputs LaTeX for formulas
print(f"LaTeX: {text}")
return text
latex = recognize_formula('formula.png')
Output: \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
Table Extraction
from openocr import OpenOCRdef extract_table(image_path):
"""Extract table content from image."""
unirec = OpenOCR(task='unirec')
text, ids = unirec(image_path=image_path, max_length=2048)
# UniRec outputs LaTeX table format
print(f"Table: {text}")
return text
table_latex = extract_table('table.png')
Examples
Example 1: Batch OCR with Progress
from openocr import OpenOCR
import osdef batch_ocr(image_dir, output_dir='./ocr_results'):
"""OCR all images in a directory."""
ocr = OpenOCR(task='ocr', mode='mobile')
os.makedirs(output_dir, exist_ok=True)
image_files = [
f for f in os.listdir(image_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.tiff'))
]
all_results = {}
for i, filename in enumerate(image_files):
filepath = os.path.join(image_dir, filename)
print(f"[{i+1}/{len(image_files)}] Processing: {filename}")
results, time_dicts = ocr(
image_path=filepath,
save_dir=output_dir,
is_visualize=True,
)
texts = []
for result in results:
for line in result:
texts.append(line[1][0])
all_results[filename] = texts
print(f" Found {len(texts)} text lines")
# Save all text
with open(os.path.join(output_dir, 'all_text.txt'), 'w') as f:
for filename, texts in all_results.items():
f.write(f"--- {filename} ---\n")
f.write('\n'.join(texts))
f.write('\n\n')
return all_results
results = batch_ocr('./images')
Example 2: Document to Markdown Converter
from openocr import OpenOCR
import osdef doc_to_markdown(input_path, output_dir='./markdown_output'):
"""Convert document images or PDFs to Markdown."""
doc = OpenOCR(
task='doc',
use_layout_detection=True,
use_chart_recognition=True,
)
os.makedirs(output_dir, exist_ok=True)
result = doc(image_path=input_path)
if isinstance(result, list):
# PDF: multiple pages
for page_result in result:
doc.save_to_markdown(page_result, output_dir)
print(f"Converted {len(result)} pages to Markdown")
else:
# Single image
doc.save_to_markdown(result, output_dir)
print("Converted image to Markdown")
print(f"Output saved to: {output_dir}")
Convert a scanned PDF
doc_to_markdown('paper.pdf')Convert a document image
doc_to_markdown('page.jpg')
Example 3: Multi-Task Comparison
from openocr import OpenOCRdef compare_tasks(image_path):
"""Compare results from different OpenOCR tasks."""
# 1. Detection only
det = OpenOCR(task='det')
det_result = det(image_path=image_path)
num_boxes = len(det_result[0]['boxes'])
print(f"Detection: Found {num_boxes} text regions")
# 2. End-to-End OCR
ocr = OpenOCR(task='ocr')
ocr_results, _ = ocr(image_path=image_path)
ocr_texts = [line[1][0] for result in ocr_results for line in result]
print(f"OCR: Extracted {len(ocr_texts)} text lines")
for t in ocr_texts[:5]:
print(f" - {t}")
# 3. Universal Recognition
unirec = OpenOCR(task='unirec')
text, _ = unirec(image_path=image_path)
print(f"UniRec: {text[:200]}...")
return {
'det_boxes': num_boxes,
'ocr_texts': ocr_texts,
'unirec_text': text,
}
compare_tasks('document.jpg')
Example 4: Gradio Demo Launch
from openocr import launch_openocr_demo, launch_unirec_demo, launch_opendoc_demoLaunch OCR demo
launch_openocr_demo(share=True, server_port=7860, server_name='0.0.0.0')Launch UniRec demo
launch_unirec_demo(share=True, server_port=7861)Launch OpenDoc demo
launch_opendoc_demo(share=True, server_port=7862)
Limitations
server mode requires PyTorch and is slower than mobile modeInstallation
# Basic installation (CPU, ONNX backend)
pip install openocr-pythonGPU-accelerated ONNX inference
pip install openocr-python[onnx-gpu]PyTorch backend (for server mode)
pip install openocr-python[pytorch]Gradio demos
pip install openocr-python[gradio]All optional dependencies
pip install openocr-python[all]From source
git clone https://github.com/Topdu/OpenOCR.git
cd OpenOCR
python build_package.py
pip install ./build/dist/openocr_python-*.whl
Resources
π‘ Examples
Example 1: Batch OCR with Progress
from openocr import OpenOCR
import osdef batch_ocr(image_dir, output_dir='./ocr_results'):
"""OCR all images in a directory."""
ocr = OpenOCR(task='ocr', mode='mobile')
os.makedirs(output_dir, exist_ok=True)
image_files = [
f for f in os.listdir(image_dir)
if f.lower().endswith(('.jpg', '.jpeg', '.png', '.bmp', '.tiff'))
]
all_results = {}
for i, filename in enumerate(image_files):
filepath = os.path.join(image_dir, filename)
print(f"[{i+1}/{len(image_files)}] Processing: {filename}")
results, time_dicts = ocr(
image_path=filepath,
save_dir=output_dir,
is_visualize=True,
)
texts = []
for result in results:
for line in result:
texts.append(line[1][0])
all_results[filename] = texts
print(f" Found {len(texts)} text lines")
# Save all text
with open(os.path.join(output_dir, 'all_text.txt'), 'w') as f:
for filename, texts in all_results.items():
f.write(f"--- {filename} ---\n")
f.write('\n'.join(texts))
f.write('\n\n')
return all_results
results = batch_ocr('./images')
Example 2: Document to Markdown Converter
from openocr import OpenOCR
import osdef doc_to_markdown(input_path, output_dir='./markdown_output'):
"""Convert document images or PDFs to Markdown."""
doc = OpenOCR(
task='doc',
use_layout_detection=True,
use_chart_recognition=True,
)
os.makedirs(output_dir, exist_ok=True)
result = doc(image_path=input_path)
if isinstance(result, list):
# PDF: multiple pages
for page_result in result:
doc.save_to_markdown(page_result, output_dir)
print(f"Converted {len(result)} pages to Markdown")
else:
# Single image
doc.save_to_markdown(result, output_dir)
print("Converted image to Markdown")
print(f"Output saved to: {output_dir}")
Convert a scanned PDF
doc_to_markdown('paper.pdf')Convert a document image
doc_to_markdown('page.jpg')
Example 3: Multi-Task Comparison
from openocr import OpenOCRdef compare_tasks(image_path):
"""Compare results from different OpenOCR tasks."""
# 1. Detection only
det = OpenOCR(task='det')
det_result = det(image_path=image_path)
num_boxes = len(det_result[0]['boxes'])
print(f"Detection: Found {num_boxes} text regions")
# 2. End-to-End OCR
ocr = OpenOCR(task='ocr')
ocr_results, _ = ocr(image_path=image_path)
ocr_texts = [line[1][0] for result in ocr_results for line in result]
print(f"OCR: Extracted {len(ocr_texts)} text lines")
for t in ocr_texts[:5]:
print(f" - {t}")
# 3. Universal Recognition
unirec = OpenOCR(task='unirec')
text, _ = unirec(image_path=image_path)
print(f"UniRec: {text[:200]}...")
return {
'det_boxes': num_boxes,
'ocr_texts': ocr_texts,
'unirec_text': text,
}
compare_tasks('document.jpg')
Example 4: Gradio Demo Launch
from openocr import launch_openocr_demo, launch_unirec_demo, launch_opendoc_demoLaunch OCR demo
launch_openocr_demo(share=True, server_port=7860, server_name='0.0.0.0')Launch UniRec demo
launch_unirec_demo(share=True, server_port=7861)Launch OpenDoc demo
launch_opendoc_demo(share=True, server_port=7862)
π Tips & Best Practices
1. Choose the Right Task: Use ocr for general text, unirec for formulas/tables, doc for full documents
2. Use Mobile Mode for Speed: mode='mobile' is much faster; use mode='server' only when accuracy is critical
3. Use ONNX Backend: Default ONNX backend works on CPU without extra dependencies
4. Set Appropriate Thresholds: Adjust drop_score (OCR) and layout_threshold (Doc) for your use case
5. Enable Layout Detection: For documents with mixed content (text + formulas + tables), always enable use_layout_detection
6. Batch Processing: Use rec_batch_num to control recognition batch size for throughput optimization
7. GPU Acceleration: Install onnxruntime-gpu or PyTorch with CUDA for significant speedup