当你第一次接触眼底图像分析时,可能会被各种专业术语和数据集搞得晕头转向。我刚开始做青光眼筛查项目时,就曾在REFUGE和IDRiD之间反复横跳,浪费了两周时间才发现选错了数据集。今天我们就用最直白的语言,拆解RETOUCH、REFUGE、IDRiD这三个最常用的眼底数据集。
先看最直观的对比表:
| 特征 | RETOUCH | REFUGE | IDRiD |
|---|---|---|---|
| 影像类型 | SD-OCT三维扫描 | 彩色眼底照片(CFP) | 超高分辨率眼底彩照 |
| 核心任务 | 视网膜液体积监测 | 视杯视盘分割 | 糖尿病视网膜病变分级 |
| 典型病灶 | IRF/SRF/PED三种液体 | 视盘/视杯几何结构 | MA/HE/SE/EX四类病灶 |
| 数据量 | 70+患者三维扫描 | 1200张二维图像 | 516张超高清图像 |
| 分辨率 | 512x1024x128(三维) | 2056x2124 | 2848x4288 |
RETOUCH就像医院的CT机,通过OCT扫描能看到视网膜各层的液体渗透情况。我处理老年黄斑变性病例时,发现它的三维数据能清晰显示SRF(视网膜下液)的立体分布,这对判断注射抗VEGF药物的时机特别关键。
REFUGE则是青光眼诊断的"黄金标准",它的视杯视杯分割任务直接关联到CDR(杯盘比)计算。记得有次模型总把视盘边缘识别成视杯,后来发现是没处理好图像中血管投影的干扰。
IDRiD的糖网病灶最有挑战性,特别是MA(微动脉瘤)小到只有几个像素。有次我调整了损失函数权重才把MA的检测率从0.3提升到0.5,但离临床可用还有距离。
RETOUCH的SD-OCT数据就像千层蛋糕,每个volume包含128层切片。不同厂家的设备数据差异很大:
python复制# 典型数据加载代码
import SimpleITK as sitk
oct_volume = sitk.ReadImage('oct.mhd') # 获取512x1024x128的三维数据
irf_mask = (sitk.GetArrayFromImage(oct_volume) == 1) # 提取IRF病灶
实际处理时要特别注意:
处理这种三维数据,我推荐两种技术路线:
有个坑我踩过三次:不同设备的类别极度不平衡。比如Cirrus数据中背景和病灶像素比是245:1,必须用加权交叉熵:
python复制class_weights = torch.tensor([1, 245, 245, 120]) # 背景/IRF/SRF/PED
criterion = nn.CrossEntropyLoss(weight=class_weights)
实测效果最好的数据增强:
REFUGE的2056x2124超高分辨率图像藏着几个魔鬼细节:
我常用的预处理流水线:
python复制def preprocess(image):
image = histogram_equalization(image) # 提升对比度
image = disc_centered_crop(image) # 以视盘为中心裁剪512x512
image = gaussian_blur(image, sigma=1) # 消除高频噪声
return image
经过20多次实验,我发现这些trick最管用:
有个容易忽视的点:CDR计算必须用垂直直径。有次我用了水平直径,导致早期青光眼漏诊率升高15%。正确的计算方式:
python复制vertical_cdr = cup_vertical_diameter / disc_vertical_diameter
IDRiD的2848x4288分辨率带来巨大挑战——一张图展开比4K电视还大!我的标准处理流程:
对于EX(硬性渗出物)这类高对比度病灶,可以先用LoG滤波器增强:
python复制import cv2
log_filter = cv2.Laplacian(image, cv2.CV_64F, ksize=5)
exudates_mask = (log_filter > threshold).astype(np.uint8)
四类病灶的数量差异极大(MA只有HE的1/10),我的应对方案:
有个特别有用的技巧:先分割HE再检测MA,因为出血点周围常伴微动脉瘤。这种级联策略让我的MA检测F1值提升了8%。
根据五年实战经验,我总结出这个选择流程图:
目标疾病判断:
技术路线选择:
资源评估:
最后提醒:RETOUCH和IDRiD都有严格的测试集提交要求,建议先用REFUGE练手。我曾见过团队在比赛截止前才发现测试集格式错误,白白浪费三个月努力。