简体   繁体   中英

How to use GDCM to write voxel data, slice by slice?

In all the examples I've seen for GDCM on how to write image data, they always consider the image volume as a single whole, cohesive buffer. The basic structure is along the lines

#include "gdcmImage.h"
#include "gdcmImageWriter.h"
#include "gdcmFileDerivation.h"
#include "gdcmUIDGenerator.h"

int write_image(...)
{
  size_t width = ..., height = ..., depth = ...;
  auto im = new gdcm::Image;

  std::vector<...> buffer;
  auto p = buffer.data();

  im->SetNumberOfDimensions(3);
  im->SetDimension(0, width);
  im->SetDimension(1, height);
  im->SetDimension(1, depth);

  im->GetPixelFormat().SetSamplesPerPixel(...);
  im->SetPhotometricInterpretation( gdcm::PhotometricInterpretation::... );

  unsigned long l = im->GetBufferLength();
  if( l != width * height * depth * sizeof(...) ){ return SOME_ERROR; }
  gdcm::DataElement pixeldata( gdcm::Tag(0x7fe0,0x0010) );
  pixeldata.SetByteValue( buffer.data(), buffer.size()*sizeof(*buffer.data()) );
  im->SetDataElement( pixeldata );

  gdcm::UIDGenerator uid;
  auto file = new gdcm::File;

  gdcm::FileDerivation fd;
  const char UID[] = ...;
  fd.AddReference( ReferencedSOPClassUID, uid.Generate() );
  fd.SetFile( *file );
  // If all Code Value are ok the filter will execute properly
  if( !fd.Derive() ){ return SOME_ERROR; }

  gdcm::ImageWriter w;
  w.SetImage( *im );
  w.SetFile( fd.GetFile() );

  // Set the filename:
  w.SetFileName( "some_image.dcm" );
  if( !w.Write() ){ return SOME_ERROR; }

  return 0;
}

The problem I'm facing with this approach is, that the amount of image data I need to store easily exceeds the available system memory, if an additional copy is being made; specifically these are volumes of 4096×4096×2048 voxels of 12 bits each, so about 48GiB of data in memory.

However the approach of using gdcm::DataElement and gdcm::Image::SetDataElement will obviously create a full copy of the data in buffer , which is troublesome. For one, the data as produced by my imaging system does not reside in memory as a cohesive, singular block of values; it is split into slices. And the total amount of data fits into the memory of the systems being used only once.

It is trivial for me, to read in the data slice by slice, which would cut down the memory requirements significantly. However I'm at a loss, how that'd be done with GDCM.

Did you check gdcm::FileStreamer:

See typical setup at:

The example show how to create an out of memory private element, but you can do the same with public DataElement.

A more complex example to read where Pixel Data is written in chunks is at:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM