AI Retinal Analysis: Grading and Segmentation

An ophthalmologist spends an average of 3 minutes analyzing a single fundus image. For screening 1000 patients per day, that's unrealistic. An AI system cuts the time to 0.5 seconds per image, enabling processing of up to 72,000 images per hour. The problem of mass screening for [diabetic retinopath

AI Development Areas

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1285
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1241
  • image_logo-advance_0.webp
    B2B Advance company logo design
    696
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_logo-aider_0.webp
    AIDER company logo development
    919
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1033

An ophthalmologist spends an average of 3 minutes analyzing a single fundus image. For screening 1000 patients per day, that's unrealistic. An AI system cuts the time to 0.5 seconds per image, enabling processing of up to 72,000 images per hour. The problem of mass screening for diabetic retinopathy (DR) requires a qualified ophthalmologist, but there is a severe shortage in many regions. AI analysis can handle the initial triage — flagging patients who actually need a specialist. We develop such systems: from prototype to production. Our models achieve AUC 0.96 on reference datasets and run in real time. Get a consultation from our engineers for your project — we'll prepare a commercial proposal within 3 business days.

Why AI retinal analysis outperforms manual grading?

Automated grading using the ICDR scale achieves AUC 0.96 — higher than the average specialist accuracy (~80%). The system operates without breaks or attention errors. Comparison: our EfficientNet-B5 evaluates an image in 0.5 seconds, while a physician takes 2–3 minutes. AI reduces the workload on ophthalmologists by 30–40% by directing only patients with confirmed pathology. ROI is achieved through increased throughput and reduced follow-up visits.

What key tasks does retinal analysis solve?

  • DR grading (0–4): determine retinopathy stage
  • Retinal vessel segmentation: assess microcirculation
  • Optic disc and macula detection: calculate C/D ratio for glaucoma
  • Detection of AMD, hypertensive retinopathy

How we implement DR grading

We use EfficientNet-B5 with ImageNet pretrained weights. The model accepts a 456×456 image, applies CLAHE augmentation to improve vessel contrast, and outputs probabilities for 5 classes. During training, we use focal loss to handle class imbalance and augmentations: random rotations, flips, color shifts. The Kaggle DR Dataset is used for training. Code:

import torch import timm import torch.nn as nn from torchvision import transforms class DRGrader: DR_GRADES = { 0: 'No DR', 1: 'Mild NPDR', 2: 'Moderate NPDR', 3: 'Severe NPDR', 4: 'Proliferative DR' } def __init__(self, model_path: str): backbone = timm.create_model('efficientnet_b5', pretrained=False) backbone.classifier = nn.Sequential( nn.Dropout(0.4), nn.Linear(backbone.classifier.in_features, 5) ) backbone.load_state_dict(torch.load(model_path)) backbone.eval() self.model = backbone self.transform = transforms.Compose([ transforms.Resize((456, 456)), transforms.CenterCrop(400), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) @torch.no_grad() def grade(self, fundus_image_path: str) -> dict: from PIL import Image image = Image.open(fundus_image_path).convert('RGB') image = self._enhance_fundus(image) tensor = self.transform(image).unsqueeze(0) logits = self.model(tensor) probs = torch.softmax(logits, dim=1).squeeze().numpy() grade = int(probs.argmax()) return { 'grade': grade, 'grade_label': self.DR_GRADES[grade], 'probabilities': {self.DR_GRADES[i]: float(probs[i]) for i in range(5)}, 'referable': grade >= 2, 'vision_threatening': grade >= 3 } def _enhance_fundus(self, image) -> 'PIL.Image': import cv2 import numpy as np img_array = np.array(image) lab = cv2.cvtColor(img_array, cv2.COLOR_RGB2LAB) l, a, b = cv2.split(lab) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) l_enhanced = clahe.apply(l) enhanced = cv2.cvtColor(cv2.merge([l_enhanced, a, b]), cv2.COLOR_LAB2RGB) return Image.fromarray(enhanced) 

How we segment vessels

For vessel segmentation, we use U-Net++ with an SE-ResNeXt50 encoder. The model is trained on the DRIVE dataset with a combined Dice + BCE loss. On validation, AUC reaches 0.99. This helps detect early microcirculation changes.

import segmentation_models_pytorch as smp vessel_segmenter = smp.UnetPlusPlus( encoder_name='se_resnext50_32x4d', encoder_weights='imagenet', in_channels=3, classes=1, activation='sigmoid' ) 

For comparison: baseline U-Net yields AUC 0.97, Attention U-Net 0.98. Architecture choice depends on inference speed requirements: U-Net++ processes an image in 0.6s, acceptable for streaming.

How we detect disc and macula

We use YOLO for simultaneous detection of optic disc, macula, and fovea. This enables automatic calculation of C/D ratio — a key metric for glaucoma diagnosis.

from ultralytics import YOLO class RetinalStructureDetector: def __init__(self, model_path: str): self.detector = YOLO(model_path) self.structures = ['optic_disc', 'macula', 'fovea'] def detect(self, fundus_image: np.ndarray) -> dict: results = self.detector(fundus_image, conf=0.5) detected = {} for box in results[0].boxes: structure = self.structures[int(box.cls)] x1, y1, x2, y2 = map(int, box.xyxy[0]) cx, cy = (x1+x2)//2, (y1+y2)//2 detected[structure] = { 'center': (cx, cy), 'bbox': [x1, y1, x2, y2], 'confidence': float(box.conf) } if 'optic_disc' in detected: detected['cdr'] = self._calculate_cdr(fundus_image, detected['optic_disc']) return detected 

How we guarantee quality?

Validation is performed on retrospective images from your clinic. We calculate AUC, sensitivity, and specificity for each module. If metrics fall below thresholds, we fine-tune the model. We guarantee AUC no lower than 0.95 on reference datasets. During deployment, we provide a Docker image with an API service (REST/gRPC), model card documentation, and deployment instructions. Operator training takes 2–3 days. If needed, we fine-tune the model on your data within 2 weeks.

Process and timelines

  1. Requirements analysis — gather clinical scenarios, available datasets, accuracy and speed requirements.
  2. Prototyping — quick baseline on public data, feasibility assessment.
  3. Development — train final architecture on your data with augmentation, hyperparameter fine-tuning.
  4. Validation — test on retrospective images, calculate AUC, sensitivity, specificity.
  5. Deployment — package as Docker/REST API, integrate with PACS, train staff.
Module Duration
DR grading (EfficientNet-B5) 6–10 weeks
Vessel segmentation (U-Net++) 6–8 weeks
Structure detection (YOLO) 4–6 weeks
Full retinal system 14–22 weeks

Contact us

Our team has over 5 years of experience in medical AI, with 12 completed ophthalmology projects, including integration with PACS in large clinics. We only use proven architectures: EfficientNet, U-Net, YOLO. Interested? Get a consultation from our engineers for your project. Contact us — we'll prepare a commercial proposal within 3 business days.