[vtkusers] using itk transform in vtk
David Gobbi
david.gobbi at gmail.com
Tue Nov 16 16:31:05 EST 2010
Hi Karl,
The VTK transform operates on the physical origin, which can be at any
desired location in the image. The relationship between DICOM
coordinates and VTK coordinates is explained thusly:
DICOM has three fields related to the positions of the image voxels in
physical (or patient) space:
- ImagePositionPatient (position of upper right corner)
- ImageOrientationPatient (row and column directions)
- PixelSpacing (X and Y)
VTK image data has two fields (no orientation):
- Origin (position of lower right corner)
- Spacing (X, Y, and Z)
Note that the image data "Origin" is a misnomer, it is not the
physical origin of the coordinate system. It is just the position of
the voxel in the lower left corner. It is the responsibility of the
VTK image reader that you are using to set the Origin and Spacing of
the data correctly. (And again, I will repeat that what VTK calls the
image "Origin" is not the physical image origin, it is just a
position).
The fundamental difference between these two coordinate systems is not
the location of the origin, it is a vertical flip since DICOM images
are top-to-bottom while VTK images are bottom-to-top. When dealing
with DICOM, I set the VTK image "origin" to the DICOM
ImagePositionPatient, and then apply a view transform that flips the
image by using a rotation of 180 degrees about the X axis.
- David
On Tue, Nov 16, 2010 at 2:02 PM, Karl <bulkmailaddress at gmail.com> wrote:
> Hi,
> I am trying to use an itk transform in vtk. Here is a high level overview
> of what I do:
>
> 1) In itk use itk::ImageRegistrationMethod with itk::AffineTransform to find
> a transform.
>
> 2) I use itk::ResampleImageFilter to create an image transformed using the
> itk::AffineTransform.
>
> 3) I use the GetLastTransformParameters() function to get the affine
> transformation matrix to use in vtk as.
> [param0 param1 param2 param9]
> [param3 param4 param5 param10]
> [param6 param7 param8 param11]
> [0 0 0 1]
>
> 4) Now in vtk I try to display both the resampled image and the original
> image with the transform applied. They should show as exactly the same if I
> can apply the transform in vtk the same as it is applied in itk.
>
> 5) I load both images in vtk. The images are binary so I use marching cubes
> to create meshes of them. I display the transformed image polydata as is.
>
> 6) I apply a vtkTransform to the original image polydata. I do this by
> concatenating 3 vtkMatrix4x4. Two to adjust for different origins in itk and
> vtk and one for the itk transform.
> Translate_Back * itkTransform * Translate_itk_origin_to_vtk_origin
>
> Where
> itkTransform is as shown in 3 above.
>
> Translate_itk_origin_to_vtk_origin is
> [1 0 0 -originX]
> [0 1 0 -originY]
> [0 0 1 -originZ]
> [0 0 0 1]
> Where the origin is as found in the dicom header for the original image
>
> Translate_Back
> [1 0 0 originX]
> [0 1 0 originY]
> [0 0 1 originZ]
> [0 0 0 1]
>
> 7) Set vtkTransform inverse flag and transform and display the original
> image.
>
> 8) The two objects show up at different places in the scene instead of at
> the same location.
>
> If I understand this correctly the itk transform is to be applied about the
> physical origin. Not the location of the corner pixel or the center of the
> image.
>
> The vtk transform uses an origin at the corner of the image.
>
> By translating by the origin defined in the dicom header I move the physical
> origin to the corner pixel of the image. This corrects for the
> discrepancies between the point with itk and vtk apply their transforms.
>
> Also the itk transform goes from output to input, so the inverse transform
> needs to be applied in vtk.
>
> Can anyone see what I am missing?
> Thanks
More information about the vtkusers
mailing list