[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