[vtkusers] vtkImageReslice config problem

David Gobbi david.gobbi at gmail.com
Mon Mar 3 15:01:12 EST 2008


Hi Dean,

I think that everything is correct except for the OutputOrigin,
which requires a bit of math.  See below.

On Mon, Mar 3, 2008 at 2:22 PM, Dean Inglis <dean.inglis at sympatico.ca> wrote:
>
> Hi
>
> I am developing a MPR application and am having some difficulty
> getting vtkImageReslice configured properly. I have a set of
> "layout lines" interactively defined on a slice through the original
> image data set. The user can set the number of slices, spacing (output slice
> thickness ) and length of the lines (in-plane FOV of the slices) as well
> as the in-plane pixel dimensions (see attached jpeg). When I set
> the vtkImageReslice, I use the following settings:
> // r, s and t define the the output axes unit vectors
> this->Reslice->SetResliceAxesDirectionCosines(
> r[0],r[1],r[2],s[0],s[1],s[2],t[0],t[1],t[2]);

That part is correct.  Note that trilinear and tricubic interpolation
give poor results if you use large oblique angles such that
there is more than one pixel worth of shear per unit slice spacing.
If the axes are orthogonal, you are always safe.

> // turn off transformation of the input spacing origin and extent
> // so we can use our own
> this->Reslice->TransformInputSamplingOff();

That's definitely necessary.

> // p0 corresponds to the origin of the output axes unit vectors
> // and would correspond to one of the corners of the preview
> // plane shown in the figure when that plane was on the first
> // of the layout lines
> this->Reslice->SetResliceAxesOrigin(p0[0], p0[1], p0[2]);

That is probably not the best choice.  I usually try to keep
the ResliceAxesOrigin at (or at least close to) the centre of the
volume.  However, where you set the ResliceAxesOrigin is not critical
as you will see in the next step.

> // neither of the following choices work!
> // this->Reslice->SetOutputOrigin( p0[0], p0[1], p0[2] );
> this->Reslice->SetOutputOrigin( 0.5*r_sp, 0.5*s_sp, 0.5*t_sp );

This is where things are going wrong.  The OutputOrigin must
be placed at the corner of the output volume, and must be
given in the Output's own coordinate system.

You already know the coordinates of Output volume's corner in
the Input coordinate system, so you just have to apply a coordinate
transformation to put it into the Output coordinate system.

If you have already set the ResliceAxesDirectionCosines and the
ResliceAxesOrigin, you have already created a 4x4 matrix containing
the transformation from the Output coordinate system to Input coordinate
system, so you can do as follows:

vtkMatrix4x4 *temp = vtkMatrix4x4::New();
temp->DeepCopy(reslice->GetResliceAxes());
temp->Invert();
temp->MultiplyPoint(outputCornderInInputCoords, outputCornerInOutputCoords);

Don't forget that MultiplyPoint takes homogeneous coords (4 values).
Use the result as your OutputOrigin.

> // r_sp, s_sp and t_sp are user specified spacings
> this->Reslice->SetOutputSpacing( r_sp, s_sp, t_sp );

Correct.

> // w_ext is calculated from the specified spacings, the length of
> // the layout lines, the distance they span, and the necessary height
> // of the output slices so that none of the input data is truncated.
> // w_ext[0], w_ext[2], w_ext[4] are all 0.
> this->Reslice->SetOutputExtent(w_ext);

Yes.

> When I update the reslice, the output slices do not appear positioned
> with respect to the requested origin. Is there some transform I have to
> apply to get the correct origin? Would I have to transform the extent?

Leave the extent alone, VTK can be a pain to work with if extents
don't start at zero.

  -David



More information about the vtkusers mailing list