全卷积神经网路【U-net项目实战】LUNA 2016 数据集详解

文章目录

  • 1.LUNA 2016 数据集详解
  • 2.mdh数据格式详解
  • 3.python读取mdh的方法
  • 4.annotations.csv坐标转换
  • 5.LUNA16数据集肺结节显示

1.LUNA 2016 数据集详解

LUNA16数据集的由来
LUNA 2016 数据集来自2016年LUng Nodule Analysis比赛,这里是其官方网站。
LUNA16数据集是最大公用肺结节数据集LIDC-IDRI的子集,LIDC-IDRI它包括1018个低剂量的肺部CT影像。LIDC-IDRI删除了切片厚度大于3mm和肺结节小于3mm的CT影像,剩下的就是LUNA16数据集了。
其数据集的文件内容如下:

subset0.zip~subset9.zip 包含所有CT图像的10个zip文件,数据格式为“.mhd”,“.raw”
CSVFILES文件夹,包括3文件:annotations.csv,candidates.csv,sampleSubmission.csv
annotations.csv:1186个肺结节信息,字段有seriesuid,coordX,coordY,coordZ,diameter_mm
candidates.csv:一共551065条数据。其中,正例(class:1):1351条,其余都是负例(class:0)
sampleSubmission.csv:正确格式的提交文件示例,我们不提交,暂时没用。

2.mdh数据格式详解

这里有一篇很好的文章,关于医疗影像的mhd和dcm格式图像的读取和坐标转换
每个病例的数据的存储都是由一个.mhd和一个.raw格式的文件组成。.mdh是说明文件,具体数据在.raw文件中,
mdh样例:

ObjectType = Image
NDims = 3          #三维数据
BinaryData = True              #二进制数据
BinaryDataByteOrderMSB = False
CompressedData = False
TransformMatrix = 1 0 0 0 1 0 0 0 1        #100,010,001 分别代表x,y,z
Offset = -195 -195 -378       #原点坐标
CenterOfRotation = 0 0 0
AnatomicalOrientation = RAI
ElementSpacing = 0.7617189884185791 0.7617189884185791 2.5     #像素间隔 x,y,z
DimSize = 512 512 141        #数据的大小 x,y,z
ElementType = MET_SHORT
ElementDataFile = 1.3.6.1.4.1.14519.5.2.1.6279.6001.173106154739244262091404659845.raw      #数据存储的文件名

3.python读取mdh的方法

mhd已经交代了图像数据的信息,接下来对图像数据进行读取,这里主要用的Python中的SimpleITK库

import SimpleITK as sitk
import matplotlib.pyplot as plt
case_path = './1.3.6.1.4.1.14519.5.2.1.6279.6001.126264578931778258890371755354.mhd'  
itkimage = sitk.ReadImage(case_path)   #这部分给出了关于图像的信息,可以打印处理查看,这里就不在显示了
#print(itkimage)
image = sitk.GetArrayFromImage(itkimage)     #z,y,x
#查看第100张图像
plt.figure()
plt.imshow(image[100,:,:]) 

4.annotations.csv坐标转换

annotations.csv中提供了医生标注肺结节位置信息
seriesuid:表示每个病例图像对应的文件名
coordX,coordX,coordX,diameter_mm:表示医生标注的结节位置信息和直径
在这里插入图片描述
在使coordX用卷积网络对肺结节进行检测时,我们需要根据医生提供的标注信息,在图像中找到相应的肺结节位置,接下来说医生标注的坐标与图像中的坐标的关系。
mhd中给定了图像中的原点坐标为(-195 ,-195 ,-378) #x,y,z
像素间隔为(0.7617189884185791,0.7617189884185791,2.5) #x,y,z
通过以上信息可以计算结节相对原点的坐标,然后用这个坐标除以像素间隔,即为在图像中对应的结节位置
#世界坐标转换到图像中的坐标

def worldToVoxelCoord(worldCoord, origin, spacing):
    stretchedVoxelCoord = np.absolute(worldCoord - origin)
    voxelCoord = stretchedVoxelCoord / spacing
    return voxelCoord

#图像上的坐标转换为世界坐标

def VoxelToWorldCoord(voxelCoord, origin, spacing):
    strechedVocelCoord = voxelCoord * spacing
    worldCoord = strechedVocelCoord + origin
    return worldCoord

5.LUNA16数据集肺结节显示

LUNA16数据集肺结节显示代码如下:

import SimpleITK as sitk
import matplotlib.pyplot as plt
import numpy as np
filename='data\\1.3.6.1.4.1.14519.5.2.1.6279.6001.173106154739244262091404659845.mhd'
itkimage = sitk.ReadImage(filename)#读取.mhd文件
OR=itkimage.GetOrigin()
print(OR)
SP=itkimage.GetSpacing()
print(SP)
numpyImage = sitk.GetArrayFromImage(itkimage)#获取数据,自动从同名的.raw文件读取

def show_nodules(ct_scan, nodules,Origin,Spacing,radius=20, pad=2, max_show_num=4): # radius是正方形边长一半,pad是边的宽度,max_show_num最大展示数
    show_index = []
    for idx in range(nodules.shape[0]): # lable是一个nx4维的数组,n是肺结节数目,4代表x,y,z,以及直径
        if idx < max_show_num:
            if abs(nodules[idx, 0]) + abs(nodules[idx, 1]) + abs(nodules[idx, 2]) + abs(nodules[idx, 3]) == 0:
                continue

            x, y, z = int((nodules[idx, 0]-Origin[0])/SP[0]), int((nodules[idx, 1]-Origin[1])/SP[1]), int((nodules[idx, 2]-Origin[2])/SP[2])
        print(x, y, z)
        data = ct_scan[z]
        radius=int(nodules[idx, 3]/SP[0]/2)
        #pad = 2*radius
        # 注意 y代表纵轴,x代表横轴
        data[max(0, y - radius):min(data.shape[0], y + radius),
        max(0, x - radius - pad):max(0, x - radius)] = 3000 # 竖线
        data[max(0, y - radius):min(data.shape[0], y + radius),
        min(data.shape[1], x + radius):min(data.shape[1], x + radius + pad)] = 3000 # 竖线
        data[max(0, y - radius - pad):max(0, y - radius),
        max(0, x - radius):min(data.shape[1], x + radius)] = 3000 # 横线
        data[min(data.shape[0], y + radius):min(data.shape[0], y + radius + pad),
        max(0, x - radius):min(data.shape[1], x + radius)] = 3000 # 横线

        if z in show_index: # 检查是否有结节在同一张切片,如果有,只显示一张
            continue
        show_index.append(z)
        plt.figure(idx)
        plt.imshow(data, cmap='gray')

    plt.show()

b = np.array([[-116.2874457,21.16102581,-124.619925,10.88839157],[-111.1930507,-1.264504521,-138.6984478,17.39699158],[73.77454834,37.27831567,-118.3077904,8.648347161]])
show_nodules(numpyImage,b,OR,SP)

结果图像,三张图,其中一张如下:

全卷积神经网路【U-net项目实战】LUNA 2016 数据集详解_第1张图片

你可能感兴趣的:(#,U-Net)