医学图像分割实操

整个实验过程包括:

1、数据集获取:https://zenodo.org/record/3757476

2、数据预处理:从.nii文件中提取包含目标区域的切片,如果不是很清楚医学图像格式的处理,也可以将.nii文件转换成png格式的图片,.nii代码转png图片代码:

import nibabel as nib
import numpy as np
import imageio
import os
def makedir(path):if os.path.exists(path):passelse:os.mkdir(path)def read_niifile(niifile):  # 读取niifile文件img = nib.load(niifile)  # 下载niifile文件(其实是提取文件)img_fdata = img.get_fdata()  # 获取niifile数据return img_fdatadef save_fig(file,savepicdir,name):  # 保存为图片fdata = read_niifile(file)  # 调用上面的函数,获得数据# (x, y, z) = fdata.shape  # 获得数据shape信息:(长,宽,维度-切片数量)# for k in range(z):silce = fdata[:, :, i]  # 三个位置表示三个不同角度的切片imageio.imwrite(os.path.join(savepicdir, '{}.png'.format(name)), silce)# 将切片信息保存为png格式
def getName(na):for i in range(0,len(na)):if na[i]=='_':return na[:i]
#传入nii.gz文件所在文件夹
niiGzFolder='/.nii文件夹路径/'
niiGzNames=os.listdir(niiGzFolder)
#存放解压后的分割图片
target='/存放png图片的路径/'
for i in range(0,len(niiGzNames)):niiGzName=niiGzNames[i]name=getName(niiGzName)pred="pred"gt="gt"img="img"if  pred in niiGzName:path=target+pred+'/'if gt in niiGzName:path=target+gt+'/'if img in niiGzName:path=target+img+'/'makedir(path)save_fig(niiGzFolder+niiGzName,path,name)print("finish",niiGzName)

3、导入自己的数据集,写自己的dataloder,不妨命名为dataset.py,代码如下:

import torch
import cv2
import os
import glob
from torch.utils.data import Dataset
import randomclass Loader(Dataset):def __init__(self, data_path):# print(data_path)images = []image_root = os.path.join(data_path,'images')# print(image_root)for image_name in os.listdir(image_root):image_path = os.path.join(image_root, image_name)images.append(image_path)# 初始化函数,读取所有data_path下的图片self.data_path = data_pathself.imgs_path = imagesdef augment(self, image, flipCode):# 使用cv2.flip进行数据增强,filpCode为1水平翻转,0垂直翻转,-1水平+垂直翻转flip = cv2.flip(image, flipCode)return flipdef __getitem__(self, index):# 根据index读取图片image_path = self.imgs_path[index]# 根据image_path生成label_pathlabel_path = image_path.replace('images', 'labels')# 读取训练图片和标签图片image = cv2.imread(image_path)label = cv2.imread(label_path)# 将数据转为单通道的图片image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)label = cv2.cvtColor(label, cv2.COLOR_BGR2GRAY)image = image.reshape(1, image.shape[0], image.shape[1])label = label.reshape(1, label.shape[0], label.shape[1])# 处理标签,将像素值为255的改为1if label.max() > 1:label = label / 255# 随机进行数据增强,为2时不做处理flipCode = random.choice([-1, 0, 1, 2])if flipCode != 2:image = self.augment(image, flipCode)label = self.augment(label, flipCode)return image, labeldef __len__(self):# 返回训练集大小return len(self.imgs_path)if __name__ == "__main__":path='../data/train/'isbi_dataset = Loader(path)print("数据个数:", len(isbi_dataset))train_loader = torch.utils.data.DataLoader(dataset=isbi_dataset,batch_size=2,shuffle=True)for image, label in train_loader:print(image.shape)

4、搭建模型,我采用的是U-Net网络,模型包括两个.py文件,unet_model.py和unet_pert.py,训练的时候将这个两个文件放在同一个文件夹,可以叫model

