본문 바로가기
AI/Medical

SimpleITK : 의료 이미지 분석을 위한 라이브러리

by Foxy현 2024. 10. 10.
728x90
반응형

 

 

What is SimpleITK?

 

SimpleITK는 의료 이미지 분석을 위한 라이브러리입니다.

다양한 의료 이미지 형식을 지원하며, 이미지 처리, 세그멘테이션, 정합 등의 기능을 제공합니다.

  • 주요 특징:
    • 다양한 이미지 포맷 지원 (DICOM, NIFTI, JPEG, PNG 등)
    • 이미지 처리(Filtering, Segmentation) 및 정합(Registration) 기능 제공
    • 2D 및 3D 이미지를 다룸

How to install SimleITK?

!pip install SimpleITK

 

 

또한 이렇게 설치된 것을 아래의 코드를 통해 확인할 수 있습니다.

 

import SimpleITK as sitk

print("SimpleITK Version : ", sitk.Version())

 

 


Read Data

이번 코드에서는 dicom 파일을 다룰 예정입니다.

 

dicom 파일은 환자의 정보나 이미지의 정보에 관한 Meta Data가 포함되어 있는것이 특징입니다.

 

또한 고해상도 데이터를 다루기에 큰 용량을 가지고 있습니다.

 

 

 

위와 같은 코드를 입력하면 모든 메타 값이 출력이 됩니다.

 

  • LoadPrivateTagsOn() : Load all Private Tags from DICOM file.
  • ReadImageInformation() : Read Image Information and meta data.
  • GetMetaDataKeys() : Return all the meta data on DICOM file.

또한 다음처럼 Key를 통해 해당 내용에 접근할 수도 있습니다.

 


 

Visualization Data

 

이 메타데이터에는 Image 값도 포함됩니다.

 

하지만, ReadImage라는 함수를 사용하는 것이 더 간단합니다.

 

이미지를 확인하는 코드는 아래와 같습니다.

 

 

 

Image Preprocessing

Medical 이미지는 preprocessing이 정말 중요한 작업입니다.

noise를 줄이고, Image Resolution을 높이며, 중요한 feature들을 명확하게 할 수 있습니다. 

이 작업을 통해 model의 performance를 올릴 수 있습니다.

 

그중 여러 방법을 소개하려고 합니다.

 

Filtering

필터링은 이미지의 노이즈를 줄이며, 흔히 Gaussian, Median, Mean 필터라는 것들을 사용합니다.

 

  • Gaussian Filter : noise 제거를 통해 이미지가 부드러워집니다.
gaussian_filtered_image = sitk.DiscreteGaussian(image, variance=2.0)

original_array = sitk.GetArrayFromImage(image)[0]
gaussian_array = sitk.GetArrayFromImage(gaussian_filtered_image)[0]

fig, axes = plt.subplots(1, 2, figsize=(10, 5))

# 원본 이미지 시각화
axes[0].imshow(original_array, cmap='gray')
axes[0].set_title('Original Image')
axes[0].axis('off')

# 가우시안 필터 이미지 시각화
axes[1].imshow(gaussian_array, cmap='gray')
axes[1].set_title('Gaussian Filtered Image')
axes[1].axis('off')

plt.show()

 

  • Median Filter : 적당한 노이즈 제거를 통해 edge를 보존합니다.
image_2d = image[:, :, 0]

# 미디안 필터 적용 (2D 슬라이스에 적용, 반경을 [2, 2]로 설정)
median_filtered_image = sitk.Median(image_2d, [2, 2])

# 시각화: 원본 이미지 및 필터링된 이미지 비교
original_array = sitk.GetArrayFromImage(image_2d)
median_array = sitk.GetArrayFromImage(median_filtered_image)

# 비교 시각화
fig, axes = plt.subplots(1, 2, figsize=(10, 5))
axes[0].imshow(original_array, cmap='gray')
axes[0].set_title('Original 2D Slice')
axes[0].axis('off')

axes[1].imshow(median_array, cmap='gray')
axes[1].set_title('Median Filtered Image')
axes[1].axis('off')

plt.show()

 

  • Mean Filter : 노이즈를 줄이고 부드럽게 만듭니다.
image_2d = image[:, :, 0]

mean_filtered_image = sitk.Mean(image_2d, [2, 2])

# 시각화: 원본 이미지 및 필터링된 이미지 비교
original_array = sitk.GetArrayFromImage(image_2d)
mean_array = sitk.GetArrayFromImage(median_filtered_image)

