# Criar um conjunto de dados NIfTI

Esta página mostra como criar e compartilhar um conjunto de dados de imagens médicas no formato NIfTI (.nii / .nii.gz) usando a biblioteca `datasets`.

Você pode compartilhar um conjunto de dados com sua equipe ou com qualquer pessoa da comunidade criando um repositório de conjunto de dados no Hugging Face Hub:

```py
from datasets import load_dataset

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

Existem duas formas comuns de criar um conjunto de dados NIfTI:

- Crie um dataset a partir de arquivos NIfTI locais em Python e faça o upload com `Dataset.push_to_hub`.
- Use uma convenção baseada em pastas (um arquivo por exemplo) e um pequeno auxiliar para convertê-la em um `Dataset`.

> [!TIP]
> Você pode controlar o acesso ao seu conjunto de dados exigindo que os usuários compartilhem primeiro suas informações de contato. Consulte o guia [Conjuntos de dados com controle de acesso](https://huggingface.co/docs/hub/datasets-gated) para mais informações.

## Arquivos locais

Se você já tem uma lista de caminhos de arquivos para arquivos NIfTI, o fluxo de trabalho mais simples é criar um `Dataset` a partir dessa lista e converter a coluna para o recurso `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
```

O recurso `Nifti` suporta um parâmetro `decode`. Quando `decode=True` (o padrão), ele carrega o arquivo NIfTI em um objeto `nibabel.nifti1.Nifti1Image`. Você pode acessar os dados da imagem como um array numpy com `img.get_fdata()`. Quando `decode=False`, ele retorna um dict com o caminho do arquivo e os 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()
```

Após preparar o conjunto de dados, você pode enviá-lo para o Hub:

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

Isso criará um repositório de dataset contendo seu dataset NIfTI com uma pasta `data/` de shards em parquet.

## Convenções de pastas e metadados

Se você organizar seu dataset em pastas, pode criar splits automaticamente (train/test/validation) seguindo uma estrutura como:

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

Se você tiver rótulos ou outros metadados, forneça um `metadata.csv`, `metadata.jsonl` ou `metadata.parquet` na pasta para que os arquivos possam ser vinculados às linhas de metadados. Os metadados devem conter um campo `file_name` (ou `*_file_name`) com o caminho relativo para o arquivo NIfTI ao lado do arquivo de metadados.

Exemplo 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
```

O recurso `Nifti` também funciona com datasets compactados — cada arquivo zip pode conter arquivos NIfTI e um arquivo de metadados. Isso é útil ao fazer upload de datasets grandes como arquivos compactados. Isso significa que a estrutura do seu dataset pode ser assim (arquivos compactados e não compactados misturados):
```
dataset/train/scan_0001.nii.gz
dataset/train/scan_0002.nii
dataset/validation/scan_1001.nii.gz
dataset/test/scan_2001.nii
```

## Convertendo para tensores do PyTorch

Use a função [set_transform()](/docs/datasets/main/pt/package_reference/main_classes#datasets.Dataset.set_transform) para aplicar a transformação em tempo real aos lotes do conjunto de dados:

```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)

```
Acessar elementos agora (por exemplo, `ds[0]`) retornará tensores torch na chave `"nifti_torch"`.

## Uso de NifTI1Image

NifTI é um formato para armazenar o resultado de exames de imagem cerebral em 3 (ou até 4) dimensões. Isso inclui 3 dimensões espaciais (x,y,z) e, opcionalmente, uma dimensão temporal (t). Além disso, as posições fornecidas aqui são apenas relativas ao scanner, portanto, as dimensões (4, 5, 6) são usadas para elevar isso a coordenadas do mundo real.

Você pode visualizar arquivos nifti, por exemplo, aproveitando o `matplotlib` da seguinte forma:
```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 mais leituras, remetemos à [documentação do nibabel](https://nipy.org/nibabel/index.html) e, em especial, a [este tutorial do nibabel](https://nipy.org/nibabel/coordinate_systems.html) ---

