Research & Engineering Disclaimer: This architecture demonstrates automated computer vision validation techniques. It is designed for software engineering research and data ingestion pipelines.

The Real Problem: Clinical Capture Variability

When training vision models on curated open-source datasets (such as EyePACS, Messidor, or APTOS), images have already undergone manual review. In real-world clinics and remote screening camps, however, images are captured by varied personnel using different fundus cameras, pupil dilation levels, and patient movement conditions.

Common real-world artifacts include:

  • Motion Blur: Involuntary patient eye saccades during shutter release.
  • Severe Corneal Flare / Overexposure: Light bounce from improperly aligned optical lenses.
  • Insufficient Field of View: Partial capture where the macula or optic disc is clipped outside the camera circle.

The Fast-Reject Pipeline Architecture

Running an expensive neural network to assess quality on every image is slow. Instead, we architect a two-tier gate:

Raw Upload Image
       │
       ▼
┌─────────────────────────────────────────────────────────────┐
│ Tier 1: Sub-Millisecond Mathematical Heuristics (OpenCV)    │
│ • Laplacian Variance (Blur Detection)                       │
│ • Luminance Histogram Skewness (Over/Underexposure)        │
│ • Circular Mask Aspect Ratio (Retinal Field Completeness)   │
└──────────────────────────────┬──────────────────────────────┘
                               │ Passes Tier 1
                               ▼
┌─────────────────────────────────────────────────────────────┐
│ Tier 2: Lightweight MobileNet Quality Classifier            │
│ • Gradable vs. Ungradable binary triage                     │
└──────────────────────────────┬──────────────────────────────┘
                               │ Passes Tier 2
                               ▼
            [ Proceed to Primary Diagnostic Model ]

OpenCV Quality Verification Code

import cv2
import numpy as np

def evaluate_image_quality(image_path: str) -> dict:
    '''Evaluates blur, brightness, and contrast using vectorized OpenCV operations.'''
    img = cv2.imread(image_path)
    if img is None:
        return {"gradable": False, "reason": "File corruption or unreadable format"}

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 1. Blur detection via Laplacian Variance
    laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
    is_blurred = laplacian_var < 85.0  # Calibrated empirical threshold

    # 2. Illumination and Exposure Audit
    mean_brightness = np.mean(gray)
    is_underexposed = mean_brightness < 25.0
    is_overexposed = mean_brightness > 220.0

    # 3. Contrast check via standard deviation
    contrast_std = np.std(gray)
    is_low_contrast = contrast_std < 28.0

    is_gradable = not (is_blurred or is_underexposed or is_overexposed or is_low_contrast)

    reasons = []
    if is_blurred: reasons.append(f"Severe motion blur (Laplacian: {laplacian_var:.1f})")
    if is_underexposed: reasons.append(f"Severe underexposure (Mean: {mean_brightness:.1f})")
    if is_overexposed: reasons.append(f"Overexposure / optical flare (Mean: {mean_brightness:.1f})")
    if is_low_contrast: reasons.append(f"Insufficient contrast (StdDev: {contrast_std:.1f})")

    return {
        "gradable": is_gradable,
        "metrics": {
            "laplacian_variance": round(laplacian_var, 2),
            "mean_brightness": round(mean_brightness, 2),
            "contrast_std": round(contrast_std, 2)
        },
        "reasons": reasons
    }