[vtkusers] vtkPolyDataToImageStencil with partial volume

Jonathan Morra jonmorra at gmail.com
Wed Feb 23 22:49:44 EST 2011


Here's a copy of a small working program in Java that shows the issues that
I'm talking about.  The program will spit out 2 lines of text.  I need them
both to evaluate to true (that the center and bounds stay the same).  In
addition a render window will open up and clearly show that the two circles
do not line up with each other (again they should).  Please let me know how
I can fix this problem.

Thanks!!

import vtk.*;
import java.util.Arrays;

public class PolyDataToImageToPolyDataTest {
    static {
        System.loadLibrary("vtkCommonJava");
        System.loadLibrary("vtkFilteringJava");
        System.loadLibrary("vtkGenericFilteringJava");
        System.loadLibrary("vtkGraphicsJava");
        System.loadLibrary("vtkHybridJava");
        System.loadLibrary("vtkImagingJava");
        System.loadLibrary("vtkIOJava");
        System.loadLibrary("vtkRenderingJava");
        System.loadLibrary("vtkVolumeRenderingJava");
        System.loadLibrary("vtkWidgetsJava");
    }

    public static void main(String[] args) {
        vtkRegularPolygonSource polygonSource = new
vtkRegularPolygonSource();

        polygonSource.SetNumberOfSides(50);
        polygonSource.SetRadius(50);
        polygonSource.GeneratePolygonOff();
        polygonSource.Update();

        vtkImageData blankImage = new vtkImageData();
        int[] extent = {0, 512, 0, 512, 0, 100};
        double[] origin = {-256, -256, 0};
        double[] spacing = {1, 1, 1};
        blankImage.SetExtent(extent);
        blankImage.SetOrigin(origin);
        blankImage.SetSpacing(spacing);
        blankImage.SetScalarTypeToUnsignedChar();
        blankImage.AllocateScalars();

        vtkPolyData initialCircle = polygonSource.GetOutput();
        vtkPolyData drawnCircle = new vtkPolyData();
        drawnCircle.DeepCopy(initialCircle);
        // I'm choosing 10 here because this problem gets exacerbated after
each run.  By varying this, the problem will get less or more severe.
        for (int i=0; i<10; i++) {
            vtkLinearExtrusionFilter extruder = new
vtkLinearExtrusionFilter();
            extruder.SetInput(drawnCircle);
            extruder.SetVector(spacing);
            extruder.Update();
            vtkPolyData extruderOutput = extruder.GetOutput();

            vtkPolyDataToImageStencil pol2Stenc = new
vtkPolyDataToImageStencil();
            pol2Stenc.SetTolerance(0);
            pol2Stenc.SetInput(extruderOutput);
            pol2Stenc.SetInformationInput(blankImage);
            pol2Stenc.Update();
            vtkImageStencilData pol2StencOutput = pol2Stenc.GetOutput();

            vtkImageStencil stencil = new vtkImageStencil();
            stencil.SetInput(blankImage);
            stencil.ReverseStencilOn();
            stencil.SetStencil(pol2StencOutput);
            stencil.Update();

            vtkImageData image = stencil.GetOutput();

            vtkMarchingSquares marching = new vtkMarchingSquares();
            marching.SetInput(image);
            // For some reason the circle moves in all 3 dimensions, so I
need to vary the z-coordinate w.r.t the iteration number
            marching.SetImageRange(new int[] {0, 512, 0, 512, i+1, i+1});
            marching.SetValue(0, 1);
            marching.Update();
            vtkPolyData marchingOutput = marching.GetOutput();

            vtkStripper stripper = new vtkStripper();
            stripper.SetInput(marchingOutput);
            stripper.Update();

            drawnCircle = stripper.GetOutput();
        }

        boolean sameCenter = Arrays.equals(drawnCircle.GetCenter(),
initialCircle.GetCenter());
        boolean sameBounds = Arrays.equals(drawnCircle.GetBounds(),
initialCircle.GetBounds());

        System.out.println("Same center: " + sameCenter);
        System.out.println("Same bounds: " + sameBounds);

        vtkPolyDataMapper circleMapper = new vtkPolyDataMapper();
        circleMapper.SetInput(initialCircle);
        circleMapper.ScalarVisibilityOff();
        circleMapper.Update();

        vtkActor circleActor = new vtkActor();
        circleActor.SetMapper(circleMapper);
        circleActor.GetProperty().SetRepresentationToSurface();
        circleActor.GetProperty().SetColor(1, 0, 0);

        vtkPolyDataMapper outCircleMapper = new vtkPolyDataMapper();
        outCircleMapper.SetInput(drawnCircle);
        outCircleMapper.ScalarVisibilityOff();
        outCircleMapper.Update();

        vtkActor outCircleActor = new vtkActor();
        outCircleActor.SetMapper(outCircleMapper);
        outCircleActor.GetProperty().SetRepresentationToSurface();
        outCircleActor.GetProperty().SetColor(0, 1, 0);

        vtkRenderer ren = new vtkRenderer();
        ren.AddActor(circleActor);
        ren.AddActor(outCircleActor);
        ren.SetBackground(0.1, 0.2, 0.4);

        vtkRenderWindow renWin = new vtkRenderWindow();
        renWin.AddRenderer(ren);

        vtkRenderWindowInteractor iren = new vtkRenderWindowInteractor();
        renWin.SetInteractor(iren);
        renWin.Render();
        ren.ResetCamera();
        iren.Start();
    }
}