# 비교 시각화
fig, axes = plt.subplots(1, 2, figsize=(10, 5))
axes[0].imshow(original_array, cmap='gray')
axes[0].set_title('Original 2D Slice')
axes[0].axis('off')

axes[1].imshow(mean_array, cmap='gray')
axes[1].set_title('Mean Filtered Image')
axes[1].axis('off')

plt.show()

 

 

Threshold

Threshold는 주어진 임계치 값을 기준으로 이진으로 만드는 세그멘테이션 기법입니다. 

 

import SimpleITK as sitk
import matplotlib.pyplot as plt

# DICOM 이미지 불러오기
image = readDicom.checkDicom('/Users/foxyhyun/Neurophotonics/HeartDisease/data/patient/JEONG_KYUNGTAE.MR.YUMC_Cardiac_Vi.2.1.2023.04.28.08.47.45.431.66981158.dcm')
# SimpleITK 이미지에 대해 이진화(Binary Threshold) 적용

binary_image = sitk.BinaryThreshold(image, lowerThreshold=50, upperThreshold=250, insideValue=1, outsideValue=0)

binary_image_array = sitk.GetArrayFromImage(binary_image)

plt.figure(figsize=(5,5))
plt.imshow(binary_image_array[0], cmap='gray')  # 2D 이미지를 시각화
plt.title('DICOM Image')
plt.axis('off')  # 축 제거
plt.show()

 

 

 

Clipping

Clipping은 픽셀의 값을 제한된 범위로 제한하는 방법입니다.

의미 없는 이상치 값을 제거할 때 사용되며, 특정 value를 가진 부분을 강조하기 위해 사용합니다.

 

import SimpleITK as sitk
import matplotlib.pyplot as plt

# DICOM 이미지 불러오기
image = readDicom.checkDicom('/Users/foxyhyun/Neurophotonics/HeartDisease/data/patient/JEONG_KYUNGTAE.MR.YUMC_Cardiac_Vi.2.1.2023.04.28.08.47.45.431.66981158.dcm')
# SimpleITK 이미지에 대해 이진화(Binary Threshold) 적용


# 픽셀 값 범위를 -500에서 500 사이로 클리핑 (CT 이미지에 유용)
clipped_image = sitk.Clamp(image, lowerBound=-500, upperBound=500)
clipped_image_array = sitk.GetArrayFromImage(clipped_image)

plt.figure(figsize=(5,5))
plt.imshow(clipped_image_array[0], cmap='gray')  # 2D 이미지를 시각화
plt.title('DICOM Image')
plt.axis('off')  # 축 제거
plt.show()

 

 

Histogram Equalization

빈번한 빈도수의 value를 평평하게 쪼개는 방법입니다.

어두운 부분은 밝게, 밝은 부분은 어둡게 만드는 방법입니다.

이렇게 해서 feature를 쉽게 볼 수 없는 부분도 볼 수 있습니다.

 

import cv2
import SimpleITK as sitk
import numpy as np
import matplotlib.pyplot as plt

# DICOM 이미지 불러오기
image = readDicom.checkDicom('/Users/foxyhyun/Neurophotonics/HeartDisease/data/patient/JEONG_KYUNGTAE.MR.YUMC_Cardiac_Vi.2.1.2023.04.28.08.47.45.431.66981158.dcm')

# SimpleITK 이미지를 Numpy 배열로 변환
image_array = sitk.GetArrayFromImage(image)

# 픽셀 값을 8-bit 범위로 변환 (0-255)
# min/max 값 기준으로 스케일링하여 uint8로 변환
image_8bit = np.uint8(255 * (image_array - np.min(image_array)) / (np.max(image_array) - np.min(image_array)))

# OpenCV의 히스토그램 평활화 적용 (첫 번째 슬라이스에 적용)
equalized_image = cv2.equalizeHist(image_8bit[0])

# 3D 이미지인 경우, 각 슬라이스에 대해 히스토그램 평활화 적용
equalized_image_3d = [cv2.equalizeHist(slice) for slice in image_8bit]

# 결과 시각화 (첫 번째 슬라이스)
plt.figure(figsize=(5, 5))
plt.imshow(equalized_image_3d[0], cmap='gray')
plt.title('Histogram Equalized (First Slice)')
plt.axis('off')
plt.show()

 

 

 

 

 

728x90
반응형