[vtkusers] orthogonal slices through a volume
David Gobbi
dgobbi at atamai.com
Mon Aug 21 14:50:58 EDT 2006
Hi Anja,
Just in case, I think that I should note a couple extra things about the
method that I described:
1) I forgot to mention that you still need to do
slicer->SetResliceDirectionCosines():
XY: slicer->SetResliceDirectionCosines(1, 0, 0, 0, 1, 0, 0, 0, 1);
YZ: slicer->SetResliceDirectionCosines(0, 1, 0, 0, 0, 1, 1, 0, 0);
XZ: slicer->SetResliceDirectionCosines(1, 0, 0, 0, 0, 1, 0, -1, 0);
(same as you had)
2) To point out the difference between vtkImageViewer, vtkImageViewer2,
vtkImageActor:
The vtkImageViewer is directly maps each image pixel to a screen pixel.
It does not take the pixel spacing into account and therefore displays
the wrong aspect ratio if the spacing is anisotropic. It does not take
the image origin into account, either, so rather than trying to draw the
image in the correct position in the window, it tries to resize the
window to the size of the image.
The vtkImageViewer2 takes the pixel spacing an origin into account, and
it always displays the image in its original coordinate system (i.e. it
maps vtkImageData data coordinates directly to VTK world coordinates).
Because of the way vtkImageReslice rotates the coordinate system, if you
display the slicer result in a vtkImageViewer2 then you must set the
viewer orientation to XY to match the slicer's output. This will
display the image as expected, except that the world coords will be
rotated as compared to the image data coords.
With vtkImageActor, you can rotate the actor to get the image data
coords to match the world coords, which is why I suggest that
vtkImageActor is the way to go.
I hope this is helping to straighten out the differences a bit.
Finally, the trick of using slicer->SetOutputDimensionality(2) is not
the only way of getting a 2D slice from vtkImageReslice. The other way
is to use e.g. slicer->SetOutputExtent(0,255,0, 255, 0,0) to crop the
output so that it is just one slice thick. That's the way that I
usually do things, but it is complicated because I also have to do some
fancy calculations to set the OutputOrigin() just right so that I get
the result I want. Since the SetOutputExtent() method is more
complicated than the SetOutputDimensionality(2) method, I don't usually
recommend it, but it is the method that vtkImagePlaneWidget uses to set
up its slicer.
- David
David Gobbi wrote:
> Hi Anja,
>
> It is possible to use vtkImageReslice to do what you want, but the
> trick is this:
>
> You need to set up vtkImageReslice so that it will extract just 1
> slice for you.
>
> If you use vtkImageReslice to reslice the whole volume, and then use
> vtkImageViewer2 or vtkImageClip to extract one slice from the resliced
> volume, then you will have a very hard time getting the result you want.
>
> So, I'm sure you are wondering how to get vtkImageReslice to select
> just one slice for you, and how to make sure that it selects the
> correct slice.
>
> The easiest way to output just one slice is to use
> slicer->SetOutputDimensionality(2).
>
> The easiest way to select which slice to output is to use
> slicer->SetResliceAxesOrigin(x,y,z) where (x,y,z) is the point where
> your three orthogonal planes will intersect.
>
> There is still one tricky part left! When you use
> SetOutputDimensionality(2), the output of vtkImageReslice will always
> be in a 2D (x,y) coordinate system with z=0. This is no problem if
> you are using vtkImageViewer, since it works in the 2D display
> coordinate system, but you will get into trouble with vtkImageViewer2.
>
> The best way to display the result is to use vtkImageActor (or
> actually 3 separate vtkImageActors). You will have to set the
> UserMatrix of the vtkImageActor to match the ResliceAxes matrix that
> was applied to the image by the slicer:
>
> imageActor->SetUserMatrix(slicer->GetResliceAxes());
>
> This will place the imageActor in exactly the same position as the
> slice that the slicer cut from the volume.
>
> So as you can see, this is all fairly complicated. But when it is all
> done, you can slice in all three directions by changing the (x,y,z)
> that you send to slicer->ResliceAxesOrigin(x,y,z). Send the same
> (x,y,z) to all three slicers.
>
> Let me know how it works for you.
>
> - David
>
>
>
> Anja Ende wrote:
>> Hi everyone,
>>
>> I know this question has been asked before but I could not find an
>> answer that could have helped me, so I am asking again.
>>
>> Well... I am trying to get the classic 3 orthogonal slices through a
>> volume. I know the vtkImageViewer2 provides this functionality but I
>> cannot use that component unfortunately.
>>
>> I was trying to use the vtkImageReslicer to get the XZ plane through
>> the volume.
>>
>> So, I tried setting up the matrix as follows:
>>
>> vtkImageReslice * slicer = vtkImageReslice::New();
>> slicer->SetInput(imageChangeInformationP->GetOutput());
>> slicer->SetResliceAxesDirectionCosines(1, 0, 0, 0, 0, 1, 0, -1, 0);
>>
>> Is this matrix correct if I want to get the XZ plane out of the
>> volume? I ask because some of the slices in the beginning and end
>> seem bogus. The vtkImageViewer2 does not show them when I set the
>> orientation to XZ in the vtk viewer.
>>
>> Also, I noticed that the vtkImageViewer2 displays the volume nicely
>> with correct aspect ratio and all that... So, I tried using:
>>
>> slicer->SetOutputSpacing(1.0, 1.0, 1.0);
>>
>> This was shown in the example. However, this changes my extents and
>> the number of Z slices reduces.
>>
>> I was wondering if someone can help me determine the correct matrix
>> for extracting these planes.
>>
>> Thanks,
>>
>> Anja
More information about the vtkusers
mailing list