#unet_model.py
import torch.nn.functional as Ffrom .unet_parts import *class UNet(nn.Module):def __init__(self, n_channels, n_classes, bilinear=True):super(UNet, self).__init__()self.n_channels = n_channelsself.n_classes = n_classesself.bilinear = bilinearself.inc = DoubleConv(n_channels, 64)self.down1 = Down(64, 128)self.down2 = Down(128, 256)self.down3 = Down(256, 512)self.down4 = Down(512, 512)self.up1 = Up(1024, 256, bilinear)self.up2 = Up(512, 128, bilinear)self.up3 = Up(256, 64, bilinear)self.up4 = Up(128, 64, bilinear)self.outc = OutConv(64, n_classes)def forward(self, x):x1 = self.inc(x)x2 = self.down1(x1)x3 = self.down2(x2)x4 = self.down3(x3)x5 = self.down4(x4)x = self.up1(x5, x4)x = self.up2(x, x3)x = self.up3(x, x2)x = self.up4(x, x1)logits = self.outc(x)return logitsif __name__ == '__main__':net = UNet(n_channels=3, n_classes=1)print(net)
# unet_part
import torch
import torch.nn as nn
import torch.nn.functional as Fclass DoubleConv(nn.Module):"""(convolution => [BN] => ReLU) * 2"""def __init__(self, in_channels, out_channels):super().__init__()self.double_conv = nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),nn.BatchNorm2d(out_channels),nn.ReLU(inplace=True),nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),nn.BatchNorm2d(out_channels),nn.ReLU(inplace=True))def forward(self, x):return self.double_conv(x)class Down(nn.Module):"""Downscaling with maxpool then double conv"""def __init__(self, in_channels, out_channels):super().__init__()self.maxpool_conv = nn.Sequential(nn.MaxPool2d(2),DoubleConv(in_channels, out_channels))def forward(self, x):return self.maxpool_conv(x)class Up(nn.Module):"""Upscaling then double conv"""def __init__(self, in_channels, out_channels, bilinear=True):super().__init__()# if bilinear, use the normal convolutions to reduce the number of channelsif bilinear:self.up = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)else:self.up = nn.ConvTranspose2d(in_channels // 2, in_channels // 2, kernel_size=2, stride=2)self.conv = DoubleConv(in_channels, out_channels)def forward(self, x1, x2):x1 = self.up(x1)# input is CHWdiffY = torch.tensor([x2.size()[2] - x1.size()[2]])diffX = torch.tensor([x2.size()[3] - x1.size()[3]])x1 = F.pad(x1, [diffX // 2, diffX - diffX // 2,diffY // 2, diffY - diffY // 2])x = torch.cat([x2, x1], dim=1)return self.conv(x)class OutConv(nn.Module):def __init__(self, in_channels, out_channels):super(OutConv, self).__init__()self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=1)def forward(self, x):return self.conv(x)

5、开始训练模型,训练模型我们用train.py文件:

from Unet.model.unet_model import UNet
from Unet.utils.dataset2 import ISBI_Loader
from torch import optim
import torch.nn as nn
import torchdef train_net(net, device, data_path, epochs=40, batch_size=4, lr=0.00001):# 加载训练集isbi_dataset = Loader(data_path)train_loader = torch.utils.data.DataLoader(dataset=isbi_dataset,batch_size=batch_size,shuffle=False)# 定义RMSprop算法optimizer = optim.RMSprop(net.parameters(), lr=lr, weight_decay=1e-8, momentum=0.9)# 定义Loss算法criterion = nn.BCEWithLogitsLoss()# best_loss统计,初始化为正无穷best_loss = float('inf')# 训练epochs次for epoch in range(epochs):# 训练模式net.train()# 按照batch_size开始训练for image, label in train_loader:optimizer.zero_grad()# 将数据拷贝到device中image = image.to(device=device, dtype=torch.float32)label = label.to(device=device, dtype=torch.float32)# 使用网络参数,输出预测结果pred = net(image)# 计算lossloss = criterion(pred, label)print('Loss/train', loss.item())# 保存loss值最小的网络参数if loss < best_loss:best_loss = losstorch.save(net.state_dict(), 'best_model.pth')# 更新参数loss.backward()optimizer.step()if __name__ == "__main__":# 选择设备,有cuda用cuda,没有就用cpudevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 加载网络,图片单通道1,分类为1。net = UNet(n_channels=1, n_classes=3)# 将网络拷贝到deivce中net.to(device=device)# 指定训练集地址,开始训练data_path = "data/train/"train_net(net, device, data_path)

6、测试模型test.py文件:

import glob
import numpy as np
import torch
import os
import cv2
from unet_model import UNetif __name__ == "__main__":# 选择设备,有cuda用cuda,没有就用cpudevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 加载网络,图片单通道,分类为1。net = UNet(n_channels=1, n_classes=1)# 将网络拷贝到deivce中net.to(device=device)# 加载模型参数net.load_state_dict(torch.load('best_model.pth', map_location=device))# 测试模式net.eval()# 读取所有图片路径tests_path = glob.glob('data/test/*.png')# 遍历所有图片for test_path in tests_path:# 保存结果地址save_res_path = test_path.split('.')[0] + '_res.png'# 读取图片img = cv2.imread(test_path)# 转为灰度图img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)# 转为batch为1,通道为1,大小为512*512的数组img = img.reshape(1, 1, img.shape[0], img.shape[1])# 转为tensorimg_tensor = torch.from_numpy(img)# 将tensor拷贝到device中,只用cpu就是拷贝到cpu中,用cuda就是拷贝到cuda中。img_tensor = img_tensor.to(device=device, dtype=torch.float32)# 预测pred = net(img_tensor)# 提取结果pred = np.array(pred.data.cpu()[0])[0]# 处理结果pred[pred >= 0.5] = 255pred[pred < 0.5] = 0# 保存图片cv2.imwrite(save_res_path, pred)

