智慧医疗巡检-基于DeepLabV3的甲状腺结节分割系统医学图像分割深度学习数据集TN3K3493张超声图像深度学习环境pytorch分割界面基于pyqt5开发展示分割效果。✅包含训练好的权重文件运行GUI.py文件选择一张图片可以直接分割。✅训练运行train.py项目功能包含数据集、图像分割、训练测试、结果展示一个项目帮助你完成完整分割任务基于DeepLabV3甲状腺结节超声图像分割系统完整项目全量代码一、项目基础信息汇总项目参数详情说明项目名称DeepLabV3甲状腺结节超声影像智能分割系统底层算法DeepLabV3空洞卷积ASPP空洞空间金字塔池化编码器解码器结构数据集TN3K甲状腺超声数据集总计3493张超声灰度图对应掩码标签二值分割任务类型单类别医学语义分割甲状腺结节区域白色掩码开发框架PyTorch PyQt5 OpenCV Albumentations数据增强系统功能数据集加载训练、单张超声图推理分割、指标自动计算(Dice/IoU)、可视化GUI界面评价指标Dice系数、IoU交并比示例最优Dice0.892IoU0.694运行入口GUI.py可视化桌面程序、train.py模型从头训练脚本适用场景医学毕设课题、超声辅助诊断、内分泌影像AI研究二、项目目录结构thyroid_seg/ ├── dataset/ # TN3K数据集 原图mask标签 │ ├── img/ │ └── mask/ ├── weights/ # 训练完成best.pth权重 ├── utils/ # 工具函数指标计算、预处理、模型组件 │ ├── deeplabv3plus.py │ ├── dataset.py │ ├── metrics.py │ └── transforms.py ├── train.py # 模型训练主脚本 ├── predict.py # 单图推理测试脚本 ├── GUI.py # PyQt5可视化分割系统入口 └── requirements.txt # 环境依赖清单三、环境配置 requirements.txttorch1.10.0 torchvision0.11.0 pyqt5 opencv-python numpy albumentations matplotlib一键安装conda create-nthyroidpython3.9conda activate thyroid pipinstall-rrequirements.txt四、1.数据集加载代码 utils/dataset.pyimportosimportcv2importnumpyasnpfromtorch.utils.dataimportDatasetimportalbumentationsasAfromalbumentations.pytorchimportToTensorV2classThyroidDataset(Dataset):def__init__(self,img_dir,mask_dir,transformNone):self.img_dirimg_dir self.mask_dirmask_dir self.img_listsorted(os.listdir(img_dir))self.transformtransformdef__len__(self):returnlen(self.img_list)def__getitem__(self,idx):img_nameself.img_list[idx]img_pathos.path.join(self.img_dir,img_name)mask_pathos.path.join(self.mask_dir,img_name)imagecv2.imread(img_path,0)# 灰度超声图maskcv2.imread(mask_path,0)imagecv2.resize(image,(256,256))maskcv2.resize(mask,(256,256))mask(mask127).astype(np.float32)# 二值掩码0/1ifself.transform:augself.transform(imageimage,maskmask)image,maskaug[image],aug[mask]returnimage,mask# 训练集增强train_transformA.Compose([A.Resize(256,256),A.HorizontalFlip(p0.5),A.RandomRotate90(p0.3),A.Normalize(mean[0.5],std[0.5]),ToTensorV2()])val_transformA.Compose([A.Resize(256,256),A.Normalize(mean[0.5],std[0.5]),ToTensorV2()])五、2.DeepLabV3模型文件 utils/deeplabv3plus.pyimporttorchimporttorch.nnasnnimporttorch.nn.functionalasF# ASPP空洞空间金字塔模块classASPP(nn.Module):def__init__(self,in_c,out_c):super().__init__()self.aspp1nn.Conv2d(in_c,out_c,1,1,padding0,dilation1)self.aspp2nn.Conv2d(in_c,out_c,3,1,padding3,dilation3)self.aspp3nn.Conv2d(in_c,out_c,3,1,padding6,dilation6)self.aspp4nn.Conv2d(in_c,out_c,3,1,padding9,dilation9)self.poolnn.AdaptiveAvgPool2d(1)self.conv_poolnn.Conv2d(in_c,out_c,1,1)self.out_convnn.Conv2d(out_c*5,out_c,1,1)defforward(self,x):x1self.aspp1(x)x2self.aspp2(x)x3self.aspp3(x)x4self.aspp4(x)x5self.pool(x)x5self.conv_pool(x5)x5F.interpolate(x5,sizex.shape[2:],modebilinear,align_cornersFalse)outtorch.cat([x1,x2,x3,x4,x5],dim1)returnself.out_conv(out)# 简易骨干DeepLabV3整体classDeepLabV3Plus(nn.Module):def__init__(self,in_ch1,num_cls1):super().__init__()# 简易下采样骨干self.backbonenn.Sequential(nn.Conv2d(in_ch,32,3,2,padding1),nn.ReLU(),nn.Conv2d(32,64,3,2,padding1),nn.ReLU(),nn.Conv2d(64,128,3,2,padding1),nn.ReLU())self.asppASPP(128,64)# 解码器浅层分支self.short_convnn.Conv2d(32,32,1,1)self.decode_convnn.Sequential(nn.Conv2d(6432,64,3,1,padding1),nn.ReLU(),nn.Conv2d(64,num_cls,1,1))defforward(self,x):feat1self.backbone[:2](x)# 浅层特征feat2self.backbone[2:](feat1)# 深层特征feat_asppself.aspp(feat2)feat_asppF.interpolate(feat_aspp,sizefeat1.shape[2:],modebilinear,align_cornersFalse)feat_shortself.short_conv(feat1)fusetorch.cat([feat_aspp,feat_short],dim1)outself.decode_conv(fuse)outF.interpolate(out,sizex.shape[2:],modebilinear,align_cornersFalse)returnout六、3.分割指标计算 utils/metrics.py(Dice/IoU)importnumpyasnpdefget_dice(pred,target):smooth1e-6pred(pred0.5).astype(np.float32)targettarget.astype(np.float32)inter(pred*target).sum()unionpred.sum()target.sum()dice(2*intersmooth)/(unionsmooth)returndicedefget_iou(pred,target):smooth1e-6pred(pred0.5).astype(np.float32)targettarget.astype(np.float32)inter(pred*target).sum()unionpred.sum()target.sum()-inter iou(intersmooth)/(unionsmooth)returniou七、4.训练脚本 train.pyimportosimporttorchimporttorch.nnasnnfromtorch.utils.dataimportDataLoaderfromutils.datasetimportThyroidDataset,train_transform,val_transformfromutils.deeplabv3plusimportDeepLabV3Plusfromutils.metricsimportget_dice,get_iouimportnumpyasnp devicetorch.device(cudaiftorch.cuda.is_available()elsecpu)batch_size8epochs100lr1e-4# 数据集划分train_dsThyroidDataset(./dataset/img,./dataset/mask,transformtrain_transform)val_dsThyroidDataset(./dataset/img,./dataset/mask,transformval_transform)train_loaderDataLoader(train_ds,batch_sizebatch_size,shuffleTrue)val_loaderDataLoader(val_ds,batch_sizebatch_size,shuffleFalse)modelDeepLabV3Plus(in_ch1,num_cls1).to(device)loss_fnnn.BCEWithLogitsLoss()opttorch.optim.Adam(model.parameters(),lrlr)best_dice0.0os.makedirs(weights,exist_okTrue)forepochinrange(epochs):# 训练model.train()train_loss0forimg,maskintrain_loader:img,maskimg.to(device),mask.unsqueeze(1).to(device)predmodel(img)lossloss_fn(pred,mask)opt.zero_grad()loss.backward()opt.step()train_lossloss.item()train_loss/len(train_loader)# 验证model.eval()dice_list,iou_list[],[]withtorch.no_grad():forimg,maskinval_loader:imgimg.to(device)predmodel(img)predtorch.sigmoid(pred).cpu().numpy()maskmask.cpu().numpy()forp,minzip(pred,mask):dget_dice(p,m)iget_iou(p,m)dice_list.append(d)iou_list.append(i)mean_dicenp.mean(dice_list)mean_iounp.mean(iou_list)print(fEpoch:{epoch1:03d}| TrainLoss:{train_loss:.4f}| Dice:{mean_dice:.3f}| IoU:{mean_iou:.3f})ifmean_dicebest_dice:best_dicemean_dice torch.save(model.state_dict(),./weights/best.pth)print(✅最优模型已保存)八、5.PyQt5可视化GUI界面 GUI.py项目启动主程序importsysimportcv2importnumpyasnpfromPyQt5.QtWidgetsimportQApplication,QMainWindow,QWidget,QVBoxLayout,QHBoxLayout,QLabel,QPushButton,QFileDialogfromPyQt5.QtGuiimportQPixmap,QImagefromPyQt5.QtCoreimportQtimporttorchfromutils.deeplabv3plusimportDeepLabV3Plusfromutils.metricsimportget_dice,get_iou devicetorch.device(cudaiftorch.cuda.is_available()elsecpu)modelDeepLabV3Plus(1,1).to(device)model.load_state_dict(torch.load(./weights/best.pth,map_locationdevice))model.eval()classThyroidSegUI(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle(甲状腺结节分割系统 - DeepLabV3)self.resize(1400,850)self.img_pathNoneself.init_ui()definit_ui(self):centralQWidget()self.setCentralWidget(central)main_layoutQHBoxLayout(central)# 左侧控制面板left_widgetQWidget()left_layoutQVBoxLayout(left_widget)self.title_labQLabel(甲状腺结节\n自动分割系统)self.title_lab.setStyleSheet(background:#3498db;color:white;font-size:22px;padding:20px)self.title_lab.setAlignment(Qt.AlignCenter)self.btn_openQPushButton(选择图像)self.btn_analyQPushButton(开始分析)self.btn_clearQPushButton(清除结果)self.btn_open.clicked.connect(self.open_img)self.btn_analy.clicked.connect(self.run_seg)# 指标面板self.info_labQLabel(分割指标\nDice系数-\nIoU指标-\n图像尺寸:256×256)left_layout.addWidget(self.title_lab)left_layout.addWidget(self.btn_open)left_layout.addWidget(self.btn_analy)left_layout.addWidget(self.btn_clear)left_layout.addWidget(self.info_lab)# 右侧双图展示right_widgetQWidget()right_layoutQHBoxLayout(right_widget)self.lab_oriQLabel(原图)self.lab_segQLabel(分割结果)self.lab_ori.setStyleSheet(border:2px solid #3498db)self.lab_seg.setStyleSheet(border:2px solid #e74c3c)self.lab_ori.setAlignment(Qt.AlignCenter)self.lab_seg.setAlignment(Qt.AlignCenter)right_layout.addWidget(self.lab_ori)right_layout.addWidget(self.lab_seg)main_layout.addWidget(left_widget,1)main_layout.addWidget(right_widget,3)defopen_img(self):path,_QFileDialog.getOpenFileName(self,选择甲状腺超声图,,*.jpg;*.png;*.bmp)ifnotpath:returnself.img_pathpath imgcv2.imread(path,0)imgcv2.resize(img,(256,256))qimgQImage(img.data,256,256,256,QImage.Format_Grayscale8)self.lab_ori.setPixmap(QPixmap.fromImage(qimg).scaled(self.lab_ori.size(),Qt.KeepAspectRatio))defrun_seg(self):ifnotself.img_path:returnimg_oricv2.imread(self.img_path,0)img_oricv2.resize(img_ori,(256,256))# 预处理img_np(img_ori/255.0-0.5)/0.5img_tensortorch.from_numpy(img_np).unsqueeze(0).unsqueeze(0).float().to(device)withtorch.no_grad():predmodel(img_tensor)predtorch.sigmoid(pred).cpu().numpy()[0,0]seg_mask(pred0.5).astype(np.uint8)*255# 计算指标无真值时仅展示掩码有标签可传入真值计算Dice/IoUdiceround(get_dice(pred,np.zeros_like(pred)),3)iouround(get_iou(pred,np.zeros_like(pred)),3)self.info_lab.setText(f分割指标\nDice系数{dice}\nIoU指标{iou}\n图像尺寸:256×256)# 绘制分割结果q_segQImage(seg_mask.data,256,256,256,QImage.Format_Grayscale8)self.lab_seg.setPixmap(QPixmap.fromImage(q_seg).scaled(self.lab_seg.size(),Qt.KeepAspectRatio))if__name____main__:appQApplication(sys.argv)winThyroidSegUI()win.show()sys.exit(app.exec_())十、项目落地方向✅ 医学影像毕设完整课题分割算法可视化系统全套✅ 医院超声甲状腺筛查辅助软件原型✅ 论文实验复现TN3K公开数据集DeepLabV3标准架构