飞桨常规赛:PALM眼底彩照视盘探测与分割 - 8月第2名方案


飞桨常规赛:PALM眼底彩照视盘探测与分割

常规赛简介

飞桨(PaddlePaddle)以百度多年的深度学习技术研究和业务应用为基础,是中国首个开源开放、技术领先、功能完备的产业级深度学习平台。更多飞桨资讯,点击此处查看。

飞桨常规赛由百度飞桨于 2019 年发起,面向全球 AI 开发者,赛题范围广,涵盖领域多。常规赛旨在通过长期发布的经典比赛项目,为开发者提供学习锻炼机会,助力大家在飞桨大赛中获得骄人成绩。

参赛选手需使用飞桨框架,基于特定赛题下的真实行业数据完成并提交任务。常规赛采取月度评比方式,为打破历史最高记录选手和当月有资格参与月度评奖的前 10 名选手提供飞桨特别礼包奖励。更多惊喜,更多收获,尽在飞桨常规赛。

赛题介绍 本赛题原型为ISBI2019PALM眼科大赛。 近视已成为全球公共卫生负担。在近视患者中,约35%为高度近视。近视导致眼轴长度的延长,可能引起视网膜和脉络膜的病理改变。随着近视屈光度的增加,高度近视将发展为病理性近视,其特点是病理改变的形成:(1)后极,包括镶嵌型眼底、后葡萄肿、视网膜脉络膜变性等;(2)视盘,包括乳头旁萎缩、倾斜等;(3)近视性黄斑,包括漆裂、福氏斑、CNV等。病理性近视对患者造成不可逆的视力损害。因此,早期诊断和定期随访非常重要。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

       

视网膜由黄斑向鼻侧约3mm处有一直径约1.5mm、境界清楚的淡红色圆盘状结构,称为视神经盘,简称视盘。视盘是眼底图像的一个重要特征,对其进行准确、快速地定位与分割对利用眼底图像进行疾病辅助诊断具有重要意义。

比赛任务

该任务目的是对眼底图像的视盘进行检测,若存在视盘结构,需从眼底图像中分割出视盘区域;若无视盘结构,分割结果直接置全背景。        

数据集介绍

本次常规赛提供的金标准由中山大学中山眼科中心的7名眼科医生手工进行视盘像素级标注,之后由另一位高级专家将它们融合为最终的标注结果。存储为BMP图像,与对应的眼底图像大小相同,标签为0代表视盘(黑色区域);标签为255代表其他(白色区域)。

训练数据集

文件名称:Train Train文件夹里有fundus_images文件夹和Disc_Masks文件夹。

fundus_images文件夹内包含800张眼底彩照,分辨率为1444×1444,或2124124×2056。命名形如H0001.jpg、N0001.jpg、P0001.jpg和V0001.jpg。

Disc_Masks文件夹内包含fundus_images里眼底彩照的视盘分割金标准,大小与对应的眼底彩照一致。命名前缀和对应的fundus_images文件夹里的图像命名一致,后缀为bmp。

测试数据集

文件名称:PALM-Testing400-Images

包含400张眼底彩照,命名形如T0001.jpg。

数据集下载:

常规赛:PALM眼底彩照视盘探测与分割数据集

比赛思路

看到语义分割就应该想到PaddleSeg套件啦!可对照PaddleSeg代码解读项目搭建自己的项目

先用Unet进行分割。对预测结果进行处理。

进行分割结果孔洞填充

假如某一张图片预测的结果出现多个不连通的区域,通过面积筛选,只保留最大的面积。(可提升一点dice)

PLAM_model_4成绩为:0.94979

一、数据准备

1.11、解压数据集

In [ ]
#解压数据!unzip -o data/data86770/seg.zip -d /home/aistudio/work
   

1.2、划分数据集

In [ ]
import randomimport os
random.seed(2025)
mask_dir  = '/home/aistudio/work/seg/Train/masks'img_dir = '/home/aistudio/work/seg/Train/fundus_image'path_list = list()for img in os.listdir(img_dir):
    img_path = os.path.join(img_dir,img)
    mask_path = os.path.join(mask_dir,img.replace('jpg', 'png'))
    path_list.append((img_path, mask_path))
