DeepSeeNet / augmentations.py
farrell236's picture
add src
b8c9192
"""
augmentations.py
Simple camera-style augmentations for color fundus photography (CFP)
classification.
Expected input:
RGB NumPy image, shape (H, W, 3)
Dependencies:
pip install albumentations opencv-python
"""
import cv2
import albumentations as A
from albumentations.pytorch import ToTensorV2
IMAGENET_MEAN = (0.485, 0.456, 0.406)
IMAGENET_STD = (0.229, 0.224, 0.225)
def get_train_transforms(
image_size=1024,
mean=IMAGENET_MEAN,
std=IMAGENET_STD,
):
return A.Compose([
A.Resize(image_size, image_size),
# Geometry is safe
A.HorizontalFlip(p=0.5),
A.ShiftScaleRotate(
shift_limit=0.02,
scale_limit=0.03, # slightly reduced
rotate_limit=5, # slightly reduced
border_mode=0,
value=0,
p=0.3,
),
# MUCH weaker photometric changes
A.RandomBrightnessContrast(
brightness_limit=0.08, # ↓ from 0.15
contrast_limit=0.08,
p=0.3,
),
# Remove or reduce gamma
A.RandomGamma(
gamma_limit=(95, 105), # very mild
p=0.2,
),
# Remove hue shift entirely (important)
# Hue shifts are not realistic for fundus physiology
# -> comment this out or reduce heavily
# A.HueSaturationValue(...)
# Keep mild quality perturbation
A.OneOf([
A.GaussianBlur(blur_limit=(3, 5)),
A.Downscale(scale_min=0.85, scale_max=0.95, interpolation=cv2.INTER_LINEAR),
A.ImageCompression(quality_lower=80, quality_upper=100),
], p=0.15),
A.Normalize(mean=mean, std=std),
ToTensorV2(),
])
def get_val_transforms(
image_size=1024,
mean=IMAGENET_MEAN,
std=IMAGENET_STD,
):
"""
Validation/test transforms.
"""
return A.Compose([
A.Resize(image_size, image_size),
A.Normalize(mean=mean, std=std),
ToTensorV2(),
])