Proposals:Writing DICOM from non-DICOM
- 1 The Problem
- 2 The current options
- 3 The way it should behave
- 4 Proposed solution
- 5 Appendix
How to take a ND image (possibly not a DICOM image file) and write it as a series of (N-1)D DICOM image files.
The current options
If the image is passed to an ImageFileWriter and a GDCMImageIO is connected to it, then the image will be writen as a single DICOM file with a multi-frame content.
If we take a 3D image in ITK and pass it to the ImageSeriesWriter and set the ImageIO to be the GDCMImageIO class, then the series will be written but they will all have the same DICOM header, and the third component of the origin and spacing will not be correct. Also the Direction cosines will completely be discarded.
The way it should behave
With the ImageSeriesWriter
The expected behavior with the ImageSeriesWriter would be to have each one of the files in the series use a corrected header such that:
- The origin of each one of the 2D images is computed in order to correspond to their location in space in the 3D image.
- The pixel spacing of the images should match the two first spacings in the input 3D image
- The inter-slice spacing is equal to the third dimension pixel spacing of the input image.
- The direction cosines of the DICOM slices should match the orientation of the original 3D image.
The final test of the correctness in the series writing process would be to take a 3D image (not-from-DICOM), save it as a DICOM series and then read it back in order to recover an identical copy of the original image.
With the ImageSeriesWriter
We propose to modify internally the ImageSeriesWriter in order to create a cannonical DICOM header and for each slice update its information about:
- 3D position
- Inter-Slice spacing
- Orientation (direction cosines)
This could be done in an "else" option to the case when the user provide a MetaDataDictionaryArray to the ImageSeriesWriter.
I would rather not add DICOM specific code to ImageSeriesWriter. Some sort of a helper class could be created that would populate the MetaDataDictionary for each slice. Helper classes would permit us to produce a variety of DICOM headers if need be. Many of the commercial Radiology workstations such as GE's Advantage Windows require tags that vary depending upon the vendor.
However, there is a know problem in image series writer. It invokes a 2D reader for each image. It passes down a 2D position and 2D orientation. DICOM, even though it is a 2D format, has a 3D position. This needs to be resolved for GDCMImageIO to generate proper image position patient.
Luis Comments to Lorensen Comments
I agree that DICOM specific code should not be added to the ImageSeriesWriter. One option is to add virtual methods to the ImageIOBase class for writing specific information in its MetaDataDictionary as well as its internal metadata. The item to set would be
- Image Origin (in the dimensionality of the input image)
- Image Spacing (in the dimensionality of the input image)
- Image Orientation (direction cosines..?)
The method names to add could be:
- virtual void SetMetaDataOrigin( const Array<double> & )
- virtual void SetMetaDataSpacing( const Array<double> & )
- virtual void SetMetaDataOrientation( const Array<double> & )
Every specific ImageIO class could overload these functions in order to update its own MetaDataDictionary as well as the data of the image that they are writing.
The GDCMImageIO, in particular, knows that DICOM slices despite the fact of looking like 2D data, do actually have 3D origins and 3D spacing data.
Different ImageIO classes uses the MetaDataDictinoary with different (file format specific) tags. Among them:
Use cases of the ImageSeriesWriter
- The Writer does not use the MetaDataDictionary of the input image, instead it takes the MetaDataDictionary from the ImageIO.
- The user can specify an array of MetaDataDictionaries. This was added a while ago in order to be able to read a DICOM series and write it as another DICOM series while still preserving the headers.
Random comments from users/developers