医疗图像切割日记 01 - 用nnUNet做Fatal Head Segmentation Challenge

本文主要是介绍医疗图像切割日记 01 - 用nnUNet做Fatal Head Segmentation Challenge,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1. nnUNet 介绍

1.1 nnUNet 特点

2. 准备工作

2.1 整理数据格式 - 用自己的数据集

2.2 设置路径

2.3 nnUNet预处理数据

3. 训练

3.1 训练代码

​编辑​编辑

3.2 训练结果

3.2.1 骰子系数 - 最差结果 - Worst Cases​编辑​编辑

3.2.2 骰子系数 - 最优结果 - Best Cases​编辑​编辑模型分析

4. 优化

4.1 数据预处理

4.2 优化结果 - 图片

4.2.1 骰子系数 - 最差结果 - Worst Cases​编辑​编辑

4.2.2 骰子系数 - 最优结果 - Best Cases​编辑​编辑

4.3 优化结果 - 数字

4.3.1 骰子

4.3.2 豪斯多夫

4.3.3 周长误差 (Circumference Error in mm)

5. 模型分析

5.1 索伦森-骰子系数 (Dice Distance)

5.2 豪斯多夫距离 (Hausdorff Distance) 

5.3 代码实现

6. 总结

总结(节俭版)


发的第一篇文,有很多要改进的地方。求各路大神多多指引
费时5天完成的一个Segmentation挑战,之前没有做过segmentation所以走了一点点弯路

nnUNet的github链接 - GitHub - MIC-DKFZ/nnUNet
nnUNet的文章链接- -nnU-Net: a self-configuring method for deep learning-based biomedical image segmentation | Nature Methods
Fatal Head Segmentation Challenge的链接 - Home - Grand Challenge 

*部分代码非原创,会标注出处以及链接*


1. nnUNet 介绍

nnUNet是一款可以自己调整数据预处理,模型架构,训练,和后处理的深度学习医疗图片分割模型。在没有人工调参的情况下,nnUNet 在23个图形切割挑战上得到了最优的分数/前沿的效果。作者把nnUNet开源,让更多人,不论背景,都能轻松的接触到医疗图形切割的领域。

1.1 nnUNet 特点

  • 衡量标准:nnUNet 在很多数据集都达到了最优的结果。作者表示nnUNet可以算是行业标杆,让其他用户的模型和nnUNet做准确率比对。(咱也不敢问,咱也不敢说,大佬说什么都对)
  • 开箱即食:nnUNet 是第一个“开箱即食”的先进图像分割系统。没有segmentation经验的用户也可以(相对)流畅的使用nnUNet来做图像分割的任务。
  • 框架:nnUNet的模块化框架可以让用户替换/优化部分,可以有效的看到自己优化的效果。

2. 准备工作

2.1 整理数据格式 - 用自己的数据集

nnUNet 对数据的格式要求比较高,是根据Medical Segmentation Decathlon (MSD)的格式。

nnUNet_raw_data_base/nnUNet_raw_data/
├── Task001_BrainTumour
├── Task002_Heart
├── Task003_Liver
├── Task004_Hippocampus
├── Task005_Prostate
├── ...~/Task001_BrainTumour/
├── dataset.json
├── imagesTr
├── (imagesTs)
└── labelsTr

详细转换方法请借鉴作者 github:nnUNet/dataset_conversion.md at master · MIC-DKFZ/nnUNet · GitHub

2.2 设置路径

nnUNet的初衷是能让每个数据集都能用这个模型跑,所以环境设置很重要!我是在colab上面跑的,如果要本地跑的话需要修改。这里有三个环境设置:

  • Raw database - 源数据路径
  • Preprocessed - 处理后的数据路径
  • Results Folder - 结果储存路径
os.environ['nnUNet_raw_data_base'] = "content/raw_data_base"
os.environ['nnUNet_preprocessed'] = "content/raw_data_base/nnUNet_preprocessed"
os.environ["RESULTS_FOLDER"] = "content/raw_data_base/results"

2.3 nnUNet预处理数据

