Reading and writing of 5D images - a dimension disappears

The library itself is here:

and bridge code is here:

1 Like

Ok, I will work on making sure I can build ITK and then understand what it will take to reconcile ITK’s NrrdIO with a fresh NrrdIO extracted from Teem.

However, if I understand the discussion above correctly - updating ThirdParty/NrrdIO isn’t going to marterialy change anything; it is the “bridge code” itkNrrdImageIO.cxx that may have to be looked at, since (I think) any axis order normalization would be happening there.

Given that - is there anyone else where who can assess if the questions about image data representation above (possibly as reflected by NRRD files), are traceable to the itkNrrdImageIO.cxx bridge code? If there are questions about the bridge code I should be able (with some nostalgia) to answer them separately from any ThirdParty/NrrdIO work.

Also - sorry if I started off on a needlessly pedantic vibe - in my Scientific Visualization class (which I’m currently teaching) I spend some time on image data representation, at the raster level and as a grid oriented in world space, so I think I slipped into professor mode there a bit. I have a pre-recorded video on the topic; if anyone is interested I can make it public.

1 Like

Thanks for the discussion! Sounds great @glk !

It seems to me that there is a very simple logic when writing out NRRDs using ITK’s IO. If there are multiple components it sets that kind based on the information in the image, and sets all other axis kinds to space (domain):

So if we define an image as itk::Image<TPixelType, 4>, then the last 4 axes will always be domain even if I set a metadata dictionary containing axis kind information. Not sure what all the implications could be for such a change, but it may just be enough to use the kinds information from the input metadata dictionary if there is any specified, which is an indication that the developer actually wants that information to be used.

Touching on the topic of OME-NGFF Zarr, we just finished a small project with the drivers of the image format effort (at least I think that it is the group from the University of Cologne who do it, the creators of OMERO and Omero.web), and waiting for a continuation. We were told that “NGFF support appears a very logical and NFDI compatible next step” (where NFDI is the name of the consortium), so there may be some opportunity to connect efforts to add NGFF support in Slicer.

Just to clarify this request should this be the meta-data dictionary of the Image or the NrrdImageIO? I seem to recall a couple ImageIO classes using their meta-data dictionary to override some writing options, but I can’t seem to find it now. I see the more common behavior of “extra” meta-data from the file format being place in the ImageIO, and not the image.

I did some trials and I found that the dictionary I set to the ImageIO was not considered, only the dictionary of the input image, if the UseInputMetaDataDictionary flag was turned on. It is possible that both can be considered, but it seemed unlikely so I assumed that the dictionary of the image is what one has to use if want to “inject” custom metadata.

The code I linked to before takes into consideration the ImageIO’s MetaDataDictionary.

The following works to explicitly set the “kinds” in the output of the NRRD file:


  auto image = itkNrrdImageIOTestGenerateRandomImage<unsigned char, 5>(10);

  auto imageIO = itk::NrrdImageIO::New();
  auto &dic = image->GetMetaDataDictionary();
  EncapsulateMetaData<std::string>(dic, std::string("NRRD_kinds[0]"), std::string("time"));
  EncapsulateMetaData<std::string>(dic, std::string("NRRD_kinds[1]"), std::string("domain"));
  EncapsulateMetaData<std::string>(dic, std::string("NRRD_kinds[2]"), std::string("domain"));
  EncapsulateMetaData<std::string>(dic, std::string("NRRD_kinds[3]"), std::string("domain"));
  EncapsulateMetaData<std::string>(dic, std::string("NRRD_kinds[4]"), std::string("list"));

  auto writer = itk::ImageFileWriter< typename decltype(image)::ObjectType >::New();
  writer->SetImageIO(imageIO);
  writer->SetFileName("NrrdKindsTest.nrrd");
  writer->SetInput(image);
  writer->Update();

Also note that when the NRRDImageIO reads an image these same metadata fields are in the dictionary, and could be copied from the input ImageIO to the output ImageIO if they should be preserved.

1 Like

Interesting. When I tried to do this, the contents of the dictionary disappeared. At least when I debugged into the writer code, the elements I added to the dictionary were not in it when getting here

I originally had this problem too, but I had to make this change:

auto dic = image->GetMetaDataDictionary();auto &dic = image->GetMetaDataDictionary();

The header of the NRRD file is:

NRRD0004
# Complete NRRD file format specification at:
# http://teem.sourceforge.net/nrrd/format.html
type: unsigned char
dimension: 5
space dimension: 5
sizes: 10 10 10 10 10
space directions: (1,0,0,0,0) (0,2,0,0,0) (0,0,3,0,0) (0,0,0,4,0) (0,0,0,0,5)
kinds: time domain domain domain list
encoding: raw
space origin: (0,1,2,3,4)
2 Likes

Great to see this discussion!

A quick note that we do have time-based processing supported by the Video group, and it would be nice for time-dimension NRRD support to be compatible with it.

1 Like