Many of us have probably heard that it’s not possible to store additional metadata in NIfTI and NRRD files, right? Generally, it’s well-known that DICOM files are the go-to format for storing a variety of metadata, including imaging and patient information.
When we convert DICOM files to NIfTI or NRRD formats, we typically rely on standard libraries that only transfer the essential imaging data, leaving out most of the metadata. This approach is considered the “classic” conversion method.
However, there are situations where we might need to retain some patient information or other metadata along with the imaging data. By default, this doesn’t happen during the conversion process, which is actually beneficial for anonymization purposes. In this way, when converting from DICOM to NIfTI or NRRD, all patient metadata is stripped out, which is ideal if we’re focused on protecting patient privacy.
On the other hand, some industries require that certain metadata be preserved in the NIfTI or NRRD files after conversion from DICOM.
In this blog, I’ll show you how you can add custom metadata to your NIfTI or NRRD files in just a few simple steps.
DICOM to NIfTI Conversion with Metadata Embedding
import SimpleITK as sitk import numpy as np import nibabel as nib import json import base64 class SimpleDicomToNiftiConverter: def __init__(self, dicom_folder, output_nifti): self.dicom_folder = dicom_folder self.output_nifti = output_nifti def convert(self): # Read the DICOM series reader = sitk.ImageSeriesReader() dicom_names = reader.GetGDCMSeriesFileNames(self.dicom_folder) reader.SetFileNames(dicom_names) image = reader.Execute() # Create affine matrix for NIfTI 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 # Convert SimpleITK image to Nibabel image image_array = sitk.GetArrayFromImage(image) nifti_image = nib.Nifti1Image(image_array, affine) # Add custom metadata as JSON custom_metadata = {"ExampleKey": "ExampleValue"} 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) # Save the NIfTI image nib.save(nifti_image, self.output_nifti) print(f"NIfTI file saved successfully: {self.output_nifti}")
- Setup: Initialize the converter with the DICOM folder and output NIfTI file paths.
- Read DICOM: Load the DICOM series into memory as a 3D image using SimpleITK.
- Create Affine Matrix: Generate an affine matrix to preserve the spatial orientation of the image.
- Convert to NIfTI: Convert the 3D image to a NIfTI file using Nibabel.
- Add Metadata: Embed custom metadata (like patient information) into the NIfTI file as a JSON object.
- Save NIfTI: Save the NIfTI file with the embedded metadata.
DICOM to NIfTI Conversion with Metadata Embedding
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): # Read the DICOM series reader = sitk.ImageSeriesReader() dicom_names = reader.GetGDCMSeriesFileNames(self.dicom_folder) reader.SetFileNames(dicom_names) image = reader.Execute() # Add custom metadata image.SetMetaData("ExampleKey", "ExampleValue") # Save as NRRD sitk.WriteImage(image, self.output_nrrd) print(f"NRRD file saved successfully: {self.output_nrrd}")
- Setup: Initialize the converter with the DICOM folder and output NRRD file paths.
- Read DICOM: Load the DICOM series as a 3D image using SimpleITK.
- Add Metadata: Attach custom metadata (like patient information) directly to the image.
- Save NRRD: Save the image and the attached metadata as an NRRD file.
For the full tutorial, please check the repo here.