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.
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 ]
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
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.")
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}")
This engine delivers instant, offline tympanic membrane diagnostic summaries conforming to AAP (American Academy of Pediatrics) Otitis Media guidelines.