LUNA 2016 數據集詳解

LUNA 2016 數據集詳解

LUNA16數據集的由來
LUNA 2016 數據集來自2016年LUng Nodule Analysis比賽,這裏是其官方網站
LUNA16數據集是最大公用肺結節數據集LIDC-IDRI的子集,LIDC-IDRI它包括1018個低劑量的肺部CT影像。LIDC-IDRI刪除了切片厚度大於3mm和肺結節小於3mm的CT影像,剩下的就是LUNA16數據集了。
其數據集的文件內容如下:

  1. subset0.zip~subset9.zip 包含所有CT圖像的10個zip文件,數據格式爲“.mhd”,“.raw”
  2. CSVFILES文件夾,包括3文件:annotations.csv,candidates.csv,sampleSubmission.csv
  3. annotations.csv:1186個肺結節信息,字段有seriesuid,coordX,coordY,coordZ,diameter_mm
  4. candidates.csv:一共551065條數據。其中,正例(class:1):1351條,其餘都是負例(class:0)
  5. sampleSubmission.csv:正確格式的提交文件示例,我們不提交,暫時沒用。

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      #數據存儲的文件名

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,:,:]) 

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

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)

結果圖像,三張圖,其中一張如下:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章