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

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

比赛地址: https://aistudio.baidu.com/aistudio/competition/detail/85

AI Studio地址: https://aistudio.baidu.com/aistudio/personalcenter/thirdview/725102

一、赛题介绍

1. 赛题简介

常规赛简介

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

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

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

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


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

2.比赛任务

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

3.数据集

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

训练数据集

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

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

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

测试数据集

文件名称:PALM-Testing400-Images

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

(一)解压数据

!unzip -o data/data86770/seg.zip -d /home/aistudio/work

(二)克隆Paddleseg

!git clone https://gitee.com/PaddlePaddle/PaddleSeg

(三)生成train.txt 和val.txt 按8:2 的比例划分数据集

import random
import os
random.seed(2020)
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.8
train_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()

(四)开始训练

模型使用Unet 预训练权重放在 /home/aistudio/unetmodel.pdparams,Loss用DiceLoss()和CrossEntropyLoss()两个损失函数,混合使用

loss:
  types:
    - type: MixedLoss
      losses:
        - type: CrossEntropyLoss
        - type: DiceLoss
      coef: [0.7, 0.3]
  coef: [1]

model:
  type: UNet
  num_classes: 2
  use_deconv: False
  pretrained: /home/aistudio/unetmodel.pdparams

%cd /home/aistudio/PaddleSeg
!python train.py \
       --config configs/Unet.yml \
       --do_eval \
       --use_vdl \
       --save_interval 450 \        #每隔450保存一次
       --save_dir output_Unet       #模型保存在output_Unet

(五)验证

!python val.py --config configs/Unet.yml  --model_path output_Unet/best_model/model.pdparams 

(六)预测

!python predict.py \
       --config configs/Unet.yml \
       --model_path output_Unet/best_model/model.pdparams \
       --image_path /home/aistudio/work/seg/test \
       --save_dir output_Unett/result

(七)生成结果

import os 
import cv2
result_path = '/home/aistudio/PaddleSeg/outputUnet/result/pseudo_color_prediction'
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, result = cv2.threshold(g, 127,255, cv2.THRESH_BINARY_INV)
    cv2.imwrite(os.path.join(dist_path,img_name), result)

先用Unet进行分割。对预测结果进行处理。假如某一张图片预测的结果出现多个不连通的区域,通过面积筛选,只保留最大的面积。
import os 
import cv2
import matplotlib.pyplot as plt
def cnt_area(cnt):
    area = cv2.contourArea(cnt)
    return area

result_path = '/home/aistudio/PaddleSeg/output_Unet/result/pseudo_color_prediction'
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)

(八)总结

1.可以尝试其他模型

2.更充分的调整超参数

我在AI Studio上获得黄金等级,点亮7个徽章,来互关呀~ https://aistudio.baidu.com/aistudio/personalcenter/thirdview/725102

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值