dicom檔案的處理
一、dicom檔案
字尾為.dcm
每個病人的一次掃描CT(scan)可能有幾十到幾百個dcm資料檔案(slices)。可以使用python的dicom包讀取。其中的pixel_array資料
slices = [dicom.read_file(os.path.join(folder_name,filename)) for filename in os.listdir(folder_name)]
slices = np.stack([s.pixel_array for s in slices])
二、dicom格式資料處理
2.1 處理思路:
首先,醫學掃描影象(scan)是三維影象,使用程式碼可以檢視不同的切面的切片(slices),可以從不同的軸切割
其次,醫學影象在掃描時,包含了人體的全部組織,需要經過一定的預處理(最重要的是放射劑量的概念)不同的放射劑量對應不同的組織器官 放射劑量單位:HU(Hounsfield Unit)
Hounsfield Unit = pixel_value * rescale_slope + rescale_intercept
一般而言 rescale slope=1,intercept=-1024
灰度值是pixel value經過重重LUT轉換得到的用來進行顯示的值,且這個轉換不可逆,灰度值是無法轉換為ct值的。只能根據窗寬窗位得到一個大概的範圍。pixel value經過modality lut得到Hu,但是懷疑pixel value的讀取出了問題。dicom文化中存在(0028 ,0106)(0028,0107)兩個tag,分別是最大和最小pixel value,可以用來檢驗你讀取出來的pixel value矩陣是否正確。
LUT是look up table的簡稱,實際上就是一張畫素灰度值的對映表,他將實際取樣得到的畫素灰度值經過一定的變換如閾值、反轉、二值化、對比度調整、線性變換等,變成了另外一個與之對應的灰度值,這樣可以起到突出影象的有用資訊,增強影象的光對比度的作用。
首先去除超過-2000的pixel_array,CT掃描邊界之外的畫素值固定為-2000(dicom和mhd都是這個值)。第一步是設定這些值為0
slices[slices == -2000] = 0
3.2處理dicom必要的包
# -*- coding:utf-8 -*- import glob import os import pandas as pd import SimpleITK as sitk import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv) import skimage, os from skimage.morphology import ball, disk, dilation, binary_erosion, remove_small_objects, erosion, closing, reconstruction, binary_closing from skimage.measure import label,regionprops, perimeter from skimage.morphology import binary_dilation, binary_opening from skimage.filters import roberts, sobel from skimage import measure, feature from skimage.segmentation import clear_border from skimage import data from scipy import ndimage as ndi import matplotlib #matplotlib.use('Agg') import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.art3d import Poly3DCollection import dicom import scipy.misc import numpy as np
Dicom檔案是醫學影象 的標準檔案,這些檔案包含了諸多的元資料資訊,(比如畫素尺寸,每個維度的 畫素代表真實人體中的長度)。下面的程式碼是包含了多個切片(slices)的掃描面,我們僅僅是將其儲存為python列表。切片的厚度丟失,即Z軸方向上的畫素尺寸,但是可以利用其它的值推測出來,加到元資料中。
# Load the scans in given folder path
def load_scan(path):
slices = [dicom.read_file(path + '/' + s) for s in os.listdir(path)]
slices.sort(key = lambda x: int(x.ImagePositionPatient[2]))
try:
slice_thickness = np.abs(slices[0].ImagePositionPatient[2] - slices[1].ImagePositionPatient[2])
except:
slice_thickness = np.abs(slices[0].SliceLocation - slices[1].SliceLocation)
for s in slices:
s.SliceThickness = slice_thickness
return slices