🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

openocr-skill

by @topdu

Extract text from images, documents and scanned PDFs using OpenOCR - a lightweight and efficient OCR system with document parsing model requiring only 0.1B parameters, capable of running recognition on personal PCs. Supports text detection, recognition, universal VLM recognition, and document parsing with layout analysis

Versionv0.1.6
Downloads2,263
Installs12
TERMINAL
clawhub install openocr-skill

πŸ“– About This Skill


name: openocr-skills description: Extract text from images, documents and scanned PDFs using OpenOCR - a lightweight and efficient OCR system with document parsing model requiring only 0.1B parameters, capable of running recognition on personal PCs. 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:

  • "Extract all text from this image"
  • "Detect text regions in this photo"
  • "Recognize the formula in this screenshot"
  • "Parse this PDF document with layout analysis"
  • "Convert this scanned page to Markdown"
  • Domain Knowledge

    OpenOCR Fundamentals

    from openocr import OpenOCR

    Initialize 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 OpenOCR

    detector = 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 OpenOCR

    Mobile 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 OpenOCR

    ocr = 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 OpenOCR

    unirec = 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 OpenOCR

    doc = 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_vis

    Text Recognition

    openocr --task rec --input_path word.jpg --mode server --backend torch

    End-to-End OCR

    openocr --task ocr --input_path image.jpg --is_vis --output_path ./results

    Universal Recognition

    openocr --task unirec --input_path formula.jpg --max_length 2048

    Document Parsing

    openocr --task doc --input_path document.pdf \ --use_layout_detection --save_vis --save_json --save_markdown

    Launch 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 OpenOCR

    ocr = 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 OpenOCR

    UniRec 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 OpenOCR

    ocr = 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 os

    def 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 re

    def 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 OpenOCR

    def 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 OpenOCR

    def 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 os

    def 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 os

    def 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 OpenOCR

    def 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_demo

    Launch 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

  • Text recognition accuracy depends on image quality
  • Very small or heavily rotated text may reduce accuracy
  • server mode requires PyTorch and is slower than mobile mode
  • UniRec and Doc tasks use 0.1B parameter VLM, larger models may yield better results
  • PDF processing converts pages to images internally, very large PDFs may use significant memory
  • Complex handwritten text accuracy varies
  • GPU recommended for best performance, especially for Doc and UniRec tasks
  • Installation

    # Basic installation (CPU, ONNX backend)
    pip install openocr-python

    GPU-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

  • OpenOCR GitHub
  • PyPI Package
  • UniRec Paper
  • OpenDoc Documentation
  • Model Zoo & Configs
  • πŸ’‘ Examples

    Example 1: Batch OCR with Progress

    from openocr import OpenOCR
    import os

    def 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 os

    def 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 OpenOCR

    def 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_demo

    Launch 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