Advertisement

深度之眼--图像分割第二周Unet

阅读量:

医学图像分割常青树 Unet

    • 1.医学图像分割面临挑战
    • 2.医学图像分割特点
    • 3.Unet分割CamVid数据集
    • 4.Unet分割医学数据集

1.医学图像分割面临挑战

医学图像分割是计算机视觉领域研究的一项重要内容,图像分割在影像学诊断中大有用处,自动分割能帮助医生确认病变组织的大小,辅助或代替医生诊断,对很多疾病的防治都具有广泛的应用价值。近年来,深度学习被广泛应用于不同模式的图像分割,CT、X射线、MRI等。通过自动地勾勒出图像内部的边界,将图像分割成不同的具有相似特征的图像片段,通常为不同的组织、病理、器官。
近年来,U-Net作为医学影像界最流行的体系结构,在分割医学图像方面表现出了大大优于传统分割方法的显著整体性能。但仍然存在训练数据稀缺、数据分布不平衡、冗余的背景信息(造影遮挡)、细节特征丢失、没有考虑具体任务的特点、分割模型不可泛化到不同任务等问题。

2.医学图像分割特点

医学图像分割的特点是:分割精度的要求高,可用的带标注的数据量小,获取病人数据难,标注成本大,病人隐私保护问题,一般要求分类数较少,通常为两类(病灶,背景),未来有广阔的应用前景。

3.Unet分割CamVid数据集

CamVid数据集是一个包含12类图像的道路景观数据集,故定义Unet模型为(3,12),输出12张概率图,使用padding=1的3x3卷积,输入输出尺寸均为(352,480)。转置卷积(3,2,1,1)或者(2,2)用来2倍放大特征图。模型代码如下:

复制代码
    import torch
    from torch import nn
    
    class 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 U_net(nn.Module):
    def __init__(self, in_ch, out_ch):
        super(U_net, 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):
        #print(x.shape)
        c1 = self.conv1(x)  # (b,64,352,480)
        p1 = self.pool1(c1) # (b,64,176,240)
        #print(p1.shape)
        c2 = self.conv2(p1) # (b,128,176,240)
        p2 = self.pool2(c2) # (b,128,88,120)
        #print(p2.shape)
        c3 = self.conv3(p2) # (b,256,88,120)
        p3 = self.pool3(c3) # (b,256,44,60)
        #print(p3.shape)
        c4 = self.conv4(p3) # (b,512,44,60)
        p4 = self.pool4(c4) # (b,512,22,30)
        #print(p4.shape)
        c5 = self.conv5(p4) # (b,1024,22,30)
        up_6 = self.up6(c5)                    # (b,512,44,60)
        merge6 = torch.cat([up_6, c4], dim=1)  # (b,1024,44,60)
        c6 = self.conv6(merge6)                # (b,512,44,60)
        up_7 = self.up7(c6)                    # (b,256,88,120)
        merge7 = torch.cat([up_7, c3], dim=1)  # (b,512,88,120)
        c7 = self.conv7(merge7)                # (b,256,88,120)
        up_8 = self.up8(c7)                    # (b,128,176,240)
        merge8 = torch.cat([up_8, c2], dim=1)  # (b,256,176,240)
        c8 = self.conv8(merge8)                # (b,128,176,240)
        up_9 = self.up9(c8)                    # (b,64,352,480)
        merge9 = torch.cat([up_9, c1], dim=1)  # (b,128,352,480)
        c9 = self.conv9(merge9)                # (b,64,352,480)
        c10 = self.conv10(c9)                  # (b,12,352,480)
        return c10

分割结果指标如下:
在这里插入图片描述
模型在40轮之后出现了过拟合,最终效果:在这里插入图片描述

4.Unet分割医学数据集

二分类问题(1病灶,0背景),使用BCEloss损失函数,Adam优化器,Unet模型循环10轮后的分割结果(仅作展示):
在这里插入图片描述

全部评论 (0)

还没有任何评论哟~