# Crear un conjunto de datos NIfTI

Esta página muestra cómo crear y compartir un conjunto de datos de imágenes médicas en formato NIfTI (.nii / .nii.gz) usando la biblioteca `datasets`.

Puedes compartir un conjunto de datos con tu equipo o con cualquier persona de la comunidad creando un repositorio de conjuntos de datos en el Hugging Face Hub:

```py
from datasets import load_dataset

dataset = load_dataset("<username>/my_nifti_dataset")
```

Hay dos formas comunes de crear un conjunto de datos NIfTI:

- Crea un conjunto de datos a partir de archivos NIfTI locales en Python y súbelo con `Dataset.push_to_hub`.
- Use una convención basada en carpetas (un archivo por ejemplo) y un pequeño helper para convertirlo en un `Dataset`.

> [!TIP]
> Puedes controlar el acceso a tu conjunto de datos requiriendo que los usuarios compartan primero su información de contacto. Consulta la guía de [Conjuntos de datos con acceso restringido](https://huggingface.co/docs/hub/datasets-gated) para obtener más información.

## Archivos locales

Si ya tienes una lista de rutas de archivos a archivos NIfTI, el flujo de trabajo más sencillo es crear un `Dataset` a partir de esa lista y convertir la columna a la característica `Nifti`.

```py
from datasets import Dataset
from datasets import Nifti

# simple example: create a dataset from file paths
files = ["/path/to/scan_001.nii.gz", "/path/to/scan_002.nii.gz"]
ds = Dataset.from_dict({"nifti": files}).cast_column("nifti", Nifti())

# access a decoded nibabel image (if decode=True)
# ds[0]["nifti"] will be a nibabel.Nifti1Image object when decode=True
# or a dict {'bytes': None, 'path': '...'} when decode=False
```

La función `Nifti` admite un parámetro `decode`. Cuando `decode=True` (el valor predeterminado), carga el archivo NIfTI en un objeto `nibabel.nifti1.Nifti1Image`. Puede acceder a los datos de la imagen como un array de numpy con `img.get_fdata()`. Cuando `decode=False`, devuelve un diccionario con la ruta del archivo y los bytes.

```py
from datasets import Dataset, Nifti

ds = Dataset.from_dict({"nifti": ["/path/to/scan.nii.gz"]}).cast_column("nifti", Nifti(decode=True))
img = ds[0]["nifti"]  # instance of: nibabel.nifti1.Nifti1Image
arr = img.get_fdata()
```

Después de preparar el conjunto de datos, puedes subirlo al Hub:

```py
ds.push_to_hub("<username>/my_nifti_dataset")
```

Esto creará un repositorio de datos que contiene tu conjunto de datos NIfTI con una carpeta `data/` de fragmentos parquet.

## Convenciones de carpetas y metadatos

Si organizas tu conjunto de datos en carpetas, puedes crear divisiones automáticamente (entrenamiento/prueba/validación) siguiendo una estructura como:

```
dataset/train/scan_0001.nii
dataset/train/scan_0002.nii
dataset/validation/scan_1001.nii
dataset/test/scan_2001.nii
```

Si tienes etiquetas u otros metadatos, proporciona un `metadata.csv`, `metadata.jsonl` o `metadata.parquet` en la carpeta para que los archivos puedan vincularse a las filas de metadatos. Los metadatos deben contener un campo `file_name` (o `*_file_name`) con la ruta relativa al archivo NIfTI junto al archivo de metadatos.

Ejemplo de `metadata.csv`:

```csv
file_name,patient_id,age,diagnosis
scan_0001.nii.gz,P001,45,healthy
scan_0002.nii.gz,P002,59,disease_x
```

La función `Nifti` también funciona con conjuntos de datos comprimidos: cada archivo zip puede contener archivos NIfTI y un archivo de metadatos. Esto resulta útil al subir conjuntos de datos grandes como archivos comprimidos. Esto significa que la estructura de su conjunto de datos podría verse así (archivos comprimidos y sin comprimir mezclados):
```
dataset/train/scan_0001.nii.gz
dataset/train/scan_0002.nii
dataset/validation/scan_1001.nii.gz
dataset/test/scan_2001.nii
```

## Conversión a tensores de PyTorch

Use la función [set_transform()](/docs/datasets/v5.2.0/es/package_reference/main_classes#datasets.Dataset.set_transform) para aplicar la transformación sobre la marcha a los lotes del conjunto de datos:

```py
import torch 
import nibabel
import numpy as np

def transform_to_pytorch(example):
    example["nifti_torch"] = [torch.tensor(ex.get_fdata()) for ex in example["nifti"]]
    return example

ds.set_transform(transform_to_pytorch)

```
Ahora, al acceder a los elementos (p. ej. `ds[0]`), se obtendrán tensores de torch en la clave `"nifti_torch"`.

## Uso de NifTI1Image

NifTI es un formato para almacenar el resultado de escaneos cerebrales de 3 (o incluso 4) dimensiones. Esto incluye 3 dimensiones espaciales (x,y,z) y, opcionalmente, una dimensión temporal (t). Además, las posiciones dadas aquí son solo relativas al escáner, por lo que se utilizan las dimensiones (4, 5, 6) para elevarlas a coordenadas del mundo real.

Puede visualizar archivos nifti, por ejemplo, aprovechando `matplotlib` de la siguiente manera:
```python
import matplotlib.pyplot as plt
from datasets import load_dataset

def show_slices(slices):
   """ Function to display row of image slices """
   fig, axes = plt.subplots(1, len(slices))
   for i, slice in enumerate(slices):
       axes[i].imshow(slice.T, cmap="gray", origin="lower")

nifti_ds = load_dataset("<username>/my_nifti_dataset")
for epi_img in nifti_ds:
    nifti_img = epi_img["nifti"].get_fdata()
    show_slices([nifti_img[:, :, 16], nifti_img[26, :, :], nifti_img[:, 30, :]])
    plt.show()
```

Para más información, remitimos al lector a la [documentación de nibabel](https://nipy.org/nibabel/index.html) y, en particular, a [este tutorial de nibabel](https://nipy.org/nibabel/coordinate_systems.html) ---