On Wed, Feb 23, 2011 at 1:31 PM, Jonathan Morra <jonmorra at gmail.com> wrote:

> I tried it but it doesn't work, any other ideas?  I really appreciate your
> help.
>
>
> On Wed, Feb 23, 2011 at 1:01 PM, David Gobbi <david.gobbi at gmail.com>wrote:
>
>> Hi Jonathan,
>>
>> If you convert a contour to a binary image and then back to a contour,
>> you won't get the exactly the same contour back again.  That said, I
>> think that you can get what you want as long as you apply the correct
>> tolerances.  You can try a contour value of 0.9 for marching squares,
>> which is fairly tight but not so tight that it will cause the edge
>> problems that I mentioned in my earlier email. It might work, or it
>> might not work.
>>
>>  - David
>>
>>
>> On Wed, Feb 23, 2011 at 1:07 PM, Jonathan Morra <jonmorra at gmail.com>
>> wrote:
>> > I tried that and now the contour appears to both erode and dilate.  What
>> I'm
>> > doing it to take as input some contour data.  I then convert it to a
>> binary
>> > image for internal storage using vtkPolyDataToImageStencil.  I then take
>> a
>> > slice of the contour and show it to the user using vtkMarchingSquares.
>>  The
>> > user can then modify the contour.  When the user is done modifying the
>> > contour I convert it back to binary data for storage using the
>> > vtkPolyDataToImageStencil, and then again reslice it and use
>> > vtkMarchingSquares to show the user the contour again.  This process is
>> very
>> > quick.  What is happening is that the contour appears to be moving on
>> the
>> > screen as this cycle happens even if no edits are done.
>> > That is the underlying problem I need to fix.
>> >
>> > On Wed, Feb 23, 2011 at 11:59 AM, David Gobbi <david.gobbi at gmail.com>
>> wrote:
>> >>
>> >> I've never used marching squares, but I have a guess as
>> >> to what the problem might be.  If your binary image has
>> >> values "0" and "1" then you should contour it at "0.5".
>> >>
>> >>  - David
>> >>
>> >>
>> >> On Wed, Feb 23, 2011 at 12:27 PM, Jonathan Morra <jonmorra at gmail.com>
>> >> wrote:
>> >> > If that's the case, then maybe I could have issues on the other side
>> >> > (converting binary images to contours, I do both).  For this I'm
>> using
>> >> > vtkMarchingSquares followed by vtkStripper
>> >> > int[] extent = binaryOrgan.GetExtent();
>> >> >         switch (orientation) {
>> >> >             case OrthoPanel.ORIENTATION_XY:
>> >> >                 extent[4] = slice;
>> >> >                 extent[5] = slice;
>> >> >                 break;
>> >> >             case OrthoPanel.ORIENTATION_XZ:
>> >> >                 extent[2] = slice;
>> >> >                 extent[3] = slice;
>> >> >                 break;
>> >> >             case OrthoPanel.ORIENTATION_YZ:
>> >> >                 extent[0] = slice;
>> >> >                 extent[1] = slice;
>> >> >                 break;
>> >> >         }
>> >> > vtkMarchingSquares marching = new vtkMarchingSquares();
>> >> >         marching.SetInput(binaryOrgan);
>> >> >         marching.SetImageRange(extent);
>> >> >         marching.SetValue(0, 1);
>> >> >         marching.Update();
>> >> >         vtkPolyData marchingOutput = marching.GetOutput();
>> >> >         vtkStripper stripper = new vtkStripper();
>> >> >         stripper.SetInput(marchingOutput);
>> >> >         stripper.Update();
>> >> > Does anything look like it could be causing my issues there?
>> >> > On Wed, Feb 23, 2011 at 11:18 AM, David Gobbi <david.gobbi at gmail.com
>> >
>> >> > wrote:
>> >> >>
>> >> >> The value "1e-6" is a common tolerance because it is larger than
>> >> >> most roundoff errors that are likely to occur in the calculations,
>> >> >> but still small enough that it won't appreciably increase size of
>> the
>> >> >> region.
>> >> >>
>> >> >> Setting the tolerance to zero does exactly what you noted.  If the
>> >> >> pixel is exactly on the edge, then it is considered to be inside if
>> the
>> >> >> edge is a leading edge, or outside if the edge is a trailing edge.
>> >> >> This is done so that if you have two contours which are adjacent
>> >> >> (i.e. share an edge), the edge voxels will be considered to be in
>> >> >> just one of the two contours instead of in both.  If the tolerance
>> is
>> >> >> set larger than zero, then the edge pixels would always be
>> considered
>> >> >> to be in both contours.
>> >> >>
>> >> >> If you are dealing with rectangular contours, then the contour
>> >> >> lines should be made so that they lie halfway between pixels,
>> instead
>> >> >> of lying directly on top of the pixels.  Then there is no
>> uncertainty
>> >> >> about whether a pixel lies inside or outside.
>> >> >>
>> >> >>  - David
>> >> >>
>> >> >>
>> >> >> On Wed, Feb 23, 2011 at 11:58 AM, Jonathan Morra <
>> jonmorra at gmail.com>
>> >> >> wrote:
>> >> >> > I had the tolerance set to 0, and setting it to 1e-6 didn't fix
>> the
>> >> >> > problem.
>> >> >> >  How did you come up with that number?  What's wrong with setting
>> it
>> >> >> > to
>> >> >> > 0?
>> >> >> >  In my case usually the left and top side of the vtkImageData is
>> >> >> > being
>> >> >> > eroded, such that if I call the filter many times, the
>> vtkImageData
>> >> >> > will
>> >> >> > eventually be blank because it will all be eroded.   However,
>> >> >> > sometimes
>> >> >> > the
>> >> >> > bottom and right grow in size, I haven't figured out which
>> situations
>> >> >> > cause
>> >> >> > which.
>> >> >> >
>> >> >> > On Wed, Feb 23, 2011 at 10:54 AM, David Gobbi <
>> david.gobbi at gmail.com>
>> >> >> > wrote:
>> >> >> >>
>> >> >> >> Hi Jonathan,
>> >> >> >>
>> >> >> >> Whether a pixel is set depends on whether the center of the pixel
>> >> >> >> is inside or outside the contour, irregardless of what proportion
>> of
>> >> >> >> the pixel's volume is inside or outside.
>> >> >> >>
>> >> >> >> The only adjustment is the Tolerance, which should be set to
>> >> >> >> around 1e-6 so that pixels right on the edge of the contour
>> >> >> >> are considered to be inside.  The tolerance cannot be negative.
>> >> >> >>
>> >> >> >>  - David
>> >> >> >>
>> >> >> >>
>> >> >> >> On Wed, Feb 23, 2011 at 11:22 AM, Jonathan Morra
>> >> >> >> <jonmorra at gmail.com>
>> >> >> >> wrote:
>> >> >> >> > I am currently using vtkPolyDataToImageStencil to successfully
>> >> >> >> > convert
>> >> >> >> > contours represented as vtkPolyData to binary vtkImageData's.
>> >> >> >> >  However,
>> >> >> >> > I'm
>> >> >> >> > noticing a problem with the output sometimes.  Sometimes the
>> >> >> >> > resulting
>> >> >> >> > binary images are slightly smaller or slightly bigger than the
>> >> >> >> > poly
>> >> >> >> > data
>> >> >> >> > they were made from.  I assume this is the result of partial
>> >> >> >> > volume
>> >> >> >> > effects.
>> >> >> >> >  I would like to know 2 things
>> >> >> >> > 1.  How does vtkPolyDataToImageStencil handle partial volume.
>> >> >> >> > 2.  Is there a way to tune partial volume in
>> >> >> >> > vtkPolyDataToImageStencil?
>> >> >> >> >  For
>> >> >> >> > instance, a parameter which says if the contour includes less
>> than
>> >> >> >> > x
>> >> >> >> > percentage of the pixel then that pixel is 0.
>> >> >> >> > Thanks,
>> >> >> >> > Jon
>> >> >> >> > PS If my assumption about partial volume effects is wrong,
>> please
>> >> >> >> > let
>> >> >> >> > me
>> >> >> >> > know.
>> >> >> >> > _______________________________________________
>> >> >> >> > Powered by www.kitware.com
>> >> >> >> >
>> >> >> >> > Visit other Kitware open-source projects at
>> >> >> >> > http://www.kitware.com/opensource/opensource.html
>> >> >> >> >
>> >> >> >> > Please keep messages on-topic and check the VTK FAQ at:
>> >> >> >> > http://www.vtk.org/Wiki/VTK_FAQ
>> >> >> >> >
>> >> >> >> > Follow this link to subscribe/unsubscribe:
>> >> >> >> > http://www.vtk.org/mailman/listinfo/vtkusers
>> >> >> >> >
>> >> >> >> >
>> >> >> >
>> >> >> >
>> >> >
>> >> >
>> >
>> >
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20110223/d489bf71/attachment.htm>


More information about the vtkusers mailing list