在训练nnUNet之前需要用他们的代码预处理一下数据,代码如下:

nnUNet_plan_and_preprocess -t XXX --verify_dataset_integrity

这里nnUNet_plan_and_preprocess是命令,XXX是自定义的任务编号,建议设置在500+以防和现有模型冲突。如果这代码跑出来没问题就可以开始训练了。

3. 训练

3.1 训练代码

!nnUNet_train 2d nnUNetTrainerV2 555 0
!nnUNet_train 2d nnUNetTrainerV2 555 1
!nnUNet_train 2d nnUNetTrainerV2 555 2
!nnUNet_train 2d nnUNetTrainerV2 555 3
!nnUNet_train 2d nnUNetTrainerV2 555 4
#nnUNet_train 命令
#2d 跑2d nnUNet
#nnUNetTrainerV2 基础nnUNet
#555 任务编号
#0/1/2/3/4 多重编号
#!nnUNet_train 2d nnUNetTrainerV2 555 4 -c 
#Add -c to continue train from the last check point

3.2 训练结果

3.2.1 骰子系数 - 最差结果 - Worst Cases

3.2.2 骰子系数 - 最优结果 - Best Cases


模型分析

第一次跑出来的结果差强人意,并没有想象中能圈出预测的范围。绝大部分的预判结果都不是一个圈。大概想了一下导致这个的的原因,因为模型读到的mask是一个圈,他不会去学习圈圈中间的内容,只会去预判那个圈。这个方法的缺点就是在模型不确定的时候会不预判任何东西,导致我们不知道哪里出了问题。

4. 优化

4.1 数据预处理

这里数据做一个简单的数据增强,就是把这个圈圈填上。
*在自己处理的时候遇到了一些小问题所以联系了nnUNet的作者,Fabian在3天内就把图像预处理的代码做出来发布在github上了(发的时候bug已解决)*
Fabian 提供的官方代码链接:nnUNet/Task218_HC18.py at master · MIC-DKFZ/nnUNet · GitHub


4.2 优化结果 - 图片

填完之后再跑一次数据格式处理,如何再训练一次。得到的结果如下。

4.2.1 骰子系数 - 最差结果 - Worst Cases


4.2.2 骰子系数 - 最优结果 - Best Cases

4.3 优化结果 - 数字

4.3.1 骰子

The 7 cases with the worst results are:
023_2HC.png - 0.34406
022_2HC.png - 0.55531
024_HC.png - 0.59306
031_HC.png - 0.63960
009_HC.png - 0.65774
094_HC.png - 0.65859
007_HC.png - 0.74304
032_2HC.png - 0.75615
====================================
The 7 cases with the best results are:
037_HC.png - 0.98398
080_HC.png - 0.98411
054_HC.png - 0.98487
039_HC.png - 0.98496
061_HC.png - 0.98595
068_HC.png - 0.98621
072_HC.png - 0.98723
040_HC.png - 0.98864
The model achieved an average accuracy score of: 0.9255711501147182
The highest Accuracy in the batch: 0.9886378848728247
The lowest Accuracy in the batch: 0.34406099681349833

4.3.2 豪斯多夫

The 7 cases with the worst results are:
052_HC.png - 53.00000
002_HC.png - 73.23933
032_2HC.png - 96.89685
046_HC.png - 151.71355
012_HC.png - 229.80426
083_2HC.png - 279.57111
023_2HC.png - 351.10254
094_HC.png - 434.88504
====================================
The 7 cases with the best results are:
037_HC.png - 0.00000
011_HC.png - 1.00000
048_HC.png - 1.00000
054_HC.png - 1.00000
066_2HC.png - 1.00000
068_HC.png - 1.00000
072_HC.png - 1.00000
076_HC.png - 1.00000
The model achieved an average accuracy score of: 21.673193653752982
The longest Haussdorf Distance in the batch: 434.8850402832031
The shortest Haussdorf Distance in the batch: 0.0

4.3.3 周长误差 (Circumference Error in mm)

