如何使用GDCM逐片写入体素数据?

问题描述

在我看到的关于如何写入图像数据的 GDCM 的所有示例中,他们总是将图像体积视为一个整体、有凝聚力的缓冲区。基本结构是这样的

#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;
}

我使用这种方法面临的问题是,如果要制作额外的副本,我需要存储的图像数据量很容易超过可用的系统内存;具体来说,这些是 4096×4096×2048 个体素的体积,每个体素为 12 位,因此内存中大约有 48GiB 的数据。

但是使用gdcm::DataElementgdcm::Image::SetDataElement方法显然会在buffer中创建数据的完整副本,这很麻烦。一方面,我的成像系统产生的数据并不是作为一个有凝聚力的、单一的值块存在于内存中;它被分成几片。并且数据总量只适合被使用一次的系统的内存。

对我来说,逐片读入数据是微不足道的,这将显着减少内存需求。但是我不知道如何使用 GDCM 来做到这一点。

解决方法

您是否检查了 gdcm::FileStreamer:

在以下位置查看典型设置:

该示例显示了如何创建内存不足的私有元素,但您可以对公共 DataElement 执行相同操作。

一个更复杂的读取像素数据写入块的例子是: