Skip to content

Commit

Permalink
New class for extracting surfaces from label masks
Browse files Browse the repository at this point in the history
The discrete flying edges classes extract isocontours from label masks.
Label masks are not continuous so special interpolation and treatment is
required. Each contour value generates a separate region.

Also, documentation in the form of cross referencing other contouring
classes was added. The discrete isocontouring classes are not well known
but very powerful and should be used more often.
  • Loading branch information
wschroed committed Jan 3, 2018
1 parent feb05ce commit 13711b3
Show file tree
Hide file tree
Showing 19 changed files with 2,962 additions and 10 deletions.
7 changes: 3 additions & 4 deletions Filters/Core/vtkContourFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@
* normals.
*
* @sa
* vtkMarchingContourFilter vtkMarchingCubes vtkSliceCubes
* vtkMarchingSquares vtkImageMarchingCubes
* vtkFlyingEdges3D vtkFlyingEdges2D vtkDiscreteFlyingEdges3D
* vtkDiscreteFlyingEdges2D vtkMarchingContourFilter vtkMarchingCubes
* vtkSliceCubes vtkMarchingSquares vtkImageMarchingCubes
*/

#ifndef vtkContourFilter_h
Expand Down Expand Up @@ -294,5 +295,3 @@ inline void vtkContourFilter::GenerateValues(int numContours, double


#endif


2 changes: 1 addition & 1 deletion Filters/Core/vtkFlyingEdges3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
*
* @sa
* vtkContourFilter vtkFlyingEdges2D vtkSynchronizedTemplates3D
* vtkMarchingCubes vtkSMPFlyingEdges3D
* vtkMarchingCubes vtkDiscreteFlyingEdges3D
*/

#ifndef vtkFlyingEdges3D_h
Expand Down
16 changes: 15 additions & 1 deletion Filters/Core/vtkMarchingCubes.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,22 @@
* This filter is specialized to volumes. If you are interested in
* contouring other types of data, use the general vtkContourFilter. If you
* want to contour an image (i.e., a volume slice), use vtkMarchingSquares.
*
* @sa
* Much faster implementations for isocontouring are available. In
* particular, vtkFlyingEdges3D and vtkFlyingEdges2D are much faster
* and if built with the right options, multithreaded, and scale well
* with additional processors.
*
* @sa
* If you are interested in extracting surfaces from label maps,
* consider using vtkDiscreteFlyingEdges3D, vtkDiscreteFlyingEdges2D, or
* vtkDiscreteMarchingCubes.
*
* @sa
* vtkContourFilter vtkSliceCubes vtkMarchingSquares vtkDividingCubes
* vtkFlyingEdges3D vtkFlyingEdges2D vtkSynchronizedTemplates3D
* vtkSynchronizedTemplates2D vtkContourFilter vtkSliceCubes
* vtkMarchingSquares vtkDividingCubes vtkDiscreteMarchingCubes
*/

#ifndef vtkMarchingCubes_h
Expand Down
2 changes: 2 additions & 0 deletions Filters/General/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ set(Module_SRCS
vtkDeformPointSet.cxx
vtkDensifyPolyData.cxx
vtkDicer.cxx
vtkDiscreteFlyingEdges2D.cxx
vtkDiscreteFlyingEdges3D.cxx
vtkDiscreteMarchingCubes.cxx
vtkEdgePoints.cxx
vtkExtractSelectedFrustum.cxx
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
571c2c61232b41a961352e2fd036d984
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ebac6173f98ecd9d5eeb37a16ae17377
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20753aecfc1b8ff6ca4880d4ed8945dc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20753aecfc1b8ff6ca4880d4ed8945dc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7c4def60144af2d5fd57976222bd5d26
2 changes: 2 additions & 0 deletions Filters/General/Testing/Python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ vtk_add_test_python(
TestClipOutline.py
TestCurvatures.py
TestDeformPointSet.py
TestDiscreteFlyingEdges2D.py
TestDiscreteFlyingEdges3D.py
TestDiscreteMarchingCubes.py
TestDiscreteMarchingCubesAdjacentScalars.py
TestGraphLayoutFilter.py
Expand Down
63 changes: 63 additions & 0 deletions Filters/General/Testing/Python/TestDiscreteFlyingEdges2D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python
import vtk
from vtk.util.misc import vtkGetDataRoot
VTK_DATA_ROOT = vtkGetDataRoot()

# Create the RenderWindow, Renderer and both Actors
#
ren1 = vtk.vtkRenderer()
ren1.SetBackground(1,1,1)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

# Read the data. Note this creates a 3-component scalar.
red = vtk.vtkPNGReader()
red.SetFileName(VTK_DATA_ROOT + "/Data/RedCircle.png")
red.Update()

# Next filter can only handle RGB *(&&*@
extract = vtk.vtkImageExtractComponents()
extract.SetInputConnection(red.GetOutputPort())
extract.SetComponents(0,1,2)

# Quantize the image into an index
quantize = vtk.vtkImageQuantizeRGBToIndex()
quantize.SetInputConnection(extract.GetOutputPort())
quantize.SetNumberOfColors(3)

# Create the pipeline
discrete = vtk.vtkDiscreteFlyingEdges2D()
discrete.SetInputConnection(quantize.GetOutputPort())
discrete.SetValue(0,0)

# Create polgons
polyLoops = vtk.vtkContourLoopExtraction()
polyLoops.SetInputConnection(discrete.GetOutputPort())

# Triangle filter because concave polygons are not rendered correctly
triF = vtk.vtkTriangleFilter()
triF.SetInputConnection(polyLoops.GetOutputPort())

# Polylines are generated
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(discrete.GetOutputPort())
mapper.ScalarVisibilityOff()

actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(0,0,0)

# Polygons are displayed
polyMapper = vtk.vtkPolyDataMapper()
polyMapper.SetInputConnection(triF.GetOutputPort())

polyActor = vtk.vtkActor()
polyActor.SetMapper(polyMapper)

ren1.AddActor(actor)
ren1.AddActor(polyActor)

renWin.Render()
iren.Start()
90 changes: 90 additions & 0 deletions Filters/General/Testing/Python/TestDiscreteFlyingEdges3D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env python
import vtk
from vtk.util.misc import vtkGetDataRoot
VTK_DATA_ROOT = vtkGetDataRoot()

# Create the RenderWindow, Renderer and both Actors
#
ren1 = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren1)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

math = vtk.vtkMath()

# Generate some random colors
def MakeColors (lut, n):
lut.SetNumberOfColors(n)
lut.SetTableRange(0, n - 1)
lut.SetScaleToLinear()
lut.Build()
lut.SetTableValue(0, 0, 0, 0, 1)
math.RandomSeed(5071)
i = 1
while i < n:
lut.SetTableValue(i, math.Random(.2, 1),
math.Random(.2, 1), math.Random(.2, 1), 1)
i += 1

lut = vtk.vtkLookupTable()
MakeColors(lut, 256)
n = 20
radius = 10

# This has been moved outside the loop so that the code can be correctly
# translated to python
blobImage = vtk.vtkImageData()

i = 0
while i < n:
sphere = vtk.vtkSphere()
sphere.SetRadius(radius)
max = 50 - radius
sphere.SetCenter(int(math.Random(-max, max)),
int(math.Random(-max, max)), int(math.Random(-max, max)))

sampler = vtk.vtkSampleFunction()
sampler.SetImplicitFunction(sphere)
sampler.SetOutputScalarTypeToFloat()
sampler.SetSampleDimensions(51, 51, 51)
sampler.SetModelBounds(-50, 50, -50, 50, -50, 50)

thres = vtk.vtkImageThreshold()
thres.SetInputConnection(sampler.GetOutputPort())
thres.ThresholdByLower(radius * radius)
thres.ReplaceInOn()
thres.ReplaceOutOn()
thres.SetInValue(i + 1)
thres.SetOutValue(0)
thres.Update()
if (i == 0):
blobImage.DeepCopy(thres.GetOutput())

maxValue = vtk.vtkImageMathematics()
maxValue.SetInputData(0, blobImage)
maxValue.SetInputData(1, thres.GetOutput())
maxValue.SetOperationToMax()
maxValue.Modified()
maxValue.Update()

blobImage.DeepCopy(maxValue.GetOutput())

i += 1

discrete = vtk.vtkDiscreteFlyingEdges3D()
discrete.SetInputData(blobImage)
discrete.GenerateValues(n, 1, n)

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(discrete.GetOutputPort())
mapper.SetLookupTable(lut)
mapper.SetScalarRange(0, lut.GetNumberOfColors())

actor = vtk.vtkActor()
actor.SetMapper(mapper)

ren1.AddActor(actor)

renWin.Render()
iren.Start()
3 changes: 1 addition & 2 deletions Filters/General/Testing/Python/TestDiscreteMarchingCubes.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,4 @@ def MakeColors (lut, n):
ren1.AddActor(actor)

renWin.Render()

#iren.Start()
iren.Start()
Loading

0 comments on commit 13711b3

Please sign in to comment.