介紹如何在 Python 中使用 Pydicom 模組,讀取與編輯 DICOM 影像檔案的內容。
Python 的 Pydicom 模組是一套非常完整的 DICOM 影像檔案處理工具,可以讀取、編輯或寫入 DICOM 檔案,以下是基本的使用教學與範例。
若要安裝 Pydicom 模組,可以使用 pip
安裝:
# 安裝 Pydicom 模組
pip3 install pydicom
另外亦可從 Pydicom 的 GitHub 網站下載 whl
檔案來安裝:
# 以 whl 檔案安裝 Pydicom 模組
pip3 install pydicom-1.4.1-py2.py3-none-any.whl
或是透過 Conda 安裝:
# 透過 Conda 安裝 Pydicom 模組 conda install -c conda-forge pydicom
除了基本的 pydicom
模組之外,如果要進行比較進階的影像資料處理,可能會用的的模組有 numpy
、pillow
、openjpeg
、jpeg
、cython
、CharPyLS
、gdcm
。
pydicom
模組在 1.0 版本之前稱為 dicom
模組,而在 1.0 版之後就改為目前的 pydicom
。這裡我們以 Pydicom 模組附帶的測試影像作為示範,若要取得自己系統上 Pydicom 測試影像的路徑,可以使用 get_testdata_files
函數,而在知道 DICOM 影像的路經之後,即可使用 dcmread
函數讀取 DICOM 檔案,並查看所有的後設資料(metadata):
from pydicom import dcmread from pydicom.data import get_testdata_files # 取得 Pydicom 附帶的 DICOM 測試影像路徑 filename = get_testdata_files('MR_small.dcm')[0] # 讀取 DICOM 檔案 ds = dcmread(filename) # 列出所有後設資料(metadata) print(ds)
(0008, 0008) Image Type CS: ['DERIVED', 'SECONDARY', 'OTHER'] (0008, 0012) Instance Creation Date DA: '20040826' (0008, 0013) Instance Creation Time TM: '185434' (0008, 0014) Instance Creator UID UI: 1.3.6.1.4.1.5962.3 (0008, 0016) SOP Class UID UI: MR Image Storage [略]
這裡透過 dcmread
函數讀取出來的 ds
是一個資料集(dataset),裡面包含了 DICOM 的各種資訊以及影像資料。
我們也可以直接取出指定欄位的資料,例如取得病人姓名(Patient’s Name)欄位的資料:
# 輸出 Patient Name 資料 print(ds.PatientName)
CompressedSamples^MR1
另外也可以參考 DICOM Tags 對照表,直接以 Tag 的十六進位碼來取出指定欄位:
# 輸出 Patient Name 資料 print(ds[0x10,0x10].value) # 輸出 Patient Name 資料 print(ds[0x100010].value)
DICOM 的後設資料可以直接更改:
# 更改 Patient Name 資料 ds.PatientName = "anonymous" print(ds.PatientName)
anonymous
若要刪除指定的 DICOM tag 資料,可以使用 del
:
# 刪除 Patient Name 欄位 del ds[0x10,0x10]
使用 dcmread
從 DICOM 檔案讀取出來的資料集中,就包含了影像的資料,我們可以透過資料集的 PixelData
(或是 FloatPixelData
、DoubleFloatPixelData
)來取得原始的影像資料,但是從原始的 DICOM 資料讀取,還需要考慮各種資料格式的問題,處理起來非常複雜。
Pydicom 為了讓讀取 DICOM 影像更為方便,提供了 pixel_array
這個 NumPy 陣列,使用者從這裡就可以直接取得影像的資料,不需要處理底層資料格式的問題,配合 matplotlib
即可立即繪製影像資料:
import matplotlib.pyplot as plt # 以 matplotlib 繪製影像 plt.imshow(ds.pixel_array) plt.show()
若要編輯 DICOM 影像資料,可以直接透過資料集的 pixel_array
來處理,例如將影像的大小縮小:
# 縮小影像 data_downsampling = ds.pixel_array[::4, ::4] # 將縮小的影像放入原來的 DICOM 資料集 ds.PixelData = data_downsampling.tobytes() # 更新影像大小 ds.Rows, ds.Columns = data_downsampling.shape
若編輯 DICOM 資料集的內容之後,要將結果儲存起來,可以使用 save_as
函數:
# 另存 DICOM 檔案 ds.save_as("de-identification.dcm")