🔬 Medical Image/Processing

nibabel affine matrix의 의미와 affine transform 적용하는 방법

복만 2020. 2. 25. 23:26

 

https://nipy.org/nibabel/coordinate_systems.html

 

Neuroimaging in Python — NiBabel 3.0.2dev documentation

Coordinate systems and affines A nibabel (and nipy) image is the association of three things: The image data array: a 3D or 4D array of image data An affine array that tells you the position of the image array data in a reference space. image metadata (dat

nipy.org

위의 문서를 정리한 내용.

 

[요약]

- Image data array는 3D or 4D image이다.

- Affine arrayreference space에서의 image array data의 위치를 알려준다.

- 본 문서는 affine array가 어떻게 reference space에서의 image data의 위치를 알려주는지 기술한다.

 

 

Introducing Someone

- "Someone"이라는 사람의 두 종류의 brain MRI 이미지가 있다고 하자. 각각은 다음과 같다.

    - someones_epi.nii.gz : single EPI volume. shape == (53, 61, 33)

    - someones_anatomy.nii.gz : structural scan. shape == (57, 67, 56)

 

- EPI image와 anatomical image의 각 차원의 center slice를 보면 다음과 같다.

import nibabel as nib
epi_img = nib.load('downloads/someones_epi.nii.gz')
epi_img_data = epi_img.get_fdata()

slice0 = epi_img_data[26, :, :]
slice1 = epi_img_data[:, 30, :]
slice2 = epi_img_data[:, :, 16]

 

순서대로 첫 번째, 두 번째, 세 번째 차원의 center slice

 

순서대로 첫 번째, 두 번째, 세 번째 차원의 center slice

 

- 같은 사람의 image이지만, shape, size, orientation이 서로 다르다.

- 이는 두 image를 획득한 orientation이나 position이 서로 다르기 때문이다.

 

 

 

Voxel coordinates are coordinates in the image data array

- Volume의 각 단위를 voxel이라 한다. (volume + pixel)

- 3D image array는 voxel들로 이루어져 있다. 각각의 voxel은 index를 통하여 접근할 수 있다.

- 각각의 voxel value는 image의 grayscale value를 의미한다.

- 예를 들어, EPI image의 middle voxel value를 다음과 같이 얻을 수 있다.

center_value = epi_img_data[26, 30, 16]

- 이 index를 voxel coordinate라 한다.

 

 

 

Voxel coordinates and points in space

- Voxel coordinate만으로는 절대적인 position을 알 수 없다.

- 앞에서 보았듯, EPI image와 anatomical image의 shape, size, orientation이 서로 다르다.

- 그러므로 우리는 서로 다른 shape, size, orientation을 가지고 있는 두 image를 연관시키기 위해서 affine array를 이용한다.

- 각각의 image에는 affine array가 저장되어 있다. 이것은 image의 voxel coordinate와 reference space와의 관계를 저장하는 array이다.

 

- 다시 말해, affine array는 array (voxel) coordinate와 mm (world) coordinate를 대응시켜주는 역할을 한다.

- array에서의 (0, 0, 0)과 (1, 0, 0) 간의 거리가 world coordinate에서는 몇mm인지를 알려준다.

 

- someones_epi.nii.gz의 affine array는 EPI image와 reference space간의 관계를 담고 있다.

- someones_anatomy.nii.gz의 affine array는 anatomical image와 reference space간의 관계를 담고 있다.

epi_affine = epi_img.affine
>> array([[   3.   ,   0.   ,   0.   , -78.   ],
          [   0.   ,   2.866,  -0.887, -76.   ],
          [   0.   ,   0.887,   2.866, -64.   ],
          [   0.   ,   0.   ,   0.   ,   1.   ]])

 

- 다음을 통하여 voxel size를 알 수 있다.

from nibabel.affines import voxel_sizes
voxel_sizes(epi_affine)
>> array([3.        , 3.00012083, 3.00012083])

 

 

 

The scanner-subject reference space

- 그렇다면 reference space는 어떤 좌표계를 의미할까?

 

- reference space는 3개의 직교 scanner axes를 사용한다.

- 원점 (0, 0, 0)은 magnet isocenter을 사용한다.

- 3개 축의 단위는 모두 milimeter이다.

- 3개의 축을 각각 scanner-bore axis, scanner-floor/ceiling axis, scanner-left/right axis라 한다.

 

scanner axis에 대한 상세한 설명

- 이에 따라 reference space는 scanner XYZ라 불리기도 한다.

 

 

 

The affine matrix as a transformation between spaces

- voxel space coordinate $(i, j, k)$reference space coordinate $(x, y, z)$로 변환시키는 function을 $f$라고 하자.

 

$(x,y,z)=f(i,j,k)$

 

- $f$는 affine transform을 통해 수행된다.

 

-  affine transform은 matrix 연산을 통해 image를 변형한다. 대표적인 몇 개의 affine matrix는 다음과 같다.

 

x, y, z축 방향으로 각각 p, q, r만큼 scaling
z축 기준으로 rotation
y축 기준으로 rotation
x축 기준으로 rotation
x, y, z축 방향으로 각각 a, b, c만큼 translation

 

- affine matrix간의 중첩도 가능하고, 순서는 상관없다.

 

 

- nibabel에서의 4*4 affine matrix $A$는 다음과 같다.

 

 

- m(i, j)는 rotation/scaling, a, b, c는 translation을 의미한다.

 

- 계산방법은 다음과 같다. 

 

 

- 이는 다음과 같이 쓸 수 있다.

 

 

- 다음 코드를 이용해 nibabel에서 affine transform을 적용할 수 있다.

from nibabel.affines import apply_affine
epi_vox_center = (np.array(epi_img_data.shape) - 1) / 2.
apply_affine(epi_img.affine, epi_vox_center)

 

반응형