Skip to content
medical-ocr logo

Medical OCR Processing Skill

medical-ocr

Medical document OCR processing for extracting structured clinical data from medical images (prescriptions, lab results, clinical notes). Uses Google Cloud Vision for text extraction and medical NLP for entity recognition. Deploy when processing healthcare documents, extracting patient data, or c...

SKILL.md

Full skill instructions

Medical OCR Processing Skill

Overview

This skill enables Claude to extract and structure clinical data from medical documents using OCR (Optical Character Recognition) combined with medical natural language processing. It's designed specifically for healthcare workflows and FHIR R4 compliance.

When to Use This Skill

Use this skill when you need to:

  • Extract text from medical prescriptions
  • Process lab result images
  • Parse clinical notes from scanned documents
  • Convert handwritten medical forms to structured data
  • Extract vital signs, medications, diagnoses from images
  • Generate FHIR-compliant resources from OCR output

Core Capabilities

1. OCR Text Extraction

from google.cloud import vision
import io

def extract_medical_text(image_path):
    """Extract text from medical image using Google Cloud Vision"""
    client = vision.ImageAnnotatorClient()
    
    with io.open(image_path, 'rb') as image_file:
        content = image_file.read()
    
    image = vision.Image(content=content)
    response = client.text_detection(image=image)
    texts = response.text_annotations
    
    if texts:
        return texts[0].description
    return ""

2. Medical Entity Recognition

Extract clinical entities using pattern matching and medical terminology:

import re

def extract_medications(text):
    """Extract medication names and dosages"""
    # Pattern for common medication formats
    med_pattern = r'([A-Z][a-z]+(?:in|ol|ide|ine))\s+(\d+\s*(?:mg|mcg|g|mL))'
    medications = re.findall(med_pattern, text)
    
    return [
        {"name": med[0], "dosage": med[1]}
        for med in medications
    ]

def extract_vital_signs(text):
    """Extract vital signs from text"""
    vitals = {}
    
    # Blood pressure pattern
    bp = re.search(r'BP[:\s]+(\d{2,3}/\d{2,3})', text, re.I)
    if bp:
        vitals['blood_pressure'] = bp.group(1)
    
    # Heart rate pattern
    hr = re.search(r'HR[:\s]+(\d{2,3})', text, re.I)
    if hr:
        vitals['heart_rate'] = hr.group(1)
    
    # Temperature pattern
    temp = re.search(r'Temp[:\s]+(\d{2,3}\.?\d*)', text, re.I)
    if temp:
        vitals['temperature'] = temp.group(1)
    
    return vitals

3. Document Type Classification

def classify_medical_document(text):
    """Determine the type of medical document"""
    text_lower = text.lower()
    
    if any(word in text_lower for word in ['prescription', 'rx', 'sig:']):
        return 'prescription'
    elif any(word in text_lower for word in ['lab results', 'test results', 'specimen']):
        return 'lab_results'
    elif any(word in text_lower for word in ['progress note', 'soap', 'assessment']):
        return 'clinical_notes'
    elif any(word in text_lower for word in ['discharge', 'summary']):
        return 'discharge_summary'
    else:
        return 'unknown'

4. FHIR Resource Generation

def generate_fhir_medication_request(medication_data):
    """Generate FHIR R4 MedicationRequest from extracted data"""
    return {
        "resourceType": "MedicationRequest",
        "status": "active",
        "intent": "order",
        "medication": {
            "CodeableConcept": {
                "text": medication_data['name']
            }
        },
        "dosageInstruction": [{
            "text": medication_data['dosage'],
            "timing": {
                "repeat": {
                    "frequency": medication_data.get('frequency', 1),
                    "period": 1,
                    "periodUnit": "d"
                }
            },
            "doseAndRate": [{
                "doseQuantity": {
                    "value": medication_data.get('dose_value'),
                    "unit": medication_data.get('dose_unit', 'mg')
                }
            }]
        }]
    }

Medical Abbreviation Dictionary

Common medical abbreviations that should be expanded:

MEDICAL_ABBREVIATIONS = {
    # Frequency
    "BID": "Twice daily",
    "TID": "Three times daily",
    "QID": "Four times daily",
    "QD": "Once daily",
    "PRN": "As needed",
    "STAT": "Immediately",
    "AC": "Before meals",
    "PC": "After meals",
    "HS": "At bedtime",
    
    # Route
    "PO": "By mouth / Oral",
    "IV": "Intravenous",
    "IM": "Intramuscular",
    "SC/​SQ": "Subcutaneous",
    "SL": "Sublingual",
    "TOP": "Topical",
    
    # Clinical
    "NPO": "Nothing by mouth",
    "SOB": "Shortness of breath",
    "N/​V": "Nausea and vomiting",
    "CBC": "Complete Blood Count",
    "CMP": "Comprehensive Metabolic Panel",
    "CXR": "Chest X-Ray",
    "EKG/​ECG": "Electrocardiogram",
    "BP": "Blood Pressure",
    "HR": "Heart Rate",
    "RR": "Respiratory Rate",
    "Temp": "Temperature"
}

Workflow Patterns

Complete OCR Pipeline

