How to write a custom Tag to an image (NRRD or other) header

The following question was asked on the ITK user mailing list:

I can’t find any possibility to add a field (custom or not) into a nrrd
header. The NrrdImageIO doesn’t allow it (or I missed it).
Is someone know how to do that?

Here is an short example to add a tag to a header (more specifically to add a key/value pair to the metadata dictionary of an image:

CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)
project(metadataNRRD)

find_package(ITK REQUIRED)
include(${ITK_USE_FILE})

add_executable(main main.cpp)
target_link_libraries(main ${ITK_LIBRARIES})

main.cpp:

#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkMetaDataObject.h>

int main(int argc, char* argv[])
{
  typedef itk::Image<float,3> ImageType;
  typedef itk::ImageFileReader<ImageType> ReaderType;
  typedef itk::ImageFileWriter<ImageType> WriterType;
  typedef itk::MetaDataObject< std::string > MetaDataStringType;

  MetaDataStringType::Pointer meta = MetaDataStringType::New();
  meta->SetMetaDataObjectValue("my_value");
  
  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();
  reader->SetFileName(argv[1]);
  reader->Update();
  reader->GetOutput()->GetMetaDataDictionary().Set("my_key", meta);
  
  writer->SetFileName(argv[2]);
  writer->SetInput(reader->GetOutput());
  writer->Update();
  
  return 0;
}

Result:

$ head /tmp/temp.nrrd  -n 35|grep my_key                                                                                                                                               
my_key:=my_value
3 Likes

Hi!

Thanks for the tip!
I was looking for something more complex. Last minor question, can I remove the ‘=’ that goes right after the ‘:’ ?
Thanks again.
Laurent

I don’t think you can change the separator in NRRD files. It seems to be hardcoded here.

Indeed, it looks like it’s harcoded. For ‘regular’ key however, there is no ‘=’.
Here below is what I get from an nrrd export.
No matter, that’s already great. Thnaks.
Laurent.

NRRD0004
# Complete NRRD file format specification at:
# http://teem.sourceforge.net/nrrd/format.html
type: short
dimension: 3
space: left-posterior-superior
sizes: 512 512 40
space directions: (0.74166344533409734,0.24553390062302261,2.0570962061581618e-009) (0.017811776715077408,-0.053802517899294709,-0.77919162737926562) (-1.3792045934269708,4.1660464344952892,-0.31918961059716106)
kinds: domain domain domain
endian: little
encoding: gzip
space origin: (-90.943809509277344,-113.14472198486328,180.36408996582031)
exam_date:=20171116

Indeed. Thanks for the information, I was unaware of that difference. If you wanted to investigate more, you could look into the documentation of teem and see if this is a bug or a feature.

While two years ago, allow me to add information to make the post more self-contained: the behaviour of := is as expected.

This is a problem which was also of interest to me: in PET images you want to keep both the raw data as the way of translating it to SUV values. For this you might want to keep some of the DICOM tags instead of storing them in a different file. := is indeed correct (see the documentation). There are several other applications where one wants to do this. For instance mammography has a complete set of lookup tables associated to the images which one might want to preserve.

Each of the “< field >: < desc >” lines specifies information about one of the fields in the nrrd. (…)
Each of the “< key >:=< value >” lines specifies a key/value pair in the nrrd. (…)