It’s a bit tricky to use vtkExtractVOI
, because when it crops the volume, it also changes the indexing. Take this simple example in Python:
a = vtkImageData()
a.SetDimensions(100,100,100)
a.AllocateScalars(VTK_UNSIGNED_CHAR,1)
v = vtkExtractVOI()
v.SetInputData(a)
v.SetVOI(25,50,25,50,25,50)
v.Update()
# cropped output
b = v.GetOutput()
b.GetExtent()
(25, 50, 25, 50, 25, 50)
b.GetOrigin()
(0, 0, 0)
The vtkExtractVOI
filter has changed the indexing of the volume so that the indexing starts at i=25,j=25,k=25
. In order to adjust the volume so that the indexing starts at zero, use vtkImageChangeInformation
like this:
c = vtkImageChangeInformation()
c.SetInputData(b)
c.SetOutputExtentStart(0,0,0)
c.Update()
c.GetOutput().GetExtent()
(0, 25, 0, 25, 0, 25)
c.GetOutput().GetOrigin()
(0.0, 0.0, 0.0)
Note that SetOutputExtentStart()
and SetOutputOrigin()
have complementary effects: they do similar things, but in different coordinate systems. The best way that I can explain it is this:
- Changing the
Extent
changes how the volume’s voxels are indexed
- Changing the
Origin
(and Spacing
and Direction
) change how the indices map to what we call VTK’s “Data Coordinates” (some people prefer to call them “Physical Coordinates”)
For convenience, the vtkImageData
method GetIndexToPhysicalMatrix()
will return a matrix that can be used to map from the i,j,k indices to the Data Coordinates.
I’m pretty sure that vtkImageChangeInformation
is the filter that you want to use, and if you’re using it after vtkExtractVOI
, you might have to change both the Origin
and the Extent
of the volume in order to make things work the way you expect.
The mapping from Data Coordinates to World Coordinates is controlled by the vtkProp3D
class (this is the base class for vtkActor
, vtkVolume
, etc). Only subclasses of vtkProp3D
can adjust the mapping from Data to World. With these classes, use GetMatrix()
to get the 4x4 matrix that maps from Data Coordinates to World Coordinates.