医学图像分割 基于深度学习的肝脏肿瘤分割 实战(一)

在之前的一篇博客里:医学图像分割 unet实现(一),是学习并复现别人的实验。这篇将记录下自己毕设第一阶段的实验。毕设题目为:基于深度学习的肝脏肿瘤分割。
经过几番调整,最终确定:第一阶段分割出腹部图像中的肝脏,作为第二阶段的ROI(region of interest),第二阶段利用ROI对腹部图像进行裁剪,裁剪后的非ROI区域变成黑色,作为该阶段输入,分割出肝脏中的肿瘤(更新2019-4-2,已做完实验,医学图像分割 基于深度学习的肝脏肿瘤分割 实战(二)。第三阶段用随机场的后处理方法进行优化。
此外,觉得当时的那篇文章写得很不用心,没费多大功夫,复制粘贴为主。我记录的主要原因之一就是觉得这方面入门实战的文章很少,希望让情况类似的同学少走一点弯路。可现在自己写的东西过几天再去看,都会一头雾水。没有从主干思路到细节的分层讲解,没有关键点的介绍。这篇文章开始,将尽我所能,写得利于接受一点。
(不过,自己才开始学习一个多月,python和框架都是临时学的,并不能保证博客里的东西是对的,有错误的话,望指出)

正文:

目标

分割出CT腹部图像的肝脏区域。

原始数据介绍

实验用到的数据为3Dircadb,即腹部的CT图。一个病人为一个文件夹。
例如3Dircadb1.1(一共20位),该文件夹下会使用到的子文件夹为PATIENT_DICOM(病人原始腹部3D CT图),MASKS_DICOM(该文件夹下具有不同部位的分割结果,比如liver和liver tumor等等)。如下图所示:
在这里插入图片描述
PATIENT_DICOM利用软件展示效果如下:一个dcm文件包含129张切片。
在这里插入图片描述
MASKS_DICOM下的liver分割图效果如下:
在这里插入图片描述

整体思路

1、数据提取

数据读取:
从原始dcm格式读入成我们需要的数组格式

#part1
import numpy as np
import pydicom
import os
import matplotlib.pyplot as plt
import cv2
from keras.preprocessing.image import ImageDataGenerator
from HDF5DatasetWriter import HDF5DatasetWriter
from HDF5DatasetGenerator import HDF5DatasetGenerator

for i in range(1,18): # 前17个人作为测试集
   full_images = [] # 后面用来存储目标切片的列表
   full_livers = [] #功能同上
   # 注意不同的系统,文件分割符的区别
   label_path = '~/3Dircadb/3Dircadb1.%d/MASKS_DICOM/liver'%i
   data_path = '~/3Dircadb/3Dircadb1.%d/PATIENT_DICOM'%i
   liver_slices = [pydicom.dcmread(label_path + '/' + s) for s in os.listdir(label_path)]
   # 注意需要排序,即使文件夹中显示的是有序的,读进来后就是随机的了
   liver_slices.sort(key = lambda x: int(x.InstanceNumber))
   # s.pixel_array 获取dicom格式中的像素值
   livers = np.stack([s.pixel_array for s in liver_slices])
   image_slices = [pydicom.dcmread(data_path + '/' + s) for s in os.listdir(data_path)]
   image_slices.sort(key = lambda x: int(x.InstanceNumber))
   
   """ 省略进行的预处理操作,具体见part2"""
   
   full_images.append(images)
   full_livers.append(livers)
   
   full_images = np.vstack(full_images)
   full_images = np.expand_dims(full_images,axis=-1)
   full_livers = np.vstack(full_livers)
   full_livers = np.expand_dims(full_livers,axis=-1)

2、数据的预处理

1、将ct值转化为标准的hu值
至于为什么要将值进行转化,这儿就不详细说明,具体可以参考医学图像预处理(三)——windowing(ct对比增强),这篇博文中有一样的get_pixels_hu函数
2、窗口化操作
医学图像预处理(三)——windowing(ct对比增强)
3、直方图均衡化

def clahe_equalized(imgs,start,end):
   assert (len(imgs.shape)==3)  #3D arrays
   #create a CLAHE object (Arguments are optional).
   clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
   imgs_equalized = np.empty(imgs.shape)
   for i in range(start, end+1):
       imgs_equalized[i,:,:] = clahe.apply(np.array(imgs[i,:,:], dtype = np.uint8))
   return imgs_equalized

4、归一化
5、仅提取腹部所有切片中包含了肝脏的那些切片,其余的不要
医学图像预处理(四)—— 提取包含目标的切片

#part2
    # 接part1
   images = get_pixels_hu(image_slices)
   
   images = transform_ctdata(images,500,150)
   
   start,end = getRangImageDepth(livers)
   images = clahe_equalized(images,start,end)
   
   images /= 255.
   # 仅提取腹部所有切片中包含了肝脏的那些切片,其余的不要
  
   total = (end - 4) - (start+4) +1
   print("%d person, total slices %d"%(i,total))
   # 首和尾目标区域都太小,舍弃
   images = images[start+5:end-5]
   print("%d person, images.shape:(%d,)"%(i,images.shape[0]))
   
   livers[livers>0] = 1
   
   livers = livers[start+5:end-5]

3、数据增强

利用keras的数据增强接口,可以实现分割问题的数据增强。一般的增强是分类问题,这种情况,只需要对image变形,label保持不变。但分割问题,就需要image和mask进行同样的变形处理。具体怎么实现,参考下面代码,注意种子设定成一样的。

# 可以在part1之前设定好(即循环外)
seed=1
data_gen_args = dict(rotation_range=3,
                    width_shift_range=0.01,
                    height_shift_range=0.01,
                    shear_range=0.01,
                    zoom_range=0.01,
                    fill_mode='nearest')

image_datagen = ImageDataGenerator(**data_gen_args)
mask_datagen = ImageDataGenerator(**data_gen_args)
#part3 接part2
    image_datagen.fit(full_images, augment
评论 269
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值