[vtkusers] vtkPolyDataToImageStencil with partial volume
David Gobbi
david.gobbi at gmail.com
Thu Feb 24 02:59:18 EST 2011
I've only had a chance to do a quick look through your code, only one
thing looks definitely wrong:
extruder.SetVector(spacing);
This extrudes the contour along a diagonal line, which is probably not
what you intended. You want to extrude only in the direction of the
slice normal. Take a look at how the extruder is set up in
VTK/Widgets/Testing/Cxx/TestImageTracerWidget.cxx and also note the
TransformPolyData that is applied to the extruder's output.
- David
On Wed, Feb 23, 2011 at 8:49 PM, Jonathan Morra <jonmorra at gmail.com> wrote:
> 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
>>> >> >> >> >
>>> >> >> >> >
>>> >> >> >
>>> >> >> >
>>> >> >
>>> >> >
>>> >
>>> >
>>
>
>
More information about the vtkusers
mailing list