1 분 소요

Dicom

Header & Pixel array

Data 는 Kaggle 에서 받아서 사용했다.

import pydicom

dicom_path = 'dicom_dir/ID_0016_AGE_0063_CONTRAST_1_CT.dcm'
ds = pydicom.dcmread(dicom_path)
print(ds)

ds 라는 객체에 dicom header 정보와 pixel 값까지 담긴다.
Dicom tag나 attribute를 사용해 원하는 헤더 정보를 볼 수 있음.

Dicom 파일의 pixel 값을 얻는 것은 두가지 방법이 있다.

import pydicom
import SimpleITK as sitk

# 1. pydicom 이용
ds = pydicom.read_file(dicom_path)
s = ds.RescaleSlope
b = ds.RescaleIntercept
image1 = s * ds.pixel_array + b

# 2. SimpleITK 이용
image2 = sitk.GetArrayFromImage(sitk.ReadImage(dicom_path)).squeeze()

# 그림으로 표현
plt.figure(figsize=(14,7))
plt.subplot(1,2,1)
plt.title('Pixel array(pydicom)', fontsize=20)
plt.imshow(image1, cmap='gray')
plt.axis('off')

plt.subplot(1,2,2)
plt.title('Pixel array(sitk)', fontsize=20)
plt.imshow(image2, cmap='gray')
plt.axis('off')

plt.tight_layout()
plt.show()


Windowing

그림과 같이 window center와 window width를 지정해 주어서 특정 영역을 더 잘 볼 수 있게 하는 것이 windowing이다.
CT 영상들은 12 비트로 저장(range 4296)되기 때문에 -3024 부터 1272 의 값을 가진다. Dicom file을 읽어올때 pydicom은 int16 or uint16, sitk는 int32로 읽어온다.
또 pydicom은 Rescaleslope 이나 intercept가 따로 존재해서 더해 줘야 하지만 sitk는 array값 그대로 가져온다.
pixel array 값을 다 불러오고 나면 -3024 부터 1272 의 value를 가지는데 여기서 window를 설정 해 화면에 다르게 보여 줄 수 있다.

import numpy as np

def get_array(dicom_path : str) -> np.array : 
    return sitk.GetArrayFromImage(sitk.ReadImage(dicom_path)).squeeze()


def windowing(image: np.array, window_center: int, window_width: int) -> np.array : 
    lower = window_center - window_width/2
    upper = window_center + window_width/2
    
    # uint8로 저장하기 위해 255를 곱해줌 (0~255 range)
    image = ((np.clip(image, lower, upper) - lower) / window_width) * 255
    return np.array(image, dtype = np.uint8)

원본과 서로 다른 window 2개를 화면에 나타 내 보았다.

abdomen_wc, abdomen_ww = 60, 400
brain_wc, brain_ww = 40, 80

original_img = get_array(dicom_path)
abdomen = windowing(original_img, abdomen_wc, abdomen_ww)
brain = windowing(original_img, brain_wc, brain_ww)

plt.figure(figsize=(18,6))
plt.subplot(1,3,1)
plt.title('Defualt', fontsize=20)
plt.imshow(original_img, cmap='gray')
plt.axis('off')

plt.subplot(1,3,2)
plt.title('Abdomen window', fontsize=20)
plt.imshow(abdomen, cmap='gray')
plt.axis('off')

plt.subplot(1,3,3)
plt.title('Brain window', fontsize=20)
plt.imshow(brain, cmap='gray')
plt.axis('off')

plt.tight_layout()
plt.show()

카테고리:

업데이트:

댓글남기기