Synapse 腹部 CT 多器官分割数据集 Synapse数据集的训练及应用 基于 DeepLabV3+ Synapse 腹部多器官 CT 分割 医学图像分割毕设、腹腔脏器AI辅助诊断
智慧医疗-Synapse数据集共有3779张图片已将图片转为png格式腹部CT图像用于腹部的多器官分割训练集测试集已经分好基于DeepLabV3 Synapse腹部多器官CT分割项目全代码项目说明一、数据集信息表项目详情数据集名称Synapse腹部CT多器官分割数据集图片总数3779张统一PNG格式图像类型腹部断层CT灰度影像任务类型多类别语义分割腹腔多脏器分割数据划分已提前拆分Train、Test文件夹标签形式对应png掩码多值标签区分不同器官开发框架PytorchDeepLabV3配套系统PyQt5可视化分割界面单图/批量CT器官分割常规Synapse包含脾脏、右肾、左肾、胆囊、食管、肝脏、胃、胰腺共8类器官背景标签值0~8。二、项目目录synapse_seg/ ├── data/ │ ├── train/img # 训练CT原图png │ ├── train/mask # 训练标签png │ ├── test/img │ └── test/mask ├── weights/ # 保存best.pth ├── utils/ │ ├── dataset.py # 数据集读取 │ ├── deeplabv3plus.py │ └── metric.py # mIoU/Dice计算 ├── train.py # 训练脚本 ├── GUI.py # PyQt可视化分割软件 └── requirements.txt三、requirements.txttorch1.10 torchvision opencv-python numpy pyqt5 albumentations matplotlib安装pip install -r requirements.txt四、utils/dataset.py 数据集加载importosimportcv2importnumpyasnpfromtorch.utils.dataimportDatasetimportalbumentationsasAfromalbumentations.pytorchimportToTensorV2classSynapseDataset(Dataset):def__init__(self,img_path,mask_path,transformNone):self.img_pimg_path self.mask_pmask_path self.name_listsorted(os.listdir(img_path))self.transformtransformdef__len__(self):returnlen(self.name_list)def__getitem__(self,idx):nameself.name_list[idx]imgcv2.imread(os.path.join(self.img_p,name),0)maskcv2.imread(os.path.join(self.mask_p,name),0)imgcv2.resize(img,(256,256))maskcv2.resize(mask,(256,256),interpolationcv2.INTER_NEAREST)ifself.transform:augself.transform(imageimg,maskmask)img,maskaug[image],aug[mask]returnimg,mask train_augA.Compose([A.Resize(256,256),A.HorizontalFlip(p0.5),A.Normalize(mean[0.5],std[0.5]),ToTensorV2()])val_augA.Compose([A.Resize(256,256),A.Normalize(mean[0.5],std[0.5]),ToTensorV2()])五、utils/deeplabv3plus.py多分类版importtorchimporttorch.nnasnnimporttorch.nn.functionalasFclassASPP(nn.Module):def__init__(self,in_c,out_c):super().__init__()self.d1nn.Conv2d(in_c,out_c,1,1,dilation1)self.d3nn.Conv2d(in_c,out_c,3,1,padding3,dilation3)self.d6nn.Conv2d(in_c,out_c,3,1,padding6,dilation6)self.d9nn.Conv2d(in_c,out_c,3,1,padding9,dilation9)self.avg_poolnn.AdaptiveAvgPool2d(1)self.p_convnn.Conv2d(in_c,out_c,1,1)self.outnn.Conv2d(out_c*5,out_c,1,1)defforward(self,x):x1self.d1(x)x2self.d3(x)x3self.d6(x)x4self.d9(x)xpself.avg_pool(x)xpself.p_conv(xp)xpF.interpolate(xp,sizex.shape[2:],modebilinear,align_cornersFalse)cattorch.cat([x1,x2,x3,x4,xp],dim1)returnself.out(cat)classDeepLabV3Plus(nn.Module):def__init__(self,in_ch1,num_classes9):super().__init__()self.bonenn.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.decodenn.Sequential(nn.Conv2d(6432,64,3,padding1),nn.ReLU(),nn.Conv2d(64,num_classes,1,1))defforward(self,x):feat1self.bone[:2](x)feat2self.bone[2:](feat1)feat_asppself.aspp(feat2)feat_asppF.interpolate(feat_aspp,feat1.shape[2:],modebilinear,align_cornersFalse)shortself.short_conv(feat1)fusetorch.cat([feat_aspp,short],dim1)outself.decode(fuse)outF.interpolate(out,x.shape[2:],modebilinear,align_cornersFalse)returnout六、utils/metric.py Dice/IoU多分类指标importnumpyasnpdefcal_dice(pred,gt,cls):smooth1e-6p(predcls).astype(np.float32)g(gtcls).astype(np.float32)inter(p*g).sum()unionp.sum()g.sum()dice(2*intersmooth)/(unionsmooth)returndicedefcal_iou(pred,gt,cls):smooth1e-6p(predcls).astype(np.float32)g(gtcls).astype(np.float32)inter(p*g).sum()unionp.sum()g.sum()-inter iou(intersmooth)/(unionsmooth)returniou七、train.py 训练代码importosimporttorchimporttorch.nnasnnfromtorch.utils.dataimportDataLoaderfromutils.datasetimportSynapseDataset,train_aug,val_augfromutils.deeplabv3plusimportDeepLabV3Plusfromutils.metricimportcal_dice,cal_iouimportnumpyasnp devicetorch.device(cudaiftorch.cuda.is_available()elsecpu)num_cls9batch8epoch100lr1e-4train_setSynapseDataset(./data/train/img,./data/train/mask,train_aug)test_setSynapseDataset(./data/test/img,./data/test/mask,val_aug)train_loaderDataLoader(train_set,batch_sizebatch,shuffleTrue)test_loaderDataLoader(test_set,batch_sizebatch,shuffleFalse)modelDeepLabV3Plus(1,num_cls).to(device)loss_funcnn.CrossEntropyLoss()opttorch.optim.Adam(model.parameters(),lrlr)os.makedirs(weights,exist_okTrue)best_dice0.0foreinrange(epoch):model.train()loss_all0forimg,maskintrain_loader:img,maskimg.to(device),mask.long().to(device)predmodel(img)lossloss_func(pred,mask)opt.zero_grad()loss.backward()opt.step()loss_allloss.item()loss_all/len(train_loader)model.eval()dice_all[]withtorch.no_grad():forimg,maskintest_loader:imgimg.to(device)outmodel(img)predtorch.argmax(out,dim1).cpu().numpy()gtmask.cpu().numpy()forp,ginzip(pred,gt):d_list[]forcinrange(1,num_cls):d_list.append(cal_dice(p,g,c))dice_all.append(np.mean(d_list))mean_dicenp.mean(dice_all)print(fEpoch{e1:3d}| Loss:{loss_all:.4f}| AvgDice:{mean_dice:.4f})ifmean_dicebest_dice:best_dicemean_dice torch.save(model.state_dict(),weights/best.pth)print(保存最优权重)八、GUI.py 腹部CT多器官分割可视化系统importsys,cv2importnumpyasnpfromPyQt5.QtWidgetsimportQApplication,QMainWindow,QWidget,QHBoxLayout,QVBoxLayout,QLabel,QPushButton,QFileDialogfromPyQt5.QtGuiimportQPixmap,QImagefromPyQt5.QtCoreimportQtimporttorchfromutils.deeplabv3plusimportDeepLabV3Plus devicetorch.device(cudaiftorch.cuda.is_available()elsecpu)modelDeepLabV3Plus(1,9).to(device)model.load_state_dict(torch.load(weights/best.pth,map_locationdevice))model.eval()# 器官配色color_map[[0,0,0],[255,0,0],[0,255,0],[0,0,255],[255,255,0],[255,0,255],[0,255,255],[128,0,128],[255,128,0]]classSynapseUI(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle(Synapse腹部CT多器官分割系统)self.resize(1500,800)self.img_pathNoneself.init_ui()definit_ui(self):cwQWidget()self.setCentralWidget(cw)main_layoutQHBoxLayout(cw)leftQWidget()lvQVBoxLayout(left)self.lab_infoQLabel(腹部CT多脏器分割\n器官脾/双肾/肝胆/胃/胰腺)self.btn_openQPushButton(打开CT图像)self.btn_runQPushButton(开始分割)self.btn_open.clicked.connect(self.openimg)self.btn_run.clicked.connect(self.predict)lv.addWidget(self.lab_info)lv.addWidget(self.btn_open)lv.addWidget(self.btn_run)rightQWidget()rhQHBoxLayout(right)self.lab_oriQLabel(原图)self.lab_resQLabel(分割结果)self.lab_ori.setStyleSheet(border:2px solid #3399cc)self.lab_res.setStyleSheet(border:2px solid #cc3333)self.lab_ori.setAlignment(Qt.AlignCenter)self.lab_res.setAlignment(Qt.AlignCenter)rh.addWidget(self.lab_ori)rh.addWidget(self.lab_res)main_layout.addWidget(left,1)main_layout.addWidget(right,3)defopenimg(self):p,_QFileDialog.getOpenFileName(self,选择CT图片,,*.png;*.jpg)ifnotp:returnself.img_pathp imgcv2.imread(p,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))defpredict(self):ifnotself.img_path:returnimgcv2.imread(self.img_path,0)imgcv2.resize(img,(256,256))inp(img/255.-0.5)/0.5tentorch.from_numpy(inp).unsqueeze(0).unsqueeze(0).float().to(device)withtorch.no_grad():outmodel(ten)predtorch.argmax(out,dim1).cpu().numpy()[0]# 上色res_imgnp.zeros((256,256,3),dtypenp.uint8)forcinrange(9):res_img[predc]color_map[c]bgrcv2.cvtColor(res_img,cv2.COLOR_RGB2BGR)qQImage(bgr.data,256,256,768,QImage.Format_RGB888)self.lab_res.setPixmap(QPixmap.fromImage(q).scaled(self.lab_res.size(),Qt.KeepAspectRatio))if__name____main__:appQApplication(sys.argv)winSynapseUI()win.show()sys.exit(app.exec_())九、使用说明将3779张png按照train、test拆分后放入data对应img、mask文件夹运行train.py训练最优模型自动存入weights运行GUI.py单张导入CT图一键多器官彩色分割十、项目适用✅ 医学图像分割毕设、腹腔脏器AI辅助诊断✅ 论文实验Synapse公开数据集DeepLabV3✅ 可后续导出ONNX部署嵌入式。