Quantcast

Ordering wrong when convert vtkImageData to vtkPolyData

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Ordering wrong when convert vtkImageData to vtkPolyData

Summer Sun
I have a 2d vtkImageData with only two value, 0 and 255.

I want to get a boundary of pixels valued 255.

Currently I use vtkMarchingSquares to get the vtkPolyData but the order of points are wrong, therefore the result is shown below.


How may I fix this ordering probem?
Or is there any other way for me to get and draw the boundary on original image?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Ordering wrong when convert vtkImageData to vtkPolyData

David Gobbi
Hi Summer,

The output of vtkMarchingSquares is a set of line segments.  If you call GetLines() on the output, you get a vtkCellArray that contains the line segments.  However, the line segments are not in order.

To put the line segments in order, try using vtkStripper.  The vtkStripper takes line segments as input, and produces a polyline as output.  So if you call GetLines() on the output of vtkStripper, then the vtkCellArray should index the points in the correct order.

Cheers,
 - David


On Thu, Mar 16, 2017 at 7:23 AM, Summer Sun <[hidden email]> wrote:
I have a 2d vtkImageData with only two value, 0 and 255.

I want to get a boundary of pixels valued 255.

Currently I use vtkMarchingSquares to get the vtkPolyData but the order of
points are wrong, therefore the result is shown below.
<http://vtk.1045678.n5.nabble.com/file/n5742492/chaos.png>

How may I fix this ordering probem?
Or is there any other way for me to get and draw the boundary on original
image?

_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Ordering wrong when convert vtkImageData to vtkPolyData

Summer Sun
Thank you so much David,

I have tried your method but the result I use vtkStripper is exactly the same...
I saw the vtk documents below that might be help but I don't quite get it:
---
Warning
If triangle strips or poly-lines exist in the input data they will be passed through to the output data. This filter will only construct triangle strips if triangle polygons are available; and will only construct poly-lines if lines are available.
---

Here's my related code:
...
// get marching squares of image data
vtkSmartPointer<vtkMarchingSquares> segContour = vtkSmartPointer<vtkMarchingSquares>::New();
segContour->SetInputData(segmentation); // segmentation is my image data
segContour->SetValue(0, 255);
segContour->Update();

// use vtkStripper to process marching squares data
vtkSmartPointer<vtkStripper> segPolyStripper = vtkSmartPointer<vtkStripper>::New();
segPolyStripper->SetInputData(segContour->GetOutput());
segPolyStripper->Update();

// draw the contour
contourWidget->Initialize(segPolyStripper->GetOutput());
...

Thanks for your help
Summer
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Ordering wrong when convert vtkImageData to vtkPolyData

David Gobbi
Hi Summer,

You need to call GetLines() on the output of the vtkStripper, because that will return the vtkCellArray that gives the correct ordering of the points.  The vtkCellArray will provide the point Ids in the correct order.

 - David


On Thu, Mar 16, 2017 at 11:13 PM, Summer Sun <[hidden email]> wrote:
Thank you so much David,

I have tried your method but the result I use vtkStripper is exactly the
*same*...
I saw the vtk documents below that might be help but I don't quite get it:
---
*Warning*
If triangle strips or poly-lines exist in the input data they *will be
passed through to the output data*. This filter will only construct triangle
strips if triangle polygons are available; and will only construct
poly-lines if lines are available.
---

*Here's my related code:*
...
/// get marching squares of image data/
vtkSmartPointer<vtkMarchingSquares> segContour =
vtkSmartPointer<vtkMarchingSquares>::New();
segContour->SetInputData(segmentation); /// segmentation is my image data/
segContour->SetValue(0, 255);
segContour->Update();

/// use vtkStripper to process marching squares data/
vtkSmartPointer<vtkStripper> segPolyStripper =
vtkSmartPointer<vtkStripper>::New();
segPolyStripper->SetInputData(segContour->GetOutput());
segPolyStripper->Update();

/// draw the contour/
contourWidget->Initialize(segPolyStripper->GetOutput());
...

Thanks for your help
Summer

_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Ordering wrong when convert vtkImageData to vtkPolyData

Summer Sun
Thank you David,
But I use code below, the render result still doesn't change.

...
// get marching squares of image data
vtkSmartPointer<vtkMarchingSquares> segContour =
vtkSmartPointer<vtkMarchingSquares>::New();
segContour->SetInputData(segmentation); // segmentation is my image data
segContour->SetValue(0, 255);
segContour->Update();

// use vtkStripper to process marching squares data
vtkSmartPointer<vtkStripper> segPolyStripper =
vtkSmartPointer<vtkStripper>::New();
segPolyStripper->SetInputData(segContour->GetOutput());
segPolyStripper->Update();