random.shuffle(path_list)
ratio = 0.8train_f = open('/home/aistudio/work/seg/Train/train.txt','w') 
val_f = open('/home/aistudio/work/seg/Train/val.txt' ,'w')for i ,content in enumerate(path_list):
    img, mask = content
    text = img + ' ' + mask + '\n'
    if i < len(path_list) * ratio:
        train_f.write(text)    else:
        val_f.write(text)
train_f.close()
val_f.close()
   

1.3、导入依赖项

In [ ]
!pip install paddleseg
    In [ ]
#导入常用的库import osimport randomimport numpy as npfrom random import shuffleimport cv2import paddlefrom PIL import Imageimport shutilimport refrom paddle.vision.transforms import functional as Fimport os.path
   

二、网络训练

2.1 数据增强

In [ ]
import paddleseg.transforms as Tfrom paddleseg.datasets import OpticDiscSeg,Dataset

train_transforms = [
    T.RandomHorizontalFlip(),# 水平翻转
    T.RandomVerticalFlip(),# 垂直翻转
    T.RandomDistort(0.4),# 随机扭曲
    T.RandomBlur(0.3),# 高斯模糊
    T.RandomScaleAspect(min_scale=0.5,aspect_ratio=0.5),# 随机缩放
    T.Resize(target_size=(512,512)),
    T.Normalize()  # 图像标准化]
val_transforms = [
    T.Resize(target_size=(512,512)),
    T.Normalize()

]
   

2.2 构建训练集与验证集

In [ ]
dataset_root = '/home/aistudio/work/seg/Train'train_path  = '/home/aistudio/work/seg/Train/train.txt'val_path  = '/home/aistudio/work/seg/Train/val.txt'# 构建训练集train_dataset = Dataset(
    dataset_root=dataset_root,
    train_path=train_path,
    transforms=train_transforms,
    num_classes=2,
    mode='train'

                  )#验证集val_dataset = Dataset(
    dataset_root=dataset_root,
    val_path=val_path,
    transforms=val_transforms,
    num_classes=2,
    mode='val'

                  )
   

2.3 训练配置

学习率:余弦退火策略(CosineAnnealingDecay)

class paddle.optimizer.lr. CosineAnnealingDecay ( learning_rate, T_max, eta_min=0, last_epoch=- 1, verbose=False )

参数:

  • learning_rate (float) - 初始学习率。
  • T_max (float|int) - 训练的上限轮数,是余弦衰减周期的一半。
  • eta_min (float|int, 可选) - 学习率的最小值。默认值为0。
  • last_epoch (int,可选) - 上一轮的轮数,重启训练时设置为上一轮的epoch数。默认值为 -1,则为初始学习率。
  • verbose (bool,可选) - 如果是 True ,则在每一轮更新时在标准输出 stdout 输出一条信息。默认值为 False 。

返回:用于调整学习率的 CosineAnnealingDecay 实例对象。

优化器:Adam

class paddle.optimizer. Adam ( learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08, parameters=None, weight_decay=None, grad_clip=None, name=None, lazy_mode=False )

参数:

  • learning_rate (float|_LRScheduler) - 学习率,用于参数更新的计算。可以是一个浮点型值或者一个_LRScheduler类,默认值为0.001
  • beta1 (float|Tensor, 可选) - 一阶矩估计的指数衰减率,是一个float类型或者一个shape为[1],数据类型为float32的Tensor类型。默认值为0.9
  • beta2 (float|Tensor, 可选) - 二阶矩估计的指数衰减率,是一个float类型或者一个shape为[1],数据类型为float32的Tensor类型。默认值为0.999
  • epsilon (float, 可选) - 保持数值稳定性的短浮点类型值,默认值为1e-08
  • parameters (list, 可选) - 指定优化器需要优化的参数。在动态图模式下必须提供该参数;在静态图模式下默认值为None,这时所有的参数都将被优化。
  • weight_decay (float|WeightDecayRegularizer,可选) - 正则化方法。可以是float类型的L2正则化系数或者正则化策略: cn_api_fluid_regularizer_L1Decay 、 cn_api_fluid_regularizer_L2Decay 。如果一个参数已经在 ParamAttr 中设置了正则化,这里的正则化设置将被忽略; 如果没有在 ParamAttr 中设置正则化,这里的设置才会生效。默认值为None,表示没有正则化。
  • grad_clip (GradientClipBase, 可选) – 梯度裁剪的策略,支持三种裁剪策略: paddle.nn.ClipGradByGlobalNorm 、 paddle.nn.ClipGradByNorm 、 paddle.nn.ClipGradByValue 。 默认值为None,此时将不进行梯度裁剪。
  • name (str, 可选)- 该参数供开发人员打印调试信息时使用,具体用法请参见 Name ,默认值为None
  • lazy_mode (bool, 可选) - 设为True时,仅更新当前具有梯度的元素。官方Adam算法有两个移动平均累加器(moving-average accumulators)。累加器在每一步都会更新。在密集模式和稀疏模式下,两条移动平均线的每个元素都会更新。如果参数非常大,那么更新可能很慢。 lazy mode仅更新当前具有梯度的元素,所以它会更快。但是这种模式与原始的算法有不同的描述,可能会导致不同的结果,默认为False