def process_medical_document(image_path):
    """Complete pipeline for medical document processing"""
    
    # Step 1: OCR extraction
    raw_text = extract_medical_text(image_path)
    
    # Step 2: Document classification
    doc_type = classify_medical_document(raw_text)
    
    # Step 3: Entity extraction
    entities = {
        'medications': extract_medications(raw_text),
        'vitals': extract_vital_signs(raw_text),
        'type': doc_type
    }
    
    # Step 4: FHIR resource generation
    fhir_resources = []
    for med in entities['medications']:
        fhir_resources.append(
            generate_fhir_medication_request(med)
        )
    
    return {
        'raw_text': raw_text,
        'document_type': doc_type,
        'extracted_entities': entities,
        'fhir_resources': fhir_resources,
        'confidence': 0.85  # Calculate based on OCR confidence
    }

Quality Assurance

Confidence Scoring

def calculate_confidence(ocr_result, extracted_entities):
    """Calculate overall confidence score"""
    scores = []
    
    # OCR confidence (from Google Vision)
    if hasattr(ocr_result, 'confidence'):
        scores.append(ocr_result.confidence)
    
    # Entity extraction confidence
    if extracted_entities['medications']:
        scores.append(0.9)  # High confidence for structured meds
    
    if extracted_entities['vitals']:
        scores.append(0.85)
    
    return sum(scores) / len(scores) if scores else 0.0

Validation Rules

def validate_extracted_data(data):
    """Validate extracted medical data"""
    warnings = []
    
    # Check for missing critical fields
    if not data.get('medications'):
        warnings.append("No medications detected")
    
    # Validate vital signs ranges
    vitals = data.get('vitals', {})
    if 'blood_pressure' in vitals:
        bp = vitals['blood_pressure']
        systolic, diastolic = map(int, bp.split('/'))
        if systolic > 180 or diastolic > 120:
            warnings.append(f"Critical BP value: {bp}")
    
    return warnings

HIPAA Compliance Guidelines

When processing medical documents:

  1. PHI Handling: Always log access to Protected Health Information
  2. Encryption: Ensure data is encrypted at rest and in transit
  3. Audit Trail: Maintain audit logs of all OCR operations
  4. Data Minimization: Only extract necessary clinical data
  5. Retention: Follow organizational data retention policies
def audit_log_ocr_operation(user_id, document_id, operation):
    """Log OCR operation for HIPAA compliance"""
    log_entry = {
        "timestamp": datetime.utcnow().isoformat(),
        "user_id": user_id,
        "document_id": document_id,
        "operation": operation,
        "phi_accessed": True,
        "justification": "Clinical data extraction for patient care"
    }
    # Store in secure audit log
    return log_entry

Integration with Agents

This skill integrates with the following agents:

  • OCRLINC: Primary OCR processing agent
  • HEALTHCARELINC: Medical entity extraction and structuring
  • COMPLIANCELINC: HIPAA compliance and audit logging
  • TTLINC: Translation for bilingual medical documents

Error Handling

def handle_ocr_errors(image_path):
    """Robust error handling for OCR operations"""
    try:
        result = extract_medical_text(image_path)
        if not result:
            return {
                "error": "No text detected",
                "suggestion": "Improve image quality or check orientation"
            }
        return {"success": True, "text": result}
    
    except Exception as e:
        return {
            "error": str(e),
            "image_path": image_path,
            "suggestion": "Check image format and API credentials"
        }

Best Practices

  1. Image Quality: Ensure images are high-resolution (300+ DPI)
  2. Preprocessing: Apply deskew, denoise, and contrast enhancement
  3. Language Detection: Specify languages for better accuracy
  4. Handwriting: Use specialized models for handwritten notes
  5. Validation: Always validate extracted data against clinical rules
  6. Confidence Thresholds: Only accept results above 80% confidence
  7. Human Review: Flag low-confidence extractions for manual review

Examples

Example 1: Process Prescription

# Input: prescription.jpg
result = process_medical_document("prescription.jpg")

# Output:
{
    "document_type": "prescription",
    "medications": [
        {"name": "Metformin", "dosage": "500mg", "frequency": "BID"},
        {"name": "Lisinopril", "dosage": "10mg", "frequency": "QD"}
    ],
    "fhir_resources": [...],
    "confidence": 0.92
}

Example 2: Extract Lab Results

# Input: lab_results.jpg
result = process_medical_document("lab_results.jpg")

# Output:
{
    "document_type": "lab_results",
    "tests": [
        {"name": "Hemoglobin A1C", "value": "7.2", "unit": "%"},
        {"name": "Fasting Glucose", "value": "126", "unit": "mg/​dL"}
    ],
    "confidence": 0.88
}

Performance Metrics

  • Processing Time: 2-5 seconds per image
  • Accuracy: 90%+ for printed text, 75%+ for handwriting
  • Supported Formats: JPEG, PNG, PDF (single page)
  • Max File Size: 10MB
  • Concurrent Processing: Up to 10 documents

Updates and Maintenance

This skill should be updated when:

  • New medical terminology is added
  • FHIR specification updates
  • OCR model improvements are available
  • New document types need support

Version: 1.0.0
Last Updated: 2024-11-22
Maintainer: Doctors-Linc Development Team

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View