日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

医学图像分割之肝脏分割(2D)

發布時間:2023/12/16 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 医学图像分割之肝脏分割(2D) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 肝臟分割數據集
  • 一、預處理
  • 二、圖像增強
  • 三、訓練
  • 四、測試
  • 總結


肝臟分割數據集

肝臟分割分割主要有三個開源數據集:LiTS17,Sliver07,3DIRCADb

LiTS17包含131個數據,可以用于肝臟及腫瘤的分割

Sliver07包含20個數據,但僅僅包含肝臟,并沒有腫瘤的金標準

3DIRCADb包含20個數據,可以用于肝臟及腫瘤的分割


提示:以下是本篇文章正文內容,下面案例可供參考

一、預處理

這三個肝臟分割數據集都是3D數據,所以如過要進行訓練必須要對數據進行切片。

對3D nii文件進行調窗,找到肝臟區域并向外擴張,將數據z軸的spacing調整到1mm。

將3D nii格式的數據切片為2D png格式。

# 將灰度值在閾值之外的截斷掉# upper = 200# lower = -200ct_array[ct_array > para.upper] = para.upperct_array[ct_array < para.lower] = para.lower#肝臟分割設置seg_array[seg_array > 0] = 1# 找到肝臟區域開始和結束的slice,并各向外擴張z = np.any(seg_array, axis=(1, 2))start_slice, end_slice = np.where(z)[0][[0, -1]]# 對CT數據在橫斷面上進行降采樣(下采樣),并進行重采樣,將所有數據的z軸的spacing調整到1mm ct_array = ndimage.zoom(ct_array,(ct.GetSpacing()[-1] / para.slice_thickness, para.down_scale, para.down_scale),order=3) seg_array = ndimage.zoom(seg_array, (ct.GetSpacing()[-1] / para.slice_thickness, para.down_scale, para.down_scale), order=0)#進行切片操作for i in range(volume.shape[0]):slice = volume[i,:,:]slice_post = WL(slice, WC, WW)slice_post = slice_post.astype(np.uint8)# slice_post = cv.equalizeHist(slice_post)slices_in_order.append(slice_post)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 原始CT? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 調窗后

二、圖像增強

同時對肝臟的 Original CT,Ground Truth進行圖像增強。

# 圖像旋轉: 按照概率0.8執行,最大左旋角度10,最大右旋角度10 # p.rotate(probability=0.5, max_left_rotation=20, max_right_rotation=20)# 圖像左右互換: 按照概率0.5執行 # p.flip_left_right(probability=0.8)# # # 圖像放大縮小: 按照概率0.8執行,面積為原始圖0.85倍 # p.zoom_random(probability=1, percentage_area=0.8)

?

三、訓練

1.模型搭建

import torch.nn as nn import torch from torch import autogradclass DoubleConv(nn.Module):def __init__(self, in_ch, out_ch):super(DoubleConv, self).__init__()self.conv = nn.Sequential(nn.Conv2d(in_ch, out_ch, 3, padding=1),nn.BatchNorm2d(out_ch),nn.ReLU(inplace=True),nn.Conv2d(out_ch, out_ch, 3, padding=1),nn.BatchNorm2d(out_ch),nn.ReLU(inplace=True))def forward(self, input):return self.conv(input)class UNet(nn.Module):def __init__(self, in_ch, out_ch):super(UNet, self).__init__()self.conv1 = DoubleConv(in_ch, 64)self.pool1 = nn.MaxPool2d(2)self.conv2 = DoubleConv(64, 128)self.pool2 = nn.MaxPool2d(2)self.conv3 = DoubleConv(128, 256)self.pool3 = nn.MaxPool2d(2)self.conv4 = DoubleConv(256, 512)self.pool4 = nn.MaxPool2d(2)self.conv5 = DoubleConv(512, 1024)self.up6 = nn.ConvTranspose2d(1024, 512, 2, stride=2)self.conv6 = DoubleConv(1024, 512)self.up7 = nn.ConvTranspose2d(512, 256, 2, stride=2)self.conv7 = DoubleConv(512, 256)self.up8 = nn.ConvTranspose2d(256, 128, 2, stride=2)self.conv8 = DoubleConv(256, 128)self.up9 = nn.ConvTranspose2d(128, 64, 2, stride=2)self.conv9 = DoubleConv(128, 64)self.conv10 = nn.Conv2d(64, out_ch, 1)def forward(self, x):c1 = self.conv1(x)p1 = self.pool1(c1)c2 = self.conv2(p1)p2 = self.pool2(c2)c3 = self.conv3(p2)p3 = self.pool3(c3)c4 = self.conv4(p3)p4 = self.pool4(c4)c5 = self.conv5(p4)up_6 = self.up6(c5)merge6 = torch.cat([up_6, c4], dim=1)c6 = self.conv6(merge6)up_7 = self.up7(c6)merge7 = torch.cat([up_7, c3], dim=1)c7 = self.conv7(merge7)up_8 = self.up8(c7)merge8 = torch.cat([up_8, c2], dim=1)c8 = self.conv8(merge8)up_9 = self.up9(c8)merge9 = torch.cat([up_9, c1], dim=1)c9 = self.conv9(merge9)c10 = self.conv10(c9)out = nn.Sigmoid()(c10)return out

2.模型訓練

if __name__ == '__main__':device = torch.device("cuda" if torch.cuda.is_available() else "cpu")LEARNING_RATE = 1e-3LR_DECAY_STEP = 2LR_DECAY_FACTOR = 0.5WEIGHT_DECAY = 5e-4BATCH_SIZE = 1MAX_EPOCHS = 2model = UNet()criterion = DiceLoss()if opt.use_gpu:criterion = criterion.cuda(opt.device)lr = opt.lroptimizer = torch.optim.Adam(model.parameters(), lr=lr, weight_decay=opt.weight_decay)lr_scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, opt.lr_decay)MODEL = Unet(out_ch=2)OPTIMIZER = torch.optim.Adam(MODEL.parameters(), lr=LEARNING_RATE, weight_decay=WEIGHT_DECAY)LR_SCHEDULER = torch.optim.lr_scheduler.StepLR(OPTIMIZER, step_size=LR_DECAY_STEP, gamma=LR_DECAY_FACTOR)CRITERION = DiceLoss().to(device)

四、測試

for i in range(1, 10):idx_list.append(i)ct = sitk.ReadImage(data_path + 'volume-' + str(i) + '.nii',sitk.sitkInt16)seg = sitk.ReadImage(data_path + 'segmentation-' + str(i) + '.nii',sitk.sitkInt16)predictions_in_order = []for slice in slices_in_order:slice = torch.from_numpy(slice).float() / 255.output = model(slice.unsqueeze(0).unsqueeze(0))prediction = sm(output)_, prediction = torch.max(prediction, dim=1) #返回每一行中最大值的那個元素,且返回其索引(返回最大元素在這一行的列索引)prediction = prediction.squeeze(0).cpu().detach().numpy().astype(np.uint8)predictions_in_order.append(prediction)

測試結果可視化:


總結

第一次寫,也是隨手一寫,后續會更新3D肝臟分割,2.5D肝臟分割,以及肝臟腫瘤分割。

總結

以上是生活随笔為你收集整理的医学图像分割之肝脏分割(2D)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。