의료 영상을 다루다보니 두 영상 간 정합(registration)을 해야하는 상황이 많이 생깁니다.
ANTs는 의료 영상 처리, 특히 정합 작업에 있어 세계적으로 가장 많이 사용되는 도구인데요, ANTsPy는 파이썬에서 지원하는 ANTs 라이브러리라고 보시면 됩니다.
Registration이란?
정합(registration)이란 서로 다른 시간, 장비, 또는 모달리티(CT, MR)로 얻은 이미지를 같은 공간 좌표계로 맞추는 과정을 의미합니다.
정합을 통해 기대하는 것은 아래 3가지 입니다.
- 원점(origin) 일치
- FOV 일치
- 시리즈 내 슬라이스 장수 일치
예시를 통해 살펴보겠습니다.
<Before registration>
→ 전체 장수 불일치, FOV 불일치, 원점 불일치
<After registration>
→ 전체 장수 일치, FOV 일치, 원점 일치
ANTsPy를 활용한 기본 Registration 예시
import os
import ants
import SimpleITK as sitk
import numpy as np
import nibabel as nib
def get_dicom_series_img(data_path):
reader = sitk.ImageSeriesReader()
reader.SetImageIO('GDCMImageIO')
try:
dicom_names = reader.GetGDCMSeriesFileNames(data_path)
reader.SetFileNames(dicom_names)
dicom_series_img = reader.Execute()
return dicom_series_img
except RuntimeError:
print("data_path", data_path)
def change_sitk_to_ants_img(dicom_series_img):
dicom = sitk.GetArrayFromImage(dicom_series_img).astype(np.float64)
dicom = dicom.T
dicom_spacing = sitk.Image.GetSpacing(dicom_series_img)
dicom_origin = sitk.Image.GetOrigin(dicom_series_img)
dicom_direction = sitk.Image.GetDirection(dicom_series_img)
dicom_direction = np.array(dicom_direction).reshape(3,3)
ants_image = ants.from_numpy(dicom, spacing=dicom_spacing, origin=dicom_origin, direction=dicom_direction)
return ants_image
def save_image(image: ants.ANTsImage, save_path: str):
"""
Save Ants Image on Save Path
:param image:
:param save_path:
:return:
"""
if os.path.isfile(save_path):
print("file already exist")
else:
os.makedirs(os.path.dirname(save_path), exist_ok=True)
nib.save(image, save_path)
print(f"save transformed image to {save_path} complete...")
def converse(fixed_domain, moving_domain, data_path):
fixed_data_path = f'{data_path}/0.raw/{fixed_domain}'
moving_data_path = f'{data_path}/0.raw/{moving_domain}'
print('')
print(f"fixed data path is {fixed_data_path}")
print(f"moving data path is {moving_data_path}")
fixed_img = get_dicom_series_img(fixed_data_path)
moving_img = get_dicom_series_img(moving_data_path)
fixed_img = change_sitk_to_ants_img(fixed_img)
moving_img = change_sitk_to_ants_img(moving_img)
moving_img.set_origin((0,0,0))
tx = ants.registration(fixed=fixed_img, moving=moving_img, type_of_transform='TRSAA') # TRSAA / Rigid / SyN
warped_moving_image = ants.apply_transforms(fixed=fixed_img, moving=moving_img, transformlist=tx['fwdtransforms']) # 'linear'(default) / interpolator='bSpline'
fixed_file_name = f'preprocessed_{fixed_domain}.nii.gz'
moving_file_name = f'preprocessed_{moving_domain}.nii.gz'
fixed_output_path = f'{data_path}/1.preprocess/nifti/{fixed_file_name}'
moving_output_path = f'{data_path}/1.preprocess/nifti/{moving_file_name}'
save_image(fixed_img, fixed_output_path)
save_image(warped_moving_image, moving_output_path)
if __name__ == "__main__":
fixed_domain = 'NECT'
moving_domain = 'T2'
data_path = '/Brain/stroke_data/S0001'
converse(fixed_domain, moving_domain, data_path)
ants.registration
변환 행렬을 구하는 과정
<필수 옵션>
- fixed : 기준이 되는 이미지
- moving : 맞춰지는 이미지
- type_of_transform : 정합 방식
- Translation : (평행)이동
- Rigid : Rotation(회전) + Translation(이동)
- Similarity : Scaling (늘리거나 줄이기) + Rotation + Translation
- Affine : Rigid + Scaling + Shear(기울이기)
- TRSAA : Translation → Rigid → Similarity → Affine → Affine
- SyN : Affine + deformable transformation (optimization metric으로 mutual information 사용)
이렇게 만들어진 output 변수(ex. tx)는 tx['fwdtransforms'] 형태로 apply_transforms 메서드에 포함시켜 정합에 사용됩니다.
'Medical Imaging > Preprocess' 카테고리의 다른 글
의료 영상 데이터 전처리 방법 - Resize, Resample, Normalization, Gamma Correction, Adaptive Equalization (0) | 2025.01.25 |
---|