之前有解释预处理部分的函数,不过觉得还不够详细,同时文字解释还不够直观,所以现在想一步步运行下,打印输出

首先读取原始数据,包括相应的注释(即结节标签)【注意】注释文件中的标签是按x,y,z的顺序给的,但是origin以及spacing都是按照z,y,x的顺序,所以要逆序处理一下([:,::-1])

raw_data,origin,spacing,isflip = load_itk_image("/home/dataset/LUNA16/subset3/1.3.6.1.4.1.14519.5.2.1.6279.6001.126631670596873065041988320084.mhd")
annos = np.array(pandas.read_csv("/home/dataset/LUNA16/CSVFILES/annotations.csv"))
this_annos = np.copy(annos[annos[:,0]==("1.3.6.1.4.1.14519.5.2.1.6279.6001.126631670596873065041988320084")])
raw_label = (this_annos[:,1:-1][:,::-1]-origin)/spacing

然后输出下原始数据的shape,以及标签的内容

print(raw_data.shape)
print(raw_label)

输出

(272, 512, 512) 
[[83.84986792 232.12420469969365 348.18196764820215] [229.169256536 308.7302064585643 158.2345410262112]]

然后可视化其中一张切片

plt.imshow(raw_data[229])

效果

现在开始进入预处理流程

之前读取过原始数据,此处不再读取,除原始数据及标签外,还需要读取LUNA16为每个CT提供的掩码,用于剔除肺部以外区域

Mask,origin,spacing,isflip = load_itk_image("/home/dataset/LUNA16/seg-lungs-LUNA16/1.3.6.1.4.1.14519.5.2.1.6279.6001.126631670596873065041988320084.mhd")

掩码是与CT图像同样大小的三维图像,区别在于掩码只有0,1两种值,这张CT的大小是(272,512,512),掩码也是(272,512,512)

值得注意的是此处的掩码却并不是0,1二值,而是0,3,4三种值,0依然代表肺部以外区域,3代表左肺,4代表右肺,为便于将肺部一起处理,还需要将左右两个肺合并一下

m1 = Mask==3    #LUNA16的掩码有两种值,3和4
m2 = Mask==4
Mask = m1+m2

然后这里做了一个我认为没那么重要但是给处理带来很多麻烦的环节,那就是对掩码求取边界(肺部边界),只保留边界内的数据

不妨想象一个正方形,里面有一个小圆,小圆就是掩码,那么此处做的就是求小圆的最小外接矩形,将矩形外的部分砍掉

xx,yy,zz= np.where(Mask)
box = np.array([[np.min(xx),np.max(xx)],[np.min(yy),np.max(yy)],[np.min(zz),np.max(zz)]])

打印输出看一下box

array([[ 21, 264],        [130, 407],        [ 62, 441]])

做到这,预处理已经差不多了,再加几步

box = box*np.expand_dims(spacing,1)/np.expand_dims(resolution,1)  #对边界即掩码的最小外部长方体应用新分辨率 box = np.floor(box).astype('int')

打印输出

array([[ 26, 330],        [ 96, 302],        [ 46, 327]])

对这个边界向外扩展一点,为了处理边缘的像素

margin = 5 extendbox = np.vstack([np.max([[0,0,0],box[:,0]-margin],0),np.min([newshape,box[:,1]+2*margin],axis=0).T]).T

打印输出

array([[ 21, 340],        [ 91, 312],        [ 41, 337]])

然后对掩码进行一点处理

convex_mask = m1       
dm1 = process_mask(m1) #对掩码采取膨胀操作,去除肺部黑洞
dm2 = process_mask(m2)
dilatedMask = dm1+dm2
Mask = m1+m2
extramask = dilatedMask ^ Mask #异或操作,求出相比于原始掩码膨胀后多出来的区域

这里mask的大小没有变过,仍然是(272,512,512)

bone_thresh = 210 
pad_value = 170
sliceim = lumTrans(sliceim) #对原始数据阈值化,并归一化
sliceim = sliceim*dilatedMask+pad_value*(1-dilatedMask).astype('uint8') #170对应归一化话后的水,掩码(膨胀过后)外的区域补充为水
bones = (sliceim*extramask)>bone_thresh #210对应归一化后的骨头,凡是大于骨头的区域都填充为水
sliceim[bones] = pad_value

此时CT数据即sliceim的大小也没有变过,现在要变化一下,进行重采样

sliceim1,_ = resample(sliceim,spacing,resolution,order=1)

查看下此时的大小

(340, 380, 380)

最后还记得之前求的box吗,我们只需要box内的数据即可

sliceim2 = sliceim1[extendbox[0,0]:extendbox[0,1],         #将extendbox内数据取出作为最后结果                     
extendbox[1,0]:extendbox[1,1],
extendbox[2,0]:extendbox[2,1]]

处理完数据,还需要处理标签

之前已经将世界坐标转换为体素坐标,现在要对其应用新的分辨率(这里取[1,1,1])

raw_label = raw_label*spacing/resolution

输出

array([[104.8123349, 172.279793861, 258.41647013999994],        [286.46157067, 229.13584731999998, 117.43977386999997]], dtype=object)

最后的最后,减去box的下界

得到

[[83.84986792 232.12420469969365 348.18196764820215]  [229.169256536 308.7302064585643 158.2345410262112]]

上面处理过的数据和标签与完整预处理后的clean.npy和label.npy是一样的,证明这个分解的过程没什么纰漏