周长误差是算基准周长和预判结果的周长差距(单位为mm)

The average error in mm is: 11.292108091481538
The file set with the maximum error is: 083_2HC.png, with an error of 84.41819 mm
The file set with the minimum error is: 006_HC.png, with an error of 0.18754 mm

计算下来,平均误差是11.29mm
测试集中,最大的误差是84.42mm
测试集中,最小的误差是0.19mm

5. 模型分析

5.1 索伦森-骰子系数 (Dice Distance)

Dice = \frac{2|X \cap Y|}{|X|+|Y|}
筛子系数是2乘以模型结果和基准的结合除以两个图片的像素总值
IoU = \frac{2|X \cap Y|}{X \cup Y}
两个公式是正相关的,比如如果模型A的骰子系数比模型B的骰子系数高,这么模型A的IoU系数比也会比模型B的IoU系数高

5.2 豪斯多夫距离 (Hausdorff Distance) 

豪斯多夫距离是在度量空间中任意两个集合之间定义的一种距离。 设X和Y是度量空间M的两个真子集,那么豪斯多夫距离dH(X,Y)是最小的数r使得X的闭r—邻域包含Y,Y的闭r—邻域也包含X

 -这段来于百度百科


5.3 代码实现

def get_Dice_list(resList, predPath, gtPath):for file in os.listdir(predPath):path = predPath + fileif os.path.isfile(path):predicted = predPath + filegroundTruth = gtPath + fileacc = diceScore(predicted, groundTruth)resList.append(acc)else:passreturn(resList)
def get_Haussdorf_list(listHaussdorf, predPath, gtPath):
"""
Calculate the Haussdorf distance between the results and the ground truthand returning them in a list.
list listHaussdorf - Haussdorf result list
str gtPath - Path to the ground truth masks
str predPath - Path to the predicted masks计算模型跑出来的结果和基准的Haussdorf值,返回一个数值列表
list listHaussdorf - Haussdorf 结果列表
str gtPath - 基准路径
str predPath - 预测结果路径
"""for file in os.listdir(predPath): #Iterate through Result Path path = gtPath + fileif os.path.isfile(path): predicted = predPath + filegroundTruth = gtPath + file# 1.Import the Photos# 1.导入图片img_cs1 = cv2.imread(predicted)img_cs2 = cv2.imread(groundTruth)# 2.Get the contours of both images# 2.获取图片连通域try:cnt_cs1 = get_contours(img_cs1)cnt_cs2 = get_contours(img_cs2)hausdorff_sd = cv2.createHausdorffDistanceExtractor()# 3.Calculate the distance between the contours# 3.计算轮廓之间的距离d3 = hausdorff_sd.computeDistance(cnt_cs2, cnt_cs1)listHaussdorf.append(d3)except IndexError:listHaussdorf.append(999999) return listHaussdorfdef get_contours(img):"""Get contours of the imageimg: Image generated from the model and ground truthReturns image of contour获取连通域:param img: 输入图片:return: 最大连通域"""img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Grayscale 灰度化ret, img_bin = cv2.threshold(img_gray, 200, 255, cv2.THRESH_BINARY)# Binary and set threshold 二值化, 连通域分析contours, hierarchy = cv2.findContours(img_bin, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)return contours[0]#The contour calculation code is adapted from https://www.pythonf.cn/read/57691
#连通区域计算代码来源于: https://www.pythonf.cn/read/57691


6. 总结

nnUNet是一个非常容易调用的深度学习模型,很多初学者可以拿他入手做一些有趣的项目。例如肿瘤检测: Task 029 - nnUNet/Task029_LiverTumorSegmentationChallenge.py at master · MIC-DKFZ/nnUNet · GitHub,马路检测: Task 120 - MassGIS Data: Massachusetts Department of Transportation (MassDOT) Roads | Mass.gov

总结(节俭版)

Fabian nb
 