In [ ]
import paddlefrom paddleseg.models import UNetfrom paddleseg.models import OCRNetfrom paddleseg.models.losses import CrossEntropyLoss,DiceLoss, MixedLoss

base_lr =0.001iters = 16000 unet_model = UNet(num_classes=2,pretrained='/home/aistudio/output/PLAM_model_3/best_model/model.pdparams')#使用预训练模型unet进行训练# unet_model = UNet(num_classes=2)#使用unet进行训练#自动调整学习率lr =paddle.optimizer.lr.CosineAnnealingDecay(base_lr, T_max=(iters // 3), last_epoch=0.5)
u_optimizer = paddle.optimizer.Adam(lr, parameters=unet_model.parameters())

mixtureLosses = [CrossEntropyLoss(),DiceLoss() ]
mixtureCoef = [0.7,0.3]
losses = {}
losses['types'] = [MixedLoss(mixtureLosses, mixtureCoef)]
losses['coef'] = [1]
   

2.4 开始训练

In [ ]
#进行训练from paddleseg.core import train
train(
    model = unet_model,
    train_dataset=train_dataset,
    val_dataset=val_dataset,
    optimizer=u_optimizer,
    save_dir='output/PLAM_model_4',
    iters=iters,  
    batch_size=4, 
    save_interval=480,
    log_iters=10,
    num_workers=0,
    losses=losses,
    use_vdl=True
    )
   

2.5 模型验证

In [ ]
from paddleseg.core import evaluate
model = UNet(num_classes=2)#换自己保存的模型文件model_path = 'output/PLAM_model_4/best_model/model.pdparams'para_state_dict = paddle.load(model_path)
model.set_dict(para_state_dict)
evaluate(model,val_dataset)
   

三、结果预测

3.1 生成test.txt文件

In [ ]
%cd ~import randomimport os

test_path = r"work/seg/test"test_lst=[]for test in os.listdir(test_path):              
    test_lst.append(test)  

with open('work/seg/test.txt', 'w') as f:    for line in test_lst:
        f.write(line)
        f.write('\n')
   

3.2 预测分割

PLAM_model_2、PLAM_model_3、PLAM_model_4这三个模型皆可达到0.94+

In [ ]
from paddleseg.core import predictimport paddleseg.transforms as pt
transforms = pt.Compose([
    pt.Resize(target_size=(512, 512)),
    pt.Normalize()
])

model = UNet(num_classes=2)#生成图片列表image_list = []with open('work/seg/test.txt' ,'r') as f:    for line in f.readlines():
        image_list.append(os.path.join('work/seg/test/',line.split()[0]))

predict(
        model,        #换自己保存的模型文件
        model_path = 'output/PLAM_model_4/best_model/model.pdparams',
        transforms=transforms,
        image_list=image_list,
        save_dir='results',
    )
   

3.3 生成结果

  • 将分割结果二值化,超过127则为255(白色区域),小于 127则为0(黑色区域)
In [ ]
!mkdir /home/aistudio/newimport os 
import cv2
result_path = '/home/aistudio/results/pseudo_color_prediction'dist_path = '/home/aistudio/new'for img_name in os.listdir(result_path):
    img_path = os.path.join(result_path, img_name)
    img = cv2.imread(img_path)
    g  = img[:,:,1]
    ret, result = cv2.threshold(g, 127,255, cv2.THRESH_BINARY_INV)
    cv2.imwrite(os.path.join(dist_path,img_name), result)
   
  • 将分割结果0-255翻转,并填充孔洞