完结,撒花

对DeepLung数据预处理部分的详细展示的更多相关文章

  1. 第七篇:数据预处理(四) - 数据归约(PCA/EFA为例)

    前言 这部分也许是数据预处理最为关键的一个阶段. 如何对数据降维是一个很有挑战,很有深度的话题,很多理论书本均有详细深入的讲解分析. 本文仅介绍主成分分析法(PCA)和探索性因子分析法(EFA),并给 ...

  2. 借助 SIMD 数据布局模板和数据预处理提高 SIMD 在动画中的使用效率

    原文链接 简介 为发挥 SIMD1 的最大作用,除了对其进行矢量化处理2外,我们还需作出其他努力.可以尝试为循环添加 #pragma omp simd3,查看编译器是否成功进行矢量化,如果性能有所提升 ...

  3. weka数据预处理

    Weka数据预处理(一) 对于数据挖掘而言,我们往往仅关注实质性的挖掘算法,如分类.聚类.关联规则等,而忽视待挖掘数据的质量,但是高质量的数据才能产生高质量的挖掘结果,否则只有"Garbag ...

  4. 对数据预处理的一点理解[ZZ]

    数据预处理没有统一的标准,只能说是根据不同类型的分析数据和业务需求,在对数据特性做了充分的理解之后,再选择相关的数据预处理技术,一般会用到多种预处理技术,而且对每种处理之后的效果做些分析对比,这里面经 ...

  5. 数据准备<3>:数据预处理

    数据预处理是指因为算法或者分析需要,对经过数据质量检查后的数据进行转换.衍生.规约等操作的过程.整个数据预处理工作主要包括五个方面内容:简单函数变换.标准化.衍生虚拟变量.离散化.降维.本文将作展开介 ...

  6. sklearn数据预处理

    一.standardization 之所以标准化的原因是,如果数据集中的某个特征的取值不服从标准的正太分布,则性能就会变得很差 ①函数scale提供了快速和简单的方法在单个数组形式的数据集上来执行标准 ...

  7. 文本数据预处理:sklearn 中 CountVectorizer、TfidfTransformer 和 TfidfVectorizer

    文本数据预处理的第一步通常是进行分词,分词后会进行向量化的操作.在介绍向量化之前,我们先来了解下词袋模型. 1.词袋模型(Bag of words,简称 BoW ) 词袋模型假设我们不考虑文本中词与词 ...

  8. 目标检测之Faster-RCNN的pytorch代码详解(数据预处理篇)

    首先贴上代码原作者的github:https://github.com/chenyuntc/simple-faster-rcnn-pytorch(非代码作者,博文只解释代码) 今天看完了simple- ...

  9. sklearn中的数据预处理和特征工程

    小伙伴们大家好~o( ̄▽ ̄)ブ,沉寂了这么久我又出来啦,这次先不翻译优质的文章了,这次我们回到Python中的机器学习,看一下Sklearn中的数据预处理和特征工程,老规矩还是先强调一下我的开发环境是 ...

随机推荐

  1. 问题:web.net页面超时;结果:设置ASP.NET页面的运行超时时间详细到单个页面及站点

    设置ASP.NET页面的运行超时时间详细到单个页面及站点 这篇文章主要介绍了如何设置ASP.NET页面的运行超时时间,包括全局超时时间.单个站点超时时间.单个页面请求超时时间,需要的朋友可以参考下 全 ...

  2. No result defined for action action.LoginAction and result success 问题解决

    转自:https://blog.csdn.net/dongzhout/article/details/43699699 搭建好SSH2框架,写一个简单的登陆功能,提交表单的时候遇到这个问题: 配置文件 ...

  3. java飞机大战之子弹的自动生成

    import java.awt.Graphics; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing. ...

  4. 正则表达式计算 origin = "1 - 2 * ( ( 60 - 30 + ( -40.0 / 5 ) * ( 9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2998 + 10 * 568 / 14 )) - ( - 4 * 3 ) / ( 16 - 3 * 2))"

    #!/usr/bin/env python import re def f1(arg): return 1 origin = "1 - 2 * ( ( 60 - 30 + ( -40.0 / ...

  5. 连接ORACLE客户端工具navicat111.12 for oracle

    安装navicat111.12 for oracle后 打开

  6. 04 UUID

    1 什么是UUID UUID 的目的是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定. 2 应用场景 MySQL数据库不能想oracle数据库那样创建序列,就 ...

  7. 算法Sedgewick第四版-第1章基础-009一链表与数组的比较及其他数据结构

    1. 2.

  8. Linux kdb命令

    一.简介 Linux 内核调试器(KDB)允许您调试 Linux 内核.这个恰如其名的工具实质上是内核代码的补丁,它允许高手访问内核内存和数据结构.KDB 的主要优点之一就是它不需要用另一台机器进行调 ...

  9. loj2436 糖果

    传送门 分析 我们知道对于一个不等式a<b可以将其转化为a+1<=b的形式,在知道这个之后我们便可以将5个关系进行差分约束了,具体的建边方式见代码.注意由于每个人都必须有糖,我们把每个人的 ...

  10. Git 之 与Github交互

    我们不可能只在一台电脑上开发,白天在公司用公司电脑,晚上在家可以用自己电脑.但是这个代码怎么让两台电脑同步呢?总不能用U盘复制粘贴.太繁琐. 这里我们就可以找个代码托管的平台,帮我们做这件事. Git ...