Hello,
I am new to VTK. I’m stuck on a problem and could really use some advice. I am writing a small program to perform multiplanar reformation (MPR) on a DICOM. I’ve read many forums, Q&As (@dgobbi) and examples. And my program is almost there, but not quite.
Here is what I am trying to do:
Given two DICOM-formatted MRIs - one which was acquired orthogonally and the other acquired in any orientation (usually doubly oblique), reformat the oblique MRI to display overlain on the orthogonal MRI. Note that the two volumes will likely have different resolutions (different voxel sizes). Also, the two volumes will always overlap. That is, in patient space, the oblique MRI lies within the volume of the orthogonal MRI.
Here is how I am trying to do it:
- Use vtkDICOMImageReader to load two DICOM MRI series. One MRI acquired orthogonally, and the other acquired in a doubly oblique orientation.
- Use ImageOrientationPatient and ImagePositionPatient from each DICOM to create an affine transformation matrix that describes the orientation of each MRI in patient space.
- Create a vtkImageReslice object for each MRI, and use the affine transformation matrices to set the reslice axes.
- Display both reformatted MRI’s, presumably now overlapping, using vtkRenderer. I display the volumes one slice at a time, with a mouse-move callback to allow scrolling through slices.
The problem:
When the resulting two volumes display in the render window, the reformatted oblique volume is in the wrong orientation, and displays far outside the orthogonal volume.
What am I doing wrong? Do I need to be somehow using SetOutputOrigin() with the reslice objects?
Thank you so much to anyone who reads all the way through this post!
- Michelle K.
My Code:
Summary
import vtk
===== IMAGE 1 (orthogonal) =====
image1_reader = vtk.vtkDICOMImageReader()
[…set directory name, update reader…]
vtkDICOMImageReader sorts images in reverse order. Flip front-to-back.
image1_flip = vtk.vtkImageReslice()
image1_flip.SetInputConnection(image1_reader.GetOutputPort())
image1_flip.SetResliceAxesDirectionCosines(1, 0, 0, 0, 1, 0, 0, 0, -1)
image1_flip.Update()
create affine matrix
image1_position = image1_reader.GetImagePositionPatient()
image1_orient = image1_reader.GetImageOrientationPatient()
image1_orient_x = image1_orient[0:3]
image1_orient_y = image1_orient[3:6]
math = vtk.vtkMath()
image1_orient_z = [0 for i in range(3)]
math.Cross(image1_orient_x, image1_orient_y, image1_orient_z)
image1_affine = vtk.vtkMatrix4x4()
for i in range(0, 3):
image1_affine.SetElement(i, 0, image1_orient_x[i])
image1_affine.SetElement(i, 1, image1_orient_y[i])
image1_affine.SetElement(i, 2, image1_orient_z[i])
image1_affine.SetElement(i, 3, position[i])
create a reslice object for the image 1
image1_reslice = vtk.vtkImageReslice()
image1_reslice.SetInputConnection(image1_flip.GetOutputPort())
Set the slicing axis for image 1
image1_reslice.SetOutputDimensionality(2)
image1_reslice.SetResliceAxes(image1_affine)
image1_reslice.SetInterpolationModeToLinear()
===== IMAGE 2 =====
[… repeat for image 2 …]
===== Map and Render Both Images =====
renderer = vtk.vtkRenderer()
image1_mapper = vtk.vtkImageResliceMapper()
image1_mapper.SetInputConnection(image1_reslice.GetOutputPort())
image1 = vtk.vtkImageSlice()
image1.SetMapper(image1_mapper)
renderer.AddViewProp(image1)
image2_mapper = vtk.vtkImageResliceMapper()
image2_mapper.SetInputConnection(image2_reslice.GetOutputPort())
image2 = vtk.vtkImageSlice()
image2.SetMapper(image2_mapper)
image2.GetProperty().SetOpacity(0.7)
renderer.AddViewProp(image2)
renWin = vtk.vtkRenderWindow()
renWin.SetSize(750, 750)
renWin.AddRenderer(renderer)
style = vtk.vtkInteractorStyle()
iren = vtk.vtkRenderWindowInteractor()
iren.SetInteractorStyle(style)
renWin.SetInteractor(iren)
renWin.Render()
Create callbacks for slicing the image
actions = {}
actions[“Slicing”] = 0
def button_callback(obj, event):
…
def mouse_move_callback(obj, event):
…
style.AddObserver(“MouseMoveEvent”, mouse_move_callback)
style.AddObserver(“LeftButtonPressEvent”, button_callback)
style.AddObserver(“LeftButtonReleaseEvent”, button_callback)
Start interaction
iren.Start()