资源整理
nnUNet 代码GitHub - MIC-DKFZ/nnUNet
nnUNet 文献nnU-Net: a self-configuring method for deep learning-based biomedical image segmentation | Nature Methods
Fatal Head Segmentation 链接Home - Grand Challenge
数据链接Automated measurement of fetal head circumference using 2D ultrasound images | Zenodo
豪斯多夫 - 代码Python+opencv2(I)豪斯多夫距离,PythonOpencv2,一,Hausdorff
推荐nnUNet文章(四:2020.07.28)nnUNet最舒服的训练教程(让我的奶奶也会用nnUNet(上))(21.04.20更新)_花卷汤圆的博客-CSDN博客_nnunet
Colab 代码链接


×注-Colab当时写的有点急促,这一段忙完了会加备注后发布,如果需要跑的话欢迎私信。也欢迎各路大佬评论留言多提建议!谢谢~

这篇关于医疗图像切割日记 01 - 用nnUNet做Fatal Head Segmentation Challenge的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/774634

相关文章

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

集中式版本控制与分布式版本控制——Git 学习笔记01

什么是版本控制 如果你用 Microsoft Word 写过东西,那你八成会有这样的经历: 想删除一段文字,又怕将来这段文字有用,怎么办呢?有一个办法,先把当前文件“另存为”一个文件,然后继续改,改到某个程度,再“另存为”一个文件。就这样改着、存着……最后你的 Word 文档变成了这样: 过了几天,你想找回被删除的文字,但是已经记不清保存在哪个文件了,只能挨个去找。真麻烦,眼睛都花了。看

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采

01 Docker概念和部署

目录 1.1 Docker 概述 1.1.1 Docker 的优势 1.1.2 镜像 1.1.3 容器 1.1.4 仓库 1.2 安装 Docker 1.2.1 配置和安装依赖环境 1.3镜像操作 1.3.1 搜索镜像 1.3.2 获取镜像 1.3.3 查看镜像 1.3.4 给镜像重命名 1.3.5 存储,载入镜像和删除镜像 1.4 Doecker容器操作 1.4

跟我一起玩《linux内核设计的艺术》第1章(四)——from setup.s to head.s,这回一定让main滚出来!(已解封)

看到书上1.3的大标题,以为马上就要见着main了,其实啊,还早着呢,光看setup.s和head.s的代码量就知道,跟bootsect.s没有可比性,真多……这确实需要包括我在内的大家多一些耐心,相信见着main后,大家的信心和干劲会上一个台阶,加油! 既然上篇已经玩转gdb,接下来的讲解肯定是边调试边分析书上的内容,纯理论讲解其实我并不在行。 setup.s: 目标:争取把setup.

【python计算机视觉编程——7.图像搜索】

python计算机视觉编程——7.图像搜索 7.图像搜索7.1 基于内容的图像检索(CBIR)从文本挖掘中获取灵感——矢量空间模型(BOW表示模型)7.2 视觉单词**思想****特征提取**: 创建词汇7.3 图像索引7.3.1 建立数据库7.3.2 添加图像 7.4 在数据库中搜索图像7.4.1 利用索引获取获选图像7.4.2 用一幅图像进行查询7.4.3 确定对比基准并绘制结果 7.

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法(KNN)8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特征8.4.3 多类支持向量机8.4.4 提取单元格并识别字符8.4.5 图像校正

HalconDotNet中的图像特征与提取详解

文章目录 简介一、边缘特征提取二、角点特征提取三、区域特征提取四、纹理特征提取五、形状特征提取 简介   图像特征提取是图像处理中的一个重要步骤,用于从图像中提取有意义的特征,以便进行进一步的分析和处理。HalconDotNet提供了多种图像特征提取方法,每种方法都有其特定的应用场景和优缺点。 一、边缘特征提取   边缘特征提取是图像处理中最基本的特征提取方法之一,通过检

src/pyaudio/device_api.c:9:10: fatal error: portaudio.h: 没有那个文件或目录

(venv) shgbitai@shgbitai-C9X299-PGF:~/pythonworkspace/ai-accompany$ pip install pyaudio sounddeviceCollecting pyaudioDownloading PyAudio-0.2.14.tar.gz (47 kB)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━