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()
'AI > Medical' 카테고리의 다른 글
[Medical] 의료 이미지 기술의 이해 : X-Ray, CT, MRI, Ultrasound, e tc... (2) | 2024.05.10 |
---|---|
[Medical] Image Classification for Covid19 Dataset (0) | 2024.01.17 |