CT流程与CT图像的windowing操作(转载+整理)
根據[4]中的定義:
? CT 的特點是能夠分辨人體組織密度的輕微差別,所采用的標準是根據各種組織對X 線的線性吸收系數(μ值) 來決定的。
[5]中提到了一個公式:
所以比賽中的dicom的灰度值需要轉化為CT值。
CT值的物理意義就是CT射線照了你的身體,輻射經過你的身體時的輻射強度的衰減程度。
-----------------------------------------------------------------------------------------------------------------------------
[1]中對CT圖像的windowing的定義:]
Windowing, also known as?grey-level mapping,?contrast stretching,?histogram modification?or?contrast enhancement?is the process in which the CT image greyscale component of an image is manipulated via the CT numbers; doing this will change the appearance of the picture to highlight particular structures. The brightness of the image is, adjusted via the window level. The contrast is adjusted via the window width.
說白了就是灰度映射為輻射強度,然后提高對比度
?
根據[2],dicom里面,如果給出了intercept和slope,就認為灰度值和輻射強度之間的轉化是線性關系.
否則就是非線性關系,是否是線性關系可以根據對dicom的數據讀取來判斷(下面的代碼輸出內容中有)
?
然后是過濾處理資料:
?
也就是根據Hu(CT)值來篩選我們想要的部位的圖片,其他部位全部抹黑或者抹白(對應代碼中的img_min或者img_max),目的是為了增加對比度.
?
下面來自[3]的代碼,這個代碼是用來進行windowing操作和濾波的:
?
# Viewing Dicom CT images with correct windowingCT image values correspond to [Hounsfield units](https://en.wikipedia.org/wiki/Hounsfield_scale) (HU). But the values stored in CT Dicoms are not Hounsfield units, but instead a scaled version. To extract the Hounsfield units we need to apply a linear transformation, which can be deduced from the Dicom tags.Once we have transformed the pixel values to Hounsfield units, we can apply a *windowing*: the usual values for a head CT are a center of 40 and a width of 80, but we can also extract this from the Dicom headers. from glob import glob import os import pandas as pd import numpy as np import re from PIL import Image import seaborn as sns from random import randrange#checnking the input files print(os.listdir("../input/rsna-intracranial-hemorrhage-detection/"))## Load Data #reading all dcm files into train and text train = sorted(glob("../input/rsna-intracranial-hemorrhage-detection/stage_1_train_images/*.dcm")) test = sorted(glob("../input/rsna-intracranial-hemorrhage-detection/stage_1_test_images/*.dcm")) print("train files: ", len(train)) print("test files: ", len(test))pd.reset_option('max_colwidth') train_df = pd.read_csv('../input/rsna-intracranial-hemorrhage-detection/stage_1_train.csv')def window_image(img, window_center,window_width, intercept, slope):img = (img*slope +intercept)#灰度值轉化為CT輻射強度,轉化后的結果其實可以理解為"醫(yī)用像素值"img_min = window_center - window_width//2 # "-"后面的先計算img_max = window_center + window_width//2 # 下面其實是一個濾波器,過濾掉噪音img[img<img_min] = img_minimg[img>img_max] = img_maxreturn img # 這里的img是一個二維矩陣def get_first_of_dicom_field_as_int(x):#get x[0] as in int is x is a 'pydicom.multival.MultiValue', otherwise get int(x)if type(x) == pydicom.multival.MultiValue:#如果有很多個值return int(x[0])else:return int(x)def get_windowing(data): # 下面是獲取dicom數據庫中某個圖片的各個參數的方式,并不是坐標dicom_fields = [data[('0028','1050')].value, #window centerdata[('0028','1051')].value, #window widthdata[('0028','1052')].value, #interceptdata[('0028','1053')].value] #slope # 上面的這個種(0028,1053)在資料中被稱為Tagreturn [get_first_of_dicom_field_as_int(x) for x in dicom_fields]import pydicom #圖片數據庫 import matplotlib.pyplot as plt print(len(train)) case = 199 # train是個list類型 data = pydicom.dcmread(train[case]) #指定某張照片plt.imshow(img, cmap=plt.cm.bone) print("-------------------------------------1--------------------------------") window_center , window_width, intercept, slope = get_windowing(data)#從dicom數據庫中獲取data的參數#displaying the image img = pydicom.read_file(train[case]).pixel_arrayimg = window_image(img, window_center, window_width, intercept, slope)#windowing操作以及過濾噪聲 plt.imshow(img, cmap=plt.cm.bone) plt.grid(False) print("---------------------------------------2------------------------------") print(data)上述代碼運行后會輸出dicom的信息以及一張顱內圖片的預覽:
---------------------------------------2------------------------------ (0008, 0018) SOP Instance UID UI: ID_00145de6f (0008, 0060) Modality CS: 'CT' (0010, 0020) Patient ID LO: 'ID_e58c888d' (0020, 000d) Study Instance UID UI: ID_c69165e24e (0020, 000e) Series Instance UID UI: ID_49ed8e3bef (0020, 0010) Study ID SH: '' (0020, 0032) Image Position (Patient) DS: ['-125.000000', '-124.697983', '223.549103'] (0020, 0037) Image Orientation (Patient) DS: ['1.000000', '0.000000', '0.000000', '0.000000', '0.927184', '-0.374607'] (0028, 0002) Samples per Pixel US: 1 (0028, 0004) Photometric Interpretation CS: 'MONOCHROME2' (0028, 0010) Rows US: 512 (0028, 0011) Columns US: 512 (0028, 0030) Pixel Spacing DS: ['0.488281', '0.488281'] (0028, 0100) Bits Allocated US: 16 (0028, 0101) Bits Stored US: 16 (0028, 0102) High Bit US: 15 (0028, 0103) Pixel Representation US: 1 (0028, 1050) Window Center DS: "30" (0028, 1051) Window Width DS: "80" (0028, 1052) Rescale Intercept DS: "-1024" (0028, 1053) Rescale Slope DS: "1" (7fe0, 0010) Pixel Data OW: Array of 524288 elements## Visualize Sample Images
TRAIN_IMG_PATH = "../input/rsna-intracranial-hemorrhage-detection/stage_1_train_images/" TEST_IMG_PATH = "../input/rsna-intracranial-hemorrhage-detection/stage_1_test_images/"def view_images(images, title = '', aug = None):width = 5height = 2fig, axs = plt.subplots(height, width, figsize=(15,5))for im in range(0, height * width):data = pydicom.read_file(os.path.join(TRAIN_IMG_PATH,images[im]+ '.dcm'))image = data.pixel_arraywindow_center , window_width, intercept, slope = get_windowing(data)#從dicom中獲取參數image_windowed = window_image(image, window_center, window_width, intercept, slope)i = im // widthj = im % widthaxs[i,j].imshow(image_windowed, cmap=plt.cm.bone) axs[i,j].axis('off')plt.suptitle(title)plt.show() train_df['image'] = train_df['ID'].str.slice(stop=12)#因為圖片名稱的前半部分是ID train_df['diagnosis'] = train_df['ID'].str.slice(start=13)#因為圖片名稱的后半部分是出血類型print("------------------------------------從下面開始每個類型的圖片都看十張------------------------------------------------------")view_images(train_df[(train_df['diagnosis'] == 'epidural') & (train_df['Label'] == 1)][:10].image.values, title = 'Images with epidural')?
下面代碼與上面一句類似,都是瀏覽圖片(結果略)
view_images(train_df[(train_df['diagnosis'] == 'intraparenchymal') & (train_df['Label'] == 1)][:10].image.values, title = 'Images with intraparenchymal')view_images(train_df[(train_df['diagnosis'] == 'intraventricular')& (train_df['Label'] == 1)][:10].image.values, title = 'Images with intraventricular')view_images(train_df[(train_df['diagnosis'] == 'subarachnoid')& (train_df['Label'] == 1)][:10].image.values, title = 'Images with subarachnoid')s'] == 'subdural') & (train_df['Label'] == 1)][:10].image.values, title = 'Images with subarachnoid')?
Reference:
[1]https://radiopaedia.org/articles/windowing-ct
[2]https://stackoverflow.com/questions/10193971/rescale-slope-and-rescale-intercept
[3]https://www.kaggle.com/omission/eda-view-dicom-images-with-correct-windowing
[4]http://www.xctmr.com/baike/ct/d054abd3bf1a96110b623e4cc2b58575.html
[5]https://baike.baidu.com/item/CT值單位/15635363
總結
以上是生活随笔為你收集整理的CT流程与CT图像的windowing操作(转载+整理)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kaggle中的Two-Stage比赛规
- 下一篇: 医学图像-颅内出血(转载+整理)