# NIfTIデータセットの作成

このページでは、`datasets`ライブラリを使用して、NIfTI形式（.nii / .nii.gz）の医療画像のデータセットを作成し、共有する方法を示します。

Hugging Face Hub上でデータセットのリポジトリを作成することで、チームやコミュニティの誰とでもデータセットを共有できます。

```py
from datasets import load_dataset

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

NIfTIデータセットを作成するには、一般的に2つの方法があります。

- PythonでローカルのNIfTIファイルからデータセットを作成し、`Dataset.push_to_hub`でアップロードします。
- フォルダベースの規約（1つの例につき1つのファイル）と、それを`Dataset`に変換するための小さなヘルパーを使用します。

> [!TIP]
> [Gated datasets](https://huggingface.co/docs/hub/datasets-gated)ガイドを参照して、ユーザーに連絡先情報の共有を要求することで、データセットへのアクセスを制御できます。

## ローカルファイル

NIfTIファイルへのファイルパスのリストが既に用意されている場合、最も簡単なワークフローは、そのリストから`Dataset`を作成し、そのカラムを`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
```

`Nifti` 機能は `decode` パラメータをサポートしています。`decode=True`（デフォルト）の場合、NIfTI ファイルを `nibabel.nifti1.Nifti1Image` オブジェクトとして読み込みます。`img.get_fdata()` を使用して、画像データを numpy 配列としてアクセスできます。`decode=False` の場合、ファイルパスとバイト列を含む dict が返されます。

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

データセットの準備が完了したら、Hubにプッシュできます:

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

これにより、`data/` フォルダに parquet シャードを含む NIfTI データセットが格納されたデータセットリポジトリが作成されます。

## フォルダの規約とメタデータ

フォルダでデータセットを整理している場合、次のような構造に従うことで、スプリット（train/test/validation）を自動的に作成できます。

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

ラベルやその他のメタデータがある場合は、フォルダ内に`metadata.csv`、`metadata.jsonl`、または`metadata.parquet`を配置し、ファイルをメタデータの行に関連付けられるようにしてください。メタデータには、メタデータファイルの隣にある NIfTI ファイルへの相対パスを含む`file_name`（または`*_file_name`）フィールドが必要です。

`metadata.csv`の例:

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

`Nifti` 機能は、圧縮されたデータセットにも対応しています。各 zip には NIfTI ファイルとメタデータファイルを含めることができます。これは、大規模なデータセットをアーカイブとしてアップロードする場合に便利です。したがって、データセットの構造は次のようになる可能性があります（圧縮ファイルと非圧縮ファイルが混在している場合）：
```
dataset/train/scan_0001.nii.gz
dataset/train/scan_0002.nii
dataset/validation/scan_1001.nii.gz
dataset/test/scan_2001.nii
```

## PyTorchテンソルへの変換

[set_transform()](/docs/datasets/v5.2.0/ja/package_reference/main_classes#datasets.Dataset.set_transform)関数を使用して、データセットのバッチにトランスフォーメーションをオンザフライで適用します:

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

```
これにより、要素へのアクセス（例: `ds[0]`）を行うと、`"nifti_torch"` キーに torch テンソルが返されるようになります。

## NifTI1Imageの使用方法

NifTIは、3次元（または4次元）の脳スキャンの結果を保存するためのフォーマットです。これには3つの空間次元（x、y、z）と、任意の時間次元（t）が含まれます。さらに、ここで与えられる位置はスキャナーに対する相対的なもののみであるため、次元（4、5、6）を使用して実世界の座標系に変換します。

例えば、`matplotlib` を活用して nifti ファイルを可視化できます。以下のようにします:
```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()
```

詳細については、[nibabelのドキュメント](https://nipy.org/nibabel/index.html)、特に[このnibabelチュートリアル](https://nipy.org/nibabel/coordinate_systems.html)を参照してください。---

