stream writing in coronal orientation

Hi.
I’ve got several mha files, each is the subvolume of the big 3d volume. These subvolumes go in coronal direction. So, I need to combine them into one big file, but I don’t have enough memory to create whole image to perform simple copy into it, thus, I have to use stream writing. Unfortunately, I’ve not found how to set coronal direction for stream writing.
Dimension of each part is 1152x260x1152. Number of parts is 3.
This code

using SeriesReaderType = itk::ImageSeriesReader< OutputImageType > ;
SeriesReaderType::Pointer reader = SeriesReaderType::New();
reader->SetFileNames(nameGenerator->GetFileNames());
reader->UpdateOutputInformation();
std::cout << reader->GetOutput()->GetLargestPossibleRegion();

using ImageWriterType = itk::ImageFileWriter<OutputImageType>;
ImageWriterType::Pointer writer = ImageWriterType::New();
writer->SetFileName("WholeVolume.mha");
writer->SetNumberOfStreamDivisions(10);
writer->SetInput(reader->GetOutput());
writer->Update();

outputs

ImageRegion (0x7f215ca7c898)
 Dimension: 3
  Index: [0, 0, 0]
  Size: [1152, 260, 3]
and the program exits with error
itk::ERROR: ImageSeriesReader(0x7f215ca371e0): Size mismatch! The size of  /home/user/dev/t4all/release/bin/part0.mha is [1152, 260, 1152] and does not match the required size [1152, 260, 1] from file /home/user/dev/t4all/release/bin/part0.mha

It looks like the input files for ImageSeriesReader should be 2-dimensional image. I created lots of 2-dim parts, each corresponds to one coronal slice, but the code above put them in axial direction. Then I did little trick - I created coronal slice but in 3d image with dimension [1152, 1, 1152] and it outputs (where 780 is the number of slices)
ImageRegion (0x7f5c54ab7f78)
Dimension: 3
Index: [0, 0, 0]
Size: [1152, 780, 1152]
! The exact dimension I need, but content is distorted. (https://imgur.com/a/XpANGVm lower pic must be the same as upper)

The only way I got it worked is to create axial slices by iterate over subvolumes opening/closing them multiple times. But this solution is very slow and over headed.
Could anyone direct me where I should look to optimize my problem ?

This example demonstrates writing chunks of output image. You need to figure out from which part and which input image you want to take the chunk, but it can be similar. Probably easiest is to only split along coronal axis.

Thanks! The following code works fine for me:

char sz[100];
int subvolumesNumber = 3;
using ImageType = itk::Image< unsigned short, 3 >;

using WriterType = itk::ImageFileWriter<ImageType>;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName("volume.mha");

ImageType::RegionType fullRegion;
ImageType::PointType origin;

using ReaderType = itk::ImageFileReader< ImageType >;

int fullSize1 = 0;
int subvolumeSize1 = 0;
ReaderType::Pointer reader = ReaderType::New();
for (int i = 0; i < subvolumesNumber; i++)
{
	sprintf(sz, "subvolume%d.mha", i);
	reader->SetFileName(sz);
	reader->UpdateOutputInformation();
	if (!i)
	{
		origin = reader->GetOutput()->GetOrigin();
		fullRegion = reader->GetOutput()->GetLargestPossibleRegion();
		subvolumeSize1 = reader->GetOutput()->GetLargestPossibleRegion().GetSize(1);
	}
	fullSize1 += reader->GetOutput()->GetLargestPossibleRegion().GetSize(1);
}
fullRegion.SetSize(1, fullSize1);
reader = nullptr;

itk::ImageIORegion ioRegion(3);
ioRegion.SetIndex(0, fullRegion.GetIndex()[0]);
ioRegion.SetIndex(2, fullRegion.GetIndex()[2]);
ioRegion.SetSize(0, fullRegion.GetSize()[0]);
ioRegion.SetSize(2, fullRegion.GetSize()[2]);

for (int i = 0; i < subvolumesNumber; i++)
{
    sprintf(sz, "subvolume%d.mha", i);
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(sz);
    reader->Update();

    ImageType::Pointer result = reader->GetOutput();
    result->DisconnectPipeline();
    result->SetLargestPossibleRegion(fullRegion);
    ImageType::RegionType region = result->GetBufferedRegion();
    region.SetIndex(1, subvolumeSize1 * i);
    result->SetBufferedRegion(region);
    result->SetOrigin(origin);

    ioRegion.SetIndex(1, region.GetIndex()[1]);
    ioRegion.SetSize(1, region.GetSize()[1]);

    writer->SetInput(result);
    writer->SetIORegion(ioRegion);
    writer->Update();
}
1 Like