1. 程式人生 > >dicom檔案的處理

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