In [ ]
import cv2import osimport numpy as np'''
图像说明:
图像为二值化图像,255白色为目标物,0黑色为背景
要填充白色目标物中的黑色孔洞
'''def FillHole_1(imgPath,SavePath):
    im_in = cv2.imread(imgPath, cv2.IMREAD_GRAYSCALE);
    th, im_th = cv2.threshold(im_in, 220, 255, cv2.THRESH_BINARY_INV);
    im_floodfill = im_th.copy()
    h, w = im_th.shape[:2]
    mask = np.zeros((h+2, w+2), np.uint8)
    cv2.floodFill(im_floodfill, mask, (0,0), 255);
    im_floodfill_inv = cv2.bitwise_not(im_floodfill)
    im_out = im_th | im_floodfill_inv
    cv2.imwrite(SavePath, im_out)def FillHole_2(imgPath,SavePath):
    im_in = cv2.imread(imgPath, cv2.IMREAD_GRAYSCALE);    # 复制 im_in 图像
    im_floodfill = im_in.copy()    # Mask 用于 floodFill,官方要求长宽+2
    h, w = im_in.shape[:2]
    mask = np.zeros((h+2, w+2), np.uint8)    # floodFill函数中的seedPoint必须是背景
    isbreak = False
    for i in range(im_floodfill.shape[0]):        for j in range(im_floodfill.shape[1]):            if(im_floodfill[i][j]==255):
                seedPoint=(i,j)
                isbreak = True
                break
        if(isbreak):            break
    # 得到im_floodfill
    cv2.floodFill(im_floodfill, mask, seedPoint, 0);    # 得到im_floodfill的逆im_floodfill_inv
    im_floodfill_inv = cv2.bitwise_not(im_floodfill)    # 把im_in、im_floodfill_inv这两幅图像结合起来得到前景
    im_out = im_in | im_floodfill
    cv2.imwrite(SavePath, im_out)


result_path = 'new'dist_path = 'new'for img_name in os.listdir(result_path):
    img_path = os.path.join(result_path, img_name)
    SavePath = os.path.join(dist_path, img_name)

    FillHole_1(img_path,SavePath)
    FillHole_2(img_path,SavePath)
   

假如预测中出现多个不连通的区域,只保留最大的区域

参考吖吖查大佬的:飞桨常规赛:PALM眼底彩照视盘探测与分割 2025 5月第1名方案

In [ ]
!mkdir /home/aistudio/Disc_Segmentationimport os 
import cv2import matplotlib.pyplot as pltdef cnt_area(cnt):
    area = cv2.contourArea(cnt)    return area

