[vtkusers] vtkResliceImage and appending slices

David Gobbi david.gobbi at gmail.com
Thu Dec 4 01:35:40 EST 2014


Hi Zarko,

Good question.  My own approach would be to build the matrix with
the binormal, normal, and tangent as the matrix columns from the
very beginning.  That way, no transpose is required:

        resliceAxes->SetElement(comp, 0, binormal[comp]);
        resliceAxes->SetElement(comp, 1, normal[comp]);
        resliceAxes->SetElement(comp, 2, tangent[comp]);

And you're correct that the code was simply transforming the origin
back and forth.  It makes more sense to just use the origin as-is:

        resliceAxes->SetElement(0, 3, origin[0]);
        resliceAxes->SetElement(1, 3, origin[1]);
        resliceAxes->SetElement(2, 3, origin[2]);
        this->reslicer->SetResliceAxes(resliceAxes);

Now the best way to think of the rotation is as follows.  The output
of vtkImageReslice is (in this case) an XY plane with a given extent
and sample spacing.  The job of the ResliceAxes is to rotate that
plane so that it "cuts" (or "slices") the input data at the correct angles.

The way that the vtkImageReslice algorithm works is this: it loops
through the output points, and for each of these points it
1) computes (x,y,z) according to the OutputSpacing and OutputOrigin
2) applies the ResliceAxes matrix to (x,y,z,1) to get (x',y',z',1)
3) samples (i.e. interpolates) the input image at (x',y',z') to get the
value to use for the output voxel at (x,y,z)

 - David



On Wed, Dec 3, 2014 at 3:45 PM, zarko.milosevic <zarko at kg.ac.rs> wrote:

> Dear David,
>
> I have encountered on some class vtkSplineDrivenImageSlicer which
> implements
> everything that i need for the my task. Actually that class is facade
> (wrapper) class which uses vtkImageReslice for reslicing and
> vtkFrenetSerretFrame for generating resliceAxes of vtkImageReslice.
> http://www.vtkjournal.org/browse/publication/838
>
> To sum up. This class as input requires image data and path in form of poly
> line. Using the path class generates three orthogonal vector representing
> the local coordinate frame in every point of the polyline. For those
> purposes this class uses Frenet Serret formula implemented in class
> vtkFrenetSerretFrame. Using those vectors resliceAxes are generated and new
> slices are extracted.
>
> I have problem with one piece of code from that class to understand. This
> is
> where i`m stuck:
>
> for ( int comp = 0; comp < 3; comp++ )
> {
> // Here reslice matrix is built using thre ortogonal vectors generated in
> previous step from path
>         resliceAxes->SetElement(0,comp,binormal[comp]);
>         resliceAxes->SetElement(1,comp,normal[comp]);
>         resliceAxes->SetElement(2,comp,tangent[comp]);
>
> // Here is calculated orgin of the slice so it would not be in the origin
> of
> the frame (resliceaxes) but in in  // lower left corner of the slice
> because
> sliceExtent is from 0, sliceExtent[0] and etc.
>         origin[comp] = center[comp] -
> normal[comp]*this->SliceExtent[1]*this->SliceSpacing[1]/2.0
>                                 -
> binormal[comp]*this->SliceExtent[0]*this->SliceSpacing[0]/2.0;
> }
>
> //! Transform the origin in the homogeneous coordinate space. Is that
> necessary in this way ?
>                  origin[3] = 1.0;
>                  double originXYZW[4];
>                  resliceAxes->MultiplyPoint(origin, originXYZW);
>
> //! Get the new origin from the transposed matrix.
>          resliceAxes->Transpose();
>          double neworiginXYZW[4];
>          resliceAxes->MultiplyPoint(originXYZW, neworiginXYZW);
>
>          resliceAxes->SetElement(0,3,neworiginXYZW[0]);
>          resliceAxes->SetElement(1,3,neworiginXYZW[1]);
>          resliceAxes->SetElement(2,3,neworiginXYZW[2]);
>  this->reslicer->SetResliceAxes( resliceAxes );
>
> Creating the newOriginXYZW in this way does not have any sense.
> newOriginXYZW is the same as Origin.
> Transposing the resliceaxes where only rotation matrix elements are present
> have same result as inverting the rotation matrix.
> originXYZW = resliceAxes(onlyRotation) * origin
> neworiginXYZW = resliceAxes(onlyRotation)^-1 * originXYZW => origin
> But that is not main problem.
>
> Main question is do you have idea why transposed (inverted rotation) is
> passed to reslicer ?
> Results with including Transposed matrix is little bit better than without
> it. Images are little bit better aligned but nothing significant.
>
> Best regards
> Zarko
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/vtkusers/attachments/20141203/9b6a0cee/attachment.html>


More information about the vtkusers mailing list