Problem with the vtkImageReslice position - help please

Hello all,

I have the problem with imageReslice position. In my code, I have the vtkDICOMReader that reads the volume. Then I extract part of the volume by the vtkExtractVOI (regular cube form). This two things work according to my needs.
What I need is to create the slice from the vtkExtractVOI output. It means, I want to show it inside the extracted cube. I’ve tried many different settings of the output extent, output origin, input origin, etc. but I’m not able to place the reslice to the correct position.

The problem is demonstrated on the following images (yellow cube is the correctly positioned vtkExtractVOI, the red cube is the imageReslice output):

Here is my code snippet:

    self.extractor = vtk.vtkExtractVOI()
    #the reader is vtkDICOMReader
    self.extractor.SetInputConnection(self.reader.GetOutputPort())    
    self.extractor.SetVOI(80, 100, 80, 100, 60, 80)    
    self.extractor.Update()

    extractorMapper = vtk.vtkFixedPointVolumeRayCastMapper()
    extractorMapper.SetInputConnection(self.extractor.GetOutputPort())

    extractorVolume = vtk.vtkVolume()
    extractorVolume.SetMapper(extractorMapper)

    transform = vtk.vtkTransform()       
    transform.RotateX(-20)
    transform.RotateY(20)      
    transform.PostMultiply()
    transform.Update()

    #setting the 4th matrix column to 1 according to vtkImageReslice documentation
    t = vtk.vtkMatrix4x4()
    transform.GetMatrix(t)
    t.SetElement(0, 3, 1)
    t.SetElement(1, 3, 1)
    t.SetElement(2, 3, 1)
    t.SetElement(3, 3, 1)

    self.imageReslice = vtk.vtkImageReslice()
    self.imageReslice.SetInputConnection(self.extractor.GetOutputPort())
    self.imageReslice.SetOutputDimensionality(3)     
    self.imageReslice.SetResliceAxes(t)
    self.imageReslice.InterpolateOn()   
    #I'm not sure to which values the output extent has to be set. The values in code are found by trying   
    #many different ones
    self.imageReslice.SetOutputExtent(0, 100, 0, 100, 0, 200)
    self.imageReslice.AutoCropOutputOn()

   #extractor is the vtkExtractVOI object 
    self.imageReslice.SetResliceAxesOrigin(self.extractor.GetOutput().GetOrigin()) 
    self.imageReslice.SetOutputOrigin(self.extractor.GetOutput().GetOrigin())
    self.imageReslice.SetOutputSpacing(1, 1, 1)
    self.imageReslice.UpdateWholeExtent()

    #mapper
    reslicedVolumeMapper = vtk.vtkFixedPointVolumeRayCastMapper()
    reslicedImageVolume = vtk.vtkVolume()

    reslicedVolumeMapper.SetInputConnection(self.imageReslice.GetOutputPort())
    reslicedImageVolume.SetMapper(reslicedVolumeMapper)
    
   #the following volume is the volume created from the vtkDICOMReader output. Commented as I don't need to show it always. "ren2" is the renderer of one of the windows I use in my code. 
   #self.ren2.AddVolume(volume)
   #the following extractorVolume is the volume created from the vtkExtractVOI output.  
    self.ren2.AddVolume(extractorVolume)
    self.ren2.AddVolume(reslicedImageVolume)


What can I do to place the imageReslice slice correctly for I can rotate it inside the extractor cube?

Thank you and have a nice day all!

Jirka

This code doesn’t look right:

The vtkImageReslice documentation says this:

The fourth column is the origin of the axes (the fourth element must be set to one).

This means that the fourth element of the fourth column must be equal to one. It doesn’t say that the other elements of the fourth column must be equal to one.

Hello David,

thank you for your reply. You are absolutely right!
So, I have tried different values for the first three elements of the fourth matrix column but, unfortunately, it has no influence on the visual representation of the resliced volume :frowning:

Any other advice?

Thank you once more,

Jirka

In order to properly reslice the VOI, you’ll need a ResliceMatrix that performs a rotation around the center of the VOI. So what you want to do is roughly as follows:

  1. Compute the coordinates of the center point of your VOI
  center = [ origin[0] + spacing[0]*(80 + 100)/2.0,
             origin[1] + spacing[1]*(80 + 100)/2.0,
             origin[2] + spacing[2]*(60 + 80)/2.0 ]
  1. Create a transform that uses that point as the center-of-rotation
    transform.PostMultiply()
    transform.Translate(-center[0], -center[1], -center[2])
    transform.RotateY(20) 
    transform.RotateX(-20)
    transform.Translate(+center[0], +center[1], +center[2])

Note that this will correctly set the 4th column of the 4x4 matrix, so no further adjustments to the 4th column will be necessary ( so DO NOT use SetResliceAxesOrigin(), since that effectively overwrites the 4th column).

After setting the ResliceAxes so that they properly rotate around the center of the VOI, the next step is to set up vtkImageReslice so that the center of the resliced volume is at the center of the VOI volume. I’ll leave that as an exercise for the reader. :slight_smile:

Hi David,

you are the God! Thank you a lot. Now, everything works as I need.

Have a beautiful day,

Jirka