2025, Dec 08 12:01

Как определить оси x, y, z и ориентацию RAS в NIfTI с NiBabel на данных MSD Task01

Как сопоставить оси x, y, z и ориентацию RAS в NIfTI с помощью NiBabel: shape, аффинная матрица, aff2axcodes. Практический пример на MSD Task01 датасете

Понять, какие оси массива соответствуют анатомическим x, y и z в 3D/4D объёмах нейровизуализации, — частая трудность. Для данных MSD Task 01 (Brain Segmentation) в формате NIfTI и с библиотекой NiBabel достаточно посмотреть на форму массива (shape) и аффинное преобразование (affine) — но только если читать их в правильной последовательности.

Пример, который проясняет вопрос

Следующий фрагмент загружает объём и выводит ключевые сведения. Форма и аффинная матрица соответствуют случаю, когда у массива есть три пространственные оси плюс четвёртое измерение.

import nibabel as nbl

file_path = "/kaggle/input/msd-dataset-task-1-brain-tumour segmentation/Task01_BrainTumour/imagesTr/BRATS_001.nii"

vol_nii = nbl.load(file_path)

print("File:", file_path)
print("Shape:", vol_nii.shape)
print("Data type:", vol_nii.get_data_dtype())
print("Voxel spacing:", vol_nii.header.get_zooms())
print("Affine matrix:\n", vol_nii.affine)

Файл: /kaggle/input/msd-dataset-task-1-brain-tumour-segmentation/Task01_BrainTumour/imagesTr/BRATS_001.nii
Форма: (240, 240, 155, 4)
Тип данных: float32
Шаг вокселя: (1.0, 1.0, 1.0, 1.0)
Аффинная матрица:
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]

Что означают оси на самом деле

В NumPy x, y и z соответствуют первой, второй и третьей осям массива. В анатомии принято понимать их так: x — лево/право, y — перед/зад, z — верх/низ. Эти направления задаёт аффинная матрица и вытекающие из неё коды ориентации. Распространённая конвенция — RAS, где положительные оси направлены Right, Anterior и Superior. Разные сканеры или этапы предобработки могут использовать другие соглашения, поэтому чтение аффинной матрицы принципиально важно.

Документация NiBabel по системам координат и аффинным преобразованиям и по работе с изображениями NIfTI — отличный ориентир, если нужно согласовать индексы массива с анатомической ориентацией.

Практический способ проверить оси и ориентацию

Быстрая визуализация помогает почувствовать, какое измерение вы режете. Ниже — тот же подход: загрузить, взять первый объём из 4D-массива и показать центральные срезы по каждой оси NumPy.

import numpy as np
import nibabel as nbl
import matplotlib.pyplot as plt

src_path = "/kaggle/input/msd-dataset-task-1-brain-tumour segmentation/Task01_BrainTumour/imagesTr/BRATS_001.nii"

nii_obj = nbl.load(src_path)
arr_4d = nii_obj.get_fdata()  # x, y, z, t (в нейровизуализации t, скорее всего, время)

vol_3d = arr_4d[..., 0]  # используем первый 3D-объём

cx, cy, cz = (np.array(vol_3d.shape[:3]) // 2).tolist()

def render_planes(planes, names=("x", "y", "z")):
    fig, axs = plt.subplots(1, len(planes))
    for idx, plane in enumerate(planes):
        axs[idx].imshow(plane.T, cmap="gray", origin="lower")
        axs[idx].set_title(f"Numpy axis {names[idx]}")
    plt.suptitle("Center slices for image")

planes = [vol_3d[cx, :, :], vol_3d[:, cy, :], vol_3d[:, :, cz]]
render_planes(planes)
plt.show()

Чтобы увидеть метки ориентации, заданные аффинной матрицей, запросите их напрямую:

# Аффинная матрица
print(nii_obj.affine)

# Коды ориентации (например, RAS)
print(nbl.aff2axcodes(nii_obj.affine))

Откуда берётся путаница

По порядку осей в массиве видно, какая из них первая, вторая и третья, но не видно, что означает рост индексов с анатомической точки зрения. Аффинная матрица связывает индексы вокселей с реальным пространством, и по ней NiBabel выводит коды ориентации. Поэтому 4D-форма вроде (240, 240, 155, 4) читается как x, y, z и четвёртое измерение, а пространственная ориентация определяется аффинной матрицей.

Замечание по датасету, которое помогает

В статье по датасету Medical Segmentation Decathlon сказано:

«Все изображения были транспонированы (без ресемплинга) к наиболее близкой системе координат right-anterior-superior, чтобы направление матрицы данных x–y–z было согласованным (с использованием fslreorient2std), и конвертированы к радиологическому стандарту NIFTI.»

Учитывая это и приведённый выше код, можно трактовать первые три оси загруженного массива как x, y и z, а направление подтверждать с помощью аффинной матрицы и кодов ориентации.

Зачем это важно

Перепутанные оси или игнорирование ориентации могут незаметно перевернуть анатомию, сорвать дальнейший анализ или ввести в заблуждение при просмотре. Проверка формы, аффинной матрицы и кодов ориентации перед работой снижает риск, особенно при переходе между инструментами или наборами данных с разными настройками по умолчанию.

Выводы

Смотрите на форму и аффинную матрицу вместе. В терминах NumPy первые три оси — это x, y и z; используйте NiBabel’s aff2axcodes, чтобы понять их анатомическое направление. Если сомневаетесь, визуализируйте центральные срезы по каждой оси, чтобы сверить интуицию. Если вы работаете с этой задачей MSD, примечание о выравнивании к RAS и согласованном направлении x–y–z — полезная опора, а короткие проверки выше удержат вас на верном пути.