7、最后的文件目录为,应按要求存放文件,以免出现路径错误、导包错误:

文件目录

8、测试结果:

(a)、(b)、(c)、(d)为不同的测试像本,每一列由上到下分别代表原图像、真实标签(GT)和预测分割结果,其中蓝色箭头指向的地方表示预测结果与真实标签的差异

参考链接:Pytorch深度学习实战教程(三):UNet模型训练,深度解析! - 知乎 (zhihu.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/48338.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【医学图像】图像分割系列.3 (uncertainty)

介绍几篇使用不确定性引导的医学图像分割论文&#xff1a;UA-MT&#xff08;MICCAI2019&#xff09;&#xff0c;SSL4MIS&#xff08;MICCAI2021&#xff09;&#xff0c;UG-MCL&#xff08;AIIM2022&#xff09;. Uncertainty-aware Self-ensembling Model for Semi-supervise…

医学图像分割文章阅读笔记

1、Detection-aided liver lesion segmentation using deep learning 2、Automatic Liver and Tumor Segmentation of CT and MRI Volumes Using Cascaded Fully Convolutional Neural Networks https://github.com/IBBM/Cascaded-FCN 一、Method 第一步:数据预处理和神经网…

医学图像笔记(四)医学图像分割

医学图像笔记&#xff08;四&#xff09;医学图像分割 1、医学图像分割的开源工具2、其他分割2.1、3D VNet2.2、PE-VNet2.3、基于PyTorch的3D 医学图像分割2.4、3D UX-Net&#xff1a;超强的医学图像分割新网络2.5、医学图像分割优质开源代码 3、医学图像数据集3.1、百度AI stu…

UniverSeg:通用医学图像分割模型来了!

自从今年以来ChatGPT爆火和GPT-4的发布&#xff0c;一时间在大模型的潮流下&#xff0c;通用人工智能&#xff08;AGI&#xff09;也呼之欲出。随着本月初SAM和SegGPT等通用的CV大模型的提出&#xff0c;大模型和通用模型这把火也逐渐烧到的CV领域&#xff0c;特别是图像分割领…

[转]医学图像分割综述

原作者&#xff1a; Zeynettin Akkus & Alfiia Galimzianova & Assaf Hoogi & Daniel L. Rubin & Bradley J. Erickson 时间&#xff1a;2017 csdn作者链接&#xff1a; https://blog.csdn.net/xy9476/article/details/80587151 (转载为收藏) Abstract 这篇综…

最新《医学图像分割》综述,详述六大类100多个算法

来源&#xff1a;专知 医学图像自动分割是医学领域的一个重要课题&#xff0c;也是计算机辅助诊断领域的一个重要分支。U-Net由于其灵活性、优化的模块化设计和在所有医学图像模式中的成功&#xff0c;是最广泛应用的图像分割体系结构。多年来&#xff0c;U-Net模式获得了学术界…

通用医学图像分割模型UniverSeg

虽然深度学习模型已经成为医学图像分割的主要方法&#xff0c;但它们通常无法推广到涉及新解剖结构、图像模态或标签的unseen分割任务。给定一个新的分割任务&#xff0c;研究人员通常必须训练或微调模型&#xff0c;这很耗时&#xff0c;并对临床研究人员构成了巨大障碍&#…

Unet分割医学图像全记录/结果全白解决办法/多分类Dice loss

文章目录 任务介绍数据来源及预处理Unet实现过程中遇到的bug 任务介绍 本项目是基于Unet网络对心肌图像进行心池和心肌分割。写这篇博客为了记录下我在写模型时遇到的bug和思考&#xff0c;我发现好像没有一篇从头到尾的笔记&#xff0c;我作为小白真的遇到了很多大坑&#xf…

【医学图像】图像分割系列.4

介绍几篇使用Transformer结构做医学图像分割的论文&#xff1a;CASTformer&#xff08;NeuralPS2022&#xff09;&#xff0c;PHNet&#xff08;arXiv2023&#xff09;。 Class-Aware Adversarial Transformers for Medical Image Segmentation, NeuralPS2022 解读&#xff1a…

医学图像分割实战——使用U-Net实现肾脏CT分割

使用U-Net实现肾脏CT分割 数据集准备数据来源数据预处理 网络结构及代码网络结构训练代码 训练过程参数设置&#xff1a;可视化 结果分析 数据集准备 数据来源 MICCAI KiTS19(Kidney Tumor Segmentation Challenge)&#xff1a;https://kits19.grand-challenge.org/ KiTS201…

医学图像分割之 Dice Loss

文章目录 医学图像分割之 Dice Loss1. Dice coefficient 定义1.1. Dice 系数计算示例1.2. Dice-coefficient loss function vs cross-entropy 2. Dice 系数的 Pytorch 实现2.1. Dice 系数2.2. Dice Loss2.3. BCELoss2d 3. Dice 系数的 Keras 实现4. Dice 系数的 TensorFlow 实现…

医学图像分割常见评价指标(单目标)——包含源码讲解和指标缺陷

单目标分割常见评价指标 1 知道4个常见指标&#xff0c;TP&#xff0c;TN&#xff0c;FP&#xff0c;FN2 评价分割区域准确率2.1 Recall Sensitivity TPR(True Positive Rate)2.2 Specificity (True Negative Rate)2.3 Precision (PPV&#xff0c; 精确率)2.4 Dice Coefficient…

医学图像分割之Attention U-Net

目录 一、背景 二、问题 三、解决问题 四、Attention U-Net网络结构 简单总结Attention U-Net的操作&#xff1a;增强目标区域的特征值&#xff0c;抑制背景区域的目标值。抑制也就是设为了0。 一、背景 为了捕获到足够大的、可接受的范围和语义上下文信息&#xff0c;在标…

常用的医学图像分割评价指标

常用的图像分割评价指标非常多&#xff0c;论文中常用的指标包括像素准确率&#xff0c;交并比&#xff08;IOU&#xff09;,Dice系数&#xff0c;豪斯多夫距离&#xff0c;体积相关误差。 下面提到的所有案例都是二分类&#xff0c;标签中只有0和1 目录 一&#xff1a;像素…

医学图像分割评判标准及程序代码

文章目录 1.图像分割指标2. 两个问题3.IOU和假阳性率4. 准确率(Accuracy), 精确率(Precision), 召回率(Recall)和F1-Measure 参考资源&#xff1a; 1.https://blog.csdn.net/zichen_ziqi/article/details/80408465 2.https://blog.csdn.net/HXG2006/article/details/79649154 …

基于Android studio开发的图灵智能聊天机器人

前言 在人工智能时代&#xff0c;开发一款自己的智能问答机器人&#xff0c;既可以提升自己的编程能力&#xff0c;又可以作为开发项目的实战练习。 百度有小度&#xff0c;小米有小爱&#xff0c;VIVO有小V&#xff0c;总之类似的智能聊天机器人是越来越多了。面对这些智能的机…

短视频矩阵源码开发部署--开原

短视频矩阵源码是一种常见的视频编码标准&#xff0c;它通过将视频分成多个小块并对每个小块进行压缩来实现高效的视频传输。在本文中&#xff0c;我们将介绍短视频矩阵的原理和实现&#xff0c;并提供示例代码。 开发链路解析 短视频矩阵系统源码开发链路包括需求分析、技术…

ChatGPT危了!注意力机制的神秘bug曝光!Transformer模型恐大受冲击...

点击下方卡片&#xff0c;关注“CVer”公众号 AI/CV重磅干货&#xff0c;第一时间送达 点击进入—>【Transformer】微信交流群 转载自&#xff1a;新智元 【导读】「注意力公式」存在8年的bug首现&#xff0c;瞬间引爆舆论。爆料者称&#xff0c;基于Transformer架构打造的模…

短视频抖音seo矩阵源码如何搭建开发?

抖音SEO矩阵源码排名逻辑采用一系列算法进行生成&#xff0c;其中包括用户行为、关键词匹配和内容质量等多维度指标的衡量。首先&#xff0c;用户行为是决定视频排名的主要因素&#xff0c;包括点赞数、评论数、观看时长和转发次数等。其次&#xff0c;关键词匹配也是影响排名的…

chatgpt赋能python:使用Python让照片动起来:一种新颖的SEO方法

使用Python让照片动起来&#xff1a;一种新颖的SEO方法 在当今数字时代&#xff0c;社交媒体已经成为营销策略中不可或缺的一部分。人们越来越喜欢以图像的形式来获取信息。然而&#xff0c;在面对大量的图像时&#xff0c;如何让自己的图片和品牌脱颖而出&#xff1f;答案是&…