๐ฉปfMRI
1. Python for (f)MRI analysis
date
Apr 14, 2023
slug
fmri-glm-1
author
status
Public
tags
NI-edu
Dartbrain
summary
Briefly learn about the nifti files
type
Post
thumbnail
category
๐ฉปfMRI
updatedAt
Apr 18, 2023 05:40 AM
1.1 What is โniftiโ1.2 The three parts of nifti images1.2.1 The header with metadata1.2.2 The image data1.2.3 The affine
1.1 What is โniftiโ
- nifti ํ์ผ(.nii or .nii.gz)์ ๋ด๋ก์ด๋ฏธ์ง ํจํค์ง์ ์๋ก์ด ํ์ค ๋ฒ์ ์
- fMRI ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ์ ์ฒซ๋ฒ์งธ ๋จ๊ณ
- ์ค์บ๋ ์ ์ฉ ํ์ผ(DCM/PAR/REC)๋ฅผ nifti ํ์ผ๋ก ๋ณํ(dcm2niix ํจํค์ง ํ์ฉ)
- + afni_proc.py์์ ํธํ๊ฒ preprocessing์ ํ ์ ์์
- ์๋์ ์์๋ .nii files๋ฅผ ๋ถ๋ฌ์ค๋ ์ฝ๋์
import nibabel as nib
mri_file = 'anat.nii.gz'
img = nib.load(mri_file)
print(type(img))
>>> <class 'nibabel.nifti1.Nifti1Image'>
print(img.shape)
>>> (240, 240, 220) # x, y ์ถ์ 240๊ฐ, z ์ถ์ 220๊ฐ์ voxel ๋ฐ์ดํฐ ์กด์ฌ1.2 The three parts of nifti images
1.2.1 The header with metadata
- ํค๋๋ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์์
- ๋ฉํ๋ฐ์ดํฐ: ๋ฐ์ดํฐ์ ๊ดํ ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ(ex. ์คํ ๋จ์, ๋ณต์ ์ฌ์ด์ฆ ๋ฑ)
# ์์์ ์ด๋ฏธ์ง๋ก ๋ณํํ ๋ฐ์ดํฐ์ ํค๋๋ฅผ ๋ถ๋ฌ์ด
hdr = img.header
hdr.get_zooms()
>>> (1.0, 1.0, 1.0) # 1x1x1mm MRI ํ์ผ์
# get_xyzt_units(): x, y, z(spatial), t(time) ์ฐจ์ ๋จ์ ์ ๋ณด
hdr.get_xyzt_units()
>>> ('mm', 'sec')1.2.2 The image data
- MRI ์ค์บ ํ์ผ(์ฌ์ง, ์์)์ 3D/4D-array๋ก ์ ์ฅ๋์ด ์์
- ์ ํธ์ ์ ๋์์น๋ณด๋ค ์ฃผ๋ณ๊ณผ์ ์๋์ ๋น๊ต ์์น๊ฐ ๋ ์ค์ํจ
img_data = img.get_fdata()
print(type(img_data))
>>> <class 'numpy.ndarray'> # ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ numpy array๋ก ๊ตฌ์ฑ๋จ
print(img_data.shape)
>>> (240, 240, 220)- ์์
# ํน์ ์ถ์ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ผ์ด์ฑ
mid_slice_x = img_data[119, :, :] # ์ฒซ๋ฒ์งธ ๋ณต์
์ถ(x)์ 120๋ฒ์งธ ๋ฐ์ดํฐ
plt.imshow(mid_slice_x.T, cmap='gray', origin='lower') # Transposeํด์ ์๊ฐํํ๊ธฐ
# ํน์ ์์ญ์ ๊ธฐ์ค์ผ๋ก ๋ชจ๋ ์๊ฐ์ ์ฌ๋ผ์ด์ฑ
mid_vox_ts = f_img_data[39, 39, 21, :] # (x, y, z)=(40, 40, 22)๋ฒ์งธ ๋ณต์
์ ๋ชจ๋ ์๊ฐ์์์ ๋ฐ์ดํฐ
plt.plot(mid_vox_ts, 'o-', ms=4) # ํน์ ์์ญ์ ๊ธฐ์ค์ผ๋ก ์๊ฐ ์์ผ๋ก์ ์ ํธ ๊ฐ๋
ย
ย

ย
1.2.3 The affine
fig, ax = plt.subplots(ncols=3, figsize=(15, 5))
ax[0].imshow(img_data[69, :, :].T, origin='lower', cmap='gray')
ax[1].imshow(img_data[:, 99, :].T, origin='lower', cmap='gray')
ax[2].imshow(img_data[:, :, 99].T, origin='lower', cmap='gray')
fig.tight_layout()
- ์์ ์ฒซ ๋ฒ์งธ ์ฌ์ง์ ๋ถ์ํ ๋, ๋์ ์ผ์ชฝ์ ๋ณด๊ณ ์๋์ง ์ค๋ฅธ์ชฝ์ ๋ณด๊ณ ์๋์ง ์ค๋ช ํ ์ ์์
- ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์ affine matrix๋ฅผ ํ์ฉํจ
- ์ฌ๊ธฐ์ ๊ฐ์์ ์ขํ๋(x, y, z) ๊ฐ์์ ์ฐจ์์์ ๋ช๋ฒ์งธ ์ฐจ๋ก(์ธ๋ฑ์ค, i, j, k)์
ย
- ์ฐธ๊ณ ๋ก image data๋ ์ฒซ ๋ฒ์งธ ์ถ์ left to right, ๋ ๋ฒ์งธ ์ถ์ posterior to anterior, ์ธ ๋ฒ์งธ ์ถ์ inferior to superior์ผ๋ก ๋ฐ์ดํฐ๊ฐ ์์๋๋ก ๊ตฌ์ฑ๋์ด ์์
- affine matrix๋ฅผ ํตํด ์ ๊ฐ์ด๋ฐ(isocenter)๋ฅผ ์ค์ฌ์ผ๋ก RAS+(Right, Anterior, Superior)์ ๋ถํธ๋ก ์์น๋ฅผ ํ์ ํ ์ ์์
np.set_printoptions(suppress=True, precision=3) # 3์งธ์๋ฆฌ์์ ๋ฐ์ฌ๋ฆผ
A = img.affine
print(A)
>>>
[[ -0.999 -0.035 -0.006 122.245]
[ -0.035 0.997 0.066 -117.457]
[ -0.004 -0.066 0.998 -51.112]
[ 0. 0. 0. 1. ]]
xyz1 = A @ np.array([69, 119, 109, 1])
print(xyz1)
>>> [48.472 5.972 49.516 1. ]- x์ ์ขํ๋ 48.472๋ก, ์ค์ ๋ก ์ค์ฌ์ผ๋ก๋ถํฐ ์ค๋ฅธ์ชฝ์ผ๋ก 48.472mm ๋งํผ ๊ฑฐ๋ฆฌ๊ฐ ๋จ์ด์ ธ ์์