介紹如何在 Python 中使用 Pydicom 模組,讀取並顯示 DICOM 檔案中的 Overlay 影像內容與相關資訊。
DICOM 的 Overlays 可以用來儲存最多 16 張單位元(one bit)的影像(群組編號從 6000
、6002
到 601E
),個別的群組(group)中有各自對應的相關資訊元素(例如 Overlay 的影像尺寸等)。
以下我們以 MR-SIEMENS-DICOM-WithOverlays.dcm
這個範例檔為例,示範如何讀取第一張 Overlay(0x6000
)的相關資訊:
import pydicom from pydicom.data import get_testdata_files # 取得示範用 DICOM 影像檔案位置 fpath = get_testdata_files("MR-SIEMENS-DICOM-WithOverlays.dcm")[0] # 讀取 DICOM 影像檔案 ds = pydicom.dcmread(fpath) # 查看所有後設資料 print(ds)
[略] (6000, 0010) Overlay Rows US: 484 (6000, 0011) Overlay Columns US: 484 (6000, 0015) Number of Frames in Overlay IS: "1" (6000, 0022) Overlay Description LO: 'Siemens MedCom Object Graphics' (6000, 0040) Overlay Type CS: 'G' (6000, 0050) Overlay Origin SS: [1, 1] (6000, 0051) Image Frame Origin US: 1 (6000, 0100) Overlay Bits Allocated US: 1 (6000, 0102) Overlay Bit Position US: 0 (6000, 3000) Overlay Data OW: Array of 29282 elements (7fe0, 0010) Pixel Data OW: Array of 468512 elements
凡是在 0x6000
這一個群組的標籤(tags)都是與第一張 Overlay 相關的屬性資料。
Overlay 的影像原始資料可以透過標籤編號直接取得,但是這個原始資料無法直接用於繪圖:
# 取得 (6000,3000) 第一張 Overlay 影像原始資料 raw = ds[0x6000, 0x3000].value
若要顯示 Overlay 影像內容,可以使用 overlay_array()
函數將 Overlay 影像讀取成 NumPy 陣列:
# 將 0x6000 第一張 Overlay 影像轉為 NumPy 陣列 arr = ds.overlay_array(0x6000) # 查看 Overlay 資料維度 arr.shape
(484, 484)
然後再使用 matplotlib
繪圖:
import matplotlib.pyplot as plt # 顯示 Overlay 影像 plt.imshow(arr, cmap = 'gray') plt.show()
若要將 Overlay 的影像轉換為一般的圖片檔案,可以將 NumPy 的陣列乘以 255
之後,儲存為圖檔:
from PIL import Image as im # 建立影像 imdata = im.fromarray(arr * 255) # 儲存至 PNG 圖片檔案 imdata.save('overlay.png')
這樣轉出來的圖片會比較清楚:
若要修改 DICOM 中的 Overlay 影像,可以在修改 NumPy 陣列之後,透過 pack_bits()
將 NumPy 陣列轉為單位元影像格式,再寫回 DICOM 影像中:
# 增加一條直線 arr[10, :] = 1 # 包裝資料 from pydicom.pixel_data_handlers.numpy_handler import pack_bits packed_bytes = pack_bits(arr) # 更新 Overlay 影像資料 ds[0x6000, 0x3000].value = packed_bytes # 儲存 DICOM 檔案 ds.save_as("modified.dcm")