// set points and lines according to stripper output
vtkSmartPointer<vtkPolyData> segPoly = vtkSmartPointer<vtkPolyData>::New();
segPoly->SetPoints(segContour->GetOutput()->GetPoints());
segPoly->SetLines(segPolyStripper->GetOutput()->GetLines());

// draw the contour
contourWidget->Initialize(segPoly);
...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Ordering wrong when convert vtkImageData to vtkPolyData

David Gobbi
Hi Summer,

For the contour widget, you will probably have to create a new vtkPoints object where the points have the ordering specified by the the cell array returned by stripper->GetLines().  The vtkStripper doesn't put the points in order, it just provides a cell array that specifies how to put the points in order.

 - David

On Fri, Mar 17, 2017 at 12:48 AM, Summer Sun <[hidden email]> wrote:
Thank you David,
But I use code below, the render result still doesn't change.

...
// get marching squares of image data
vtkSmartPointer<vtkMarchingSquares> segContour =
vtkSmartPointer<vtkMarchingSquares>::New();
segContour->SetInputData(segmentation); // segmentation is my image data
segContour->SetValue(0, 255);
segContour->Update();

// use vtkStripper to process marching squares data
vtkSmartPointer<vtkStripper> segPolyStripper =
vtkSmartPointer<vtkStripper>::New();
segPolyStripper->SetInputData(segContour->GetOutput());
segPolyStripper->Update();

*// set points and lines according to stripper output*
vtkSmartPointer<vtkPolyData> segPoly = vtkSmartPointer<vtkPolyData>::New();
segPoly->SetPoints(segContour->GetOutput()->GetPoints());
segPoly->SetLines(segPolyStripper->GetOutput()->GetLines());

// draw the contour
contourWidget->Initialize(segPoly);
...



--
View this message in context: http://vtk.1045678.n5.nabble.com/Ordering-wrong-when-convert-vtkImageData-to-vtkPolyData-tp5742492p5742504.html
Sent from the VTK - Users mailing list archive at Nabble.com.
_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/vtkusers


_______________________________________________
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

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/vtkusers
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Ordering wrong when convert vtkImageData to vtkPolyData

Summer Sun
This post was updated on .
Thank you David, I have now reach my goal and I would like to paste my code here for others to reference.

I have an vtkImageData with two pixel value: 0 and 255, I want to draw the boundary valued 255 using vtkContourWidget.

1. I use vtkMarchingSquares, and the output of marching squares is a vtkPolyData while the lines segments are not ordered;
2. I use vtkStripper to order the output of vtkMarchingSquares;
3. After process by vtkStripper, the line segments (vtkCellArray) of vtkPolydata is correctly ordered, and I use the vtkCellArray to order vtkPoints (for how to access data in vtkCellArray, you may take David's another post for reference).
4. Finally I use ordered points and lines to construct a new vtkPolyData and draw it.

My code block is shown below:

// get marching squares of image data
vtkSmartPointer<vtkMarchingSquares> segContour =
vtkSmartPointer<vtkMarchingSquares>::New();
segContour->SetInputData(segmentation); // segmentation is my image data
segContour->SetValue(0, 255);
segContour->Update();

// use vtkStripper to order line segments in correct order
vtkSmartPointer<vtkStripper> segPolyStripper =
vtkSmartPointer<vtkStripper>::New();
segPolyStripper->SetInputData(segContour->GetOutput());
segPolyStripper->Update();

// order points according to ordered lines segments
vtkSmartPointer<vtkCellArray> orderedLines = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPoints> originPoints = vtkSmartPointer<vtkPoints>::New();
originPoints = segContour->GetOutput()->GetPoints();
orderedLines = segPolyStripper->GetOutput()->GetLines();
int numPts = originPoints->GetNumberOfPoints();
vtkSmartPointer<vtkPoints> orderedPoints = vtkSmartPointer<vtkPoints>::New();

// access data of vtkCellArray as order dictionary
vtkIdType numCells = orderedLines->GetNumberOfCells();
vtkIdType cellLocation = 0; // the index into the cell array
vtkIdType numIds; // to hold the size of the cell
vtkIdType *pointIds; // to hold the ids in the cell
for (vtkIdType i = 0; i < numCells; i++) {
        orderedLines->GetCell(cellLocation, numIds, pointIds);
        pointIds[0], pointIds[1], pointIds[2];
        cellLocation += 1 + numIds;
}

// order points according to dictionary above
for (vtkIdType i = 0; i < numPts - 1; i++) {
        vtkIdType pointId = pointIds[i];
        orderedPoints->InsertPoint(static_cast<vtkIdType>(i), originPoints->GetPoint(pointId));
}

// construct a poly data with ordered points and lines
vtkSmartPointer<vtkPolyData> segPoly = vtkSmartPointer<vtkPolyData>::New();
segPoly->SetPoints(orderedPoints);
segPoly->SetLines(orderedLines);

// draw the contour
contourWidget->Initialize(segPoly);

Loading...