Scaling a Nifti Volume

Hello,
When reading a volume as a TIFF stack using the vtkTiffReader the size of the volume can be scaled using the readers SetDataSpacing function.

However, when reading a Nifti volume, using the Nifti reader, the SetDataSpacing(x,y,z) function don’t seem to do anything.

Any tips on how to scale a nifti? Is it possible?

The vtkImageChangeInformation class can change the spacing, put it into your pipeline just after the reader. The way this filter works, is that it makes a shallow copy of the data (it keeps the same voxel array) and attaches new information to the data.

That worked perfect!

We know have something like this:

    vtkSmartPointer<vtkImageChangeInformation> imageChange = vtkSmartPointer<vtkImageChangeInformation>::New();
   imageChange->SetInputConnection(reader->GetOutputPort());        
   imageChange->Update();
   mVolumeMapper->SetInputData(imageChange->GetOutput()) ;

My next problem is that I need to scale this volume data from being in millimeter units to to microns.

I thought using the setDataSpacing(1000,1000,1000) would do it, but I guess I’m missing something.

Another thing I noticed is that the opacity of the volume changes radically when changing the data spacing, e.g.

No Spacing:

image

setting spacing: imageChange->SetOutputSpacing(10, 10, 10);

image

I guess this is result of how the opacity function works, as a function of distance?
Is there a way to change spacing while keeping the opacity ‘constant’?

If the units of the nifti file are millimeters and you want VTK world coordinates to be measured in microns, then scaling by 1000 is the correct thing to do.

Regarding the volume rendering, you will have to adjust sampling distances and opacity functions according to the size of the volume. The opacity function for a volume that’s 10 units from front to back will be very different from a volume that 10000 units from front to back.

Actually, let me clarify: If the units of the nifti file are millimeters and you want VTK world coordinates to be measured in microns, you would do this:

   imageChange->SetSpacingScale(1000, 1000, 1000);

and you would not call SetDataSpacing() on anything.

1 Like

That worked perfect as well! I was afraid I had to figure out origin of volume and do some calculations regarding the extents of the data… But the above just did it. Thanks!

Now just gotta think about the opacity function.