Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors

Store metadata in NIfTI and NRRD

Guide to storing custom metadata in NIfTI and NRRD files after DICOM conversion

Store metadata in NIfTI and NRRD is a header write: put a few keys you choose into a NIfTI Nifti1Extension, or onto an NRRD with SetMetaData. This page is that how-to. It is not “convert DICOM to NIfTI.”

If you meant a plain convert without extra tags → how to convert DICOM to NIfTI. dcm2niix already keeps acquisition context in a BIDS sidecar. This page is the other write: fields you attach yourself.

Why bother

A classic DICOM → NIfTI/NRRD convert keeps the pixels and the affine and drops patient tags. That strip is the right default (it is half of anonymization). Some pipelines still need one or two fields to travel with the volume — a series description, an acquisition date you control — without putting the file back into DICOM.

The keys below are placeholders you fill. They are not a dump of (0010,0010) Patient’s Name. Do not copy identifiers you just stripped.

Format Call What it stores
NIfTI Nifti1Extension(40, …) on header.extensions A JSON blob (here, base64) inside the NIfTI header
NRRD image.SetMetaData(key, value) Plain key/value on the NRRD header

Environment

python -m venv nifti_nrrd_meta
source nifti_nrrd_meta/bin/activate   # Windows: nifti_nrrd_metaScriptsactivate
pip install SimpleITK nibabel numpy

Sanity check: import SimpleITK as sitk, nibabel as nib, numpy as np, json, base64. Tutorial repo: pycadd/YouTube-Tutorials — nifti_nrrd_metadata.

NIfTI: Nifti1Extension

SimpleITK reads the series so we have pixels, spacing, direction, and origin. The job on this page starts after that: build the affine, wrap a Nifti1Image, append an extension, save.

import base64
import json

import SimpleITK as sitk
import nibabel as nib
import numpy as np


class SimpleDicomToNiftiConverter:
    def __init__(self, dicom_folder, output_nifti):
        self.dicom_folder = dicom_folder
        self.output_nifti = output_nifti

    def convert(self):
        reader = sitk.ImageSeriesReader()
        dicom_names = reader.GetGDCMSeriesFileNames(self.dicom_folder)
        reader.SetFileNames(dicom_names)
        image = reader.Execute()

        spacing = image.GetSpacing()
        direction = image.GetDirection()
        origin = image.GetOrigin()
        affine = np.eye(4)
        affine[:3, :3] = np.array(direction).reshape(3, 3) * spacing
        affine[:3, 3] = origin

        image_array = sitk.GetArrayFromImage(image)
        nifti_image = nib.Nifti1Image(image_array, affine)

        # Keys you choose. Not a copy of the DICOM patient tags.
        custom_metadata = {
            "SeriesDescription": "T1w research export",
            "AcquisitionDate": "20260115",
        }
        json_str = json.dumps(custom_metadata)
        encoded_json = base64.b64encode(json_str.encode("utf-8")).decode("utf-8")
        nifti_extension = nib.nifti1.Nifti1Extension(40, encoded_json.encode("utf-8"))
        nifti_image.header.extensions.append(nifti_extension)

        nib.save(nifti_image, self.output_nifti)
        print("wrote", self.output_nifti)

Code 40 is a user-defined NIfTI extension. The payload here is base64(JSON) so the bytes stay printable. A reader that does not know the extension still opens the volume; it just ignores the blob. To read it back: walk nifti_image.header.extensions, decode the base64, json.loads.

SeriesDescription and AcquisitionDate are examples. Replace them with the two fields your pipeline actually needs. Patient name / ID do not belong here.

NRRD: SetMetaData

NRRD stores key/value pairs on the image. Same reader, no nibabel.

import SimpleITK as sitk


class SimpleDicomToNrrdConverter:
    def __init__(self, dicom_folder, output_nrrd):
        self.dicom_folder = dicom_folder
        self.output_nrrd = output_nrrd

    def convert(self):
        reader = sitk.ImageSeriesReader()
        dicom_names = reader.GetGDCMSeriesFileNames(self.dicom_folder)
        reader.SetFileNames(dicom_names)
        image = reader.Execute()

        image.SetMetaData("SeriesDescription", "T1w research export")
        image.SetMetaData("AcquisitionDate", "20260115")

        sitk.WriteImage(image, self.output_nrrd)
        print("wrote", self.output_nrrd)

SetMetaData is a string key and a string value. Same two example fields as the NIfTI path so the pair stays consistent. Read them later with image.GetMetaData("SeriesDescription") after sitk.ReadImage.

The DICOM read is only the vehicle. If you do not need extra keys, stop at DICOM to NIfTI and use the sidecar.

PYCAD builds the imaging side of products that have to keep these fields for real. Case studies.

We build custom medical imaging platforms — advanced DICOM viewers, AI segmentation, and the clinical systems around them.

Get in Touch

Copyright © 2026 PYCAD. All Rights Reserved.