Cookbook 72: Offline Otolaryngology Tympanic Membrane Otoscopy & Otitis Classifier

This cookbook details how to deploy a localized otolaryngology digital otoscopy analysis engine to segment tympanic membrane (TM) boundaries, detect middle ear effusion, calculate perforation surface areas, and grade Acute Otitis Media (AOM) directly from high-definition video otoscopes without cloud API latency.

1. Overview & Use Case

Otitis media is the primary cause of pediatric antibiotic prescriptions and urgent care visits. In pediatric clinics, ENT practices, and teledermatology/tele-ENT settings, automated computer-aided diagnosis of the tympanic membrane (evaluating bulging, erythema, translucency, and fluid levels) reduces diagnostic error and inappropriate antibiotic over-prescription.

This engine enables:

       [ High-Definition Digital Otoscopy Frame ]
                           │
                           ▼
                   [ OtoNet-TM-v1 ] 
                   ├── Specular Glare Suppression
                   └── TM Boundary & Malleus Landmark Mask
                           │
                           ▼
               [ Tympanic-Scoring-CLI ]
               ├── Perforation Area Micrometry (%)
               └── AOM / OME Clinical Diagnostic Grading
                           │
                           ▼
        [ Structured Otolaryngology Summary JSON ]

2. Installation & Prerequisites

Ensure Python 3.10+, torch, torchvision, scikit-image, and OpenCV are installed:

pip install torch torchvision opencv-python-headless scikit-image numpy

Clone the offline model weights:

git clone https://github.com/OpenPHRorg/otonet-tm-local.git
cd otonet-tm-local

3. Digital Otoscopy Preprocessing & Glare Filter

Filter specular reflection spots caused by otoscope LED illumination on the moist tympanic surface:

import cv2
import numpy as np

def preprocess_otoscopy_image(image_path):
    img = cv2.imread(image_path)
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    
    # Isolate bright LED specular glare spots
    v_channel = hsv[:, :, 2]
    s_channel = hsv[:, :, 1]
    glare_mask = (v_channel > 240) & (s_channel < 30)
    
    # Inpaint specular reflection points
    glare_mask_uint8 = glare_mask.astype(np.uint8) * 255
    clean_otoscopy = cv2.inpaint(img, glare_mask_uint8, inpaintRadius=3, flags=cv2.INPAINT_TELEA)

    return clean_otoscopy

# Example preprocessing
prep_oto = preprocess_otoscopy_image("sample_tympanic_membrane.jpg")
cv2.imwrite("clean_otoscopy.jpg", prep_oto)
print("Otoscopy image preprocessing completed.")

4. Inference & Otitis Media Clinical Scoring

Execute tympanic membrane segmentation and acute otitis media risk classification:

import torch

def evaluate_tympanic_membrane(clean_image):
    model = torch.hub.load('OpenPHRorg/otonet-tm-local', 'otonet_v1', pretrained=True)
    model.eval()

    tensor_input = torch.from_numpy(clean_image).permute(2, 0, 1).unsqueeze(0).float() / 255.0

    with torch.no_grad():
        tm_mask, perf_mask, otitis_logits = model(tensor_input)
        tm_binary = (torch.sigmoid(tm_mask) > 0.5).numpy()[0, 0]
        perf_binary = (torch.sigmoid(perf_mask) > 0.5).numpy()[0, 0]
        diagnosis_idx = torch.argmax(otitis_logits, dim=1).item()

    tm_area = np.sum(tm_binary)
    perf_area = np.sum(perf_binary)
    perf_pct = (perf_area / float(tm_area) * 100.0) if tm_area > 0 else 0.0

    diagnoses = [
        "Normal Tympanic Membrane",
        "Acute Otitis Media (AOM - Severe Bulging / Erythema)",
        "Otitis Media with Effusion (OME - Serous Fluid)",
        "Tympanic Membrane Perforation"
    ]

    return {
        "primary_diagnosis": diagnoses[diagnosis_idx],
        "tm_perforation_detected": perf_pct > 1.0,
        "perforation_surface_area_pct": round(perf_pct, 1),
        "effusion_present": diagnosis_idx in [1, 2],
        "antibiotic_recommendation": "Indicated (AOM)" if diagnosis_idx == 1 else "Watchful Waiting / Symptomatic"
    }

# Run assessment
result = evaluate_tympanic_membrane(prep_oto)
print(f"Otolaryngology Diagnostic Summary: {result}")

5. Verification & Summary

This engine delivers instant, offline tympanic membrane diagnostic summaries conforming to AAP (American Academy of Pediatrics) Otitis Media guidelines.