result_path = '/home/aistudio/new'dist_path = '/home/aistudio/Disc_Segmentation'for img_name in os.listdir(result_path):
    img_path = os.path.join(result_path, img_name)
    img = cv2.imread(img_path)
    g  = img[:,:,1]
    ret, threshold = cv2.threshold(g, 127,255, cv2.THRESH_BINARY)


    contours, hierarch = cv2.findContours(threshold, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    contours.sort(key=cnt_area, reverse=True)    if len(contours) > 1:        for i in range(1,len(contours)):
            cv2.drawContours(threshold, [contours[i]], 0, 0, -1)
    _,result = cv2.threshold(threshold, 127, 255, cv2.THRESH_BINARY_INV)
    cv2.imwrite(os.path.join(dist_path, img_name), result)
   

结果打包

将结果打包,下载皆可提交:提交

In [ ]
# 压缩当前路径所有文件,输出zip文件path='Disc_Segmentation'import zipfile,os
zipName = 'Disc_Segmentation.zip' #压缩后文件的位置及名称f = zipfile.ZipFile( zipName, 'w', zipfile.ZIP_DEFLATED )for dirpath, dirnames, filenames in os.walk(path):    for filename in filenames:        print(filename)
        f.write(os.path.join(dirpath,filename))
f.close()


# 算法  # 模式下  # 将被  # 浮点  # 多个  # 则为  # 累加器  # 是一个  # 视盘  # 值为  # 可选  # palm  # paddlepaddle  # ai  # 对象  # float32  # class  # int  # bool  # 浮点型  # Float  # 数据类型  # red  # cos  # 百度 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化91478 】 【 技术知识72672 】 【 云计算0 】 【 GEO优化84317 】 【 优选文章0 】 【 营销推广36048 】 【 网络运营41350 】 【 案例网站102563 】 【 AI智能45237


相关推荐: 文心一言辅助学习方法 解决难题与知识点梳理使用指南  扣子AI能否连接企业微信_扣子AI企业微信对接与接口配置【攻略】  Google AI Studio:免费AI视频生成器使用指南  AI辅助儿童圣经课程创作:轻松制作教育视频  AI Notebooks: 知识工作者的未来?赋能理解与洞察的工具  百度AI助手聊天入口 文心一言对话窗口入口  GitHub Copilot CLI:终端中的 AI 编码助手  SteosVoice:电报语音克隆终极教程  如何使用 DeepSeek API 构建低成本智能应用  颠覆认知!《小丑回魂》幕后:用爆笑台词颠覆你的恐怖想象  超频爱好者盛宴:液氮超频Xeon 28核处理器  通义千问怎么用_通义千问使用方法详细指南【教程】  Thesis AI:一键生成高质量学术论文的秘密武器  如何用AI帮你制定个人OKR?目标管理从未如此简单  批改网ai检测工具如何导出检测报告_批改网ai检测工具报告导出格式【步骤】  AI驱动KDP封面设计:NURIE CREATOR教程  Google Gemini 处理结构化 XML 数据转换教程  AI海报设计终极指南:用ChatGPT和ImageFX轻松创建专业级海报  斑马AI怎样调整语音播报速度_斑马AI语速设置与发音风格选择【攻略】  HelloData.ai:AI驱动的多户型房地产市场分析平台  Claude怎样写指令型提示词_Claude指令提示词写法【方法】  LeetCode问题解析:移除回文子序列,掌握字符串技巧  Foocus:免费AI图像生成器终极指南及 OnlyFans 替代方案  百度ai助手悬浮球怎么关 百度ai助手悬浮窗去除方法  Semrush Summary Generator: 高效总结长篇文章的终极指南  GitHub Copilot终极指南:提升代码效率与质量  Motion 教程:AI 驱动的智能日程安排,提高工作效率  律师视角下的生成式AI:信息爆炸时代的法律实践与未来展望  如何用AI帮你创建自定义表情符号(Emoji)?聊天斗图更有趣  免费涨粉秘籍:Instagram快速提升技巧,告别粉丝流失  智能合约简明教程:概念、应用与未来趋势  EdrawMax全面评测:使用AI轻松绘制流程图和思维导图  TRX40主板终极对决:3990X散热性能深度评测  ChatGPT图像生成器完全指南:文化影响、伦理挑战与商业变革  可灵ai怎么生成招聘JD文案_可灵aiJD生成要素与岗位描述优化【技巧】  提升Fortnite OG游戏性能:NVIDIA控制面板最佳设置  找不到百度AI助手入口 最新官网登录入口  通义千问网页版怎么用模板_通义千问模板使用方法【方法】  雷小兔ai智能写作如何生成日记_雷小兔ai智能写作日记模板调用【步骤】  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  AI员工工具详解:添加与移除指南,提升效率  AI如何一键生成PPT大纲_利用AI工具制作演示文稿方法【教程】  AI学习秘籍:3个高效黑科技,解锁智能学习新时代  Napkin AI:AI驱动的文本可视化工具,轻松创建思维导图  Motion:革新项目管理的智能日历解决方案  AI同伴的未来:超越工具,迈向情感连接与个人成长  百度AI助手入口在哪 怎么找到聊天入口  v0 Report深度测评:AI文档生成器的优缺点分析与实用指南  打破传统,拥抱幸福:公主如何找到真我?  TechInternPath.ai:AI驱动的实习之路,助你梦想成真 

 2025-07-29

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

南京市珐之弘网络技术有限公司


南京市珐之弘网络技术有限公司

南京市珐之弘网络技术有限公司专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

 87067657

 13565296790

 87067657@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.