Difference between revisions of "2010 Summer Project Week SegmentationMeshEmbeddedContours"
(Created page with '__NOTOC__ <gallery> Image:PW-SLC2010.png|Projects List Image:BrainH.png|Surface Mean Curvature Image:Sulci6_done2.png|Converged Contour Surr…') |
|||
(10 intermediate revisions by the same user not shown) | |||
Line 6: | Line 6: | ||
Image:Sulci3_init_3.png|Initial Points From User | Image:Sulci3_init_3.png|Initial Points From User | ||
Image:bone-end3.png|Segmenting Tibia Fracture via Surface Geometry | Image:bone-end3.png|Segmenting Tibia Fracture via Surface Geometry | ||
+ | Image:Surface_H_c.png|Surface curvature display for segmented colon MRI in Slicer | ||
+ | Image:lsvtk_qtcreator.png|'Extreme Programming' with QT Creator in Ubuntu Linux | ||
</gallery> | </gallery> | ||
− | ==Key Investigators== | + | == Key Investigators == |
* Georgia Tech: Peter Karasev, Karol Chudy, Allen Tannenbaum | * Georgia Tech: Peter Karasev, Karol Chudy, Allen Tannenbaum | ||
* BWH: Ron Kikinis | * BWH: Ron Kikinis | ||
Line 19: | Line 21: | ||
+ | </div> | ||
+ | <div style="width: 40%; float: left;"> | ||
+ | |||
+ | <h3>Approach, Plan</h3> | ||
+ | |||
+ | Surface Geometry Computation | ||
+ | |||
+ | Closest Path Between Initial Points | ||
+ | |||
+ | Fast Level Set Implementation for Unstructured Mesh | ||
+ | |||
+ | Support 'global geometry' estimation for statistical analysis versus local-only for fast segmentation | ||
+ | |||
+ | Extend Functionality in VTK and ITK to perform needed operations | ||
− | |||
− | + | The module pipeline now contains three classes that extend vtkPolyDataAlgorithm. It now makes use of vtkSmartPointer. | |
− | + | * vtkInitClosedPath : take in poly data and set of fiducial points, create a closed path including the closest points on the mesh to the given fiducials. Searches for pre-existence of geometry information, pass-through if it already exists. | |
− | + | * vtkComputeLocalGeometry : take in poly data, compute curvature, its derivatives, and related differential geometric quantities. Uses its own version of curvature computation- vtk versions are not useable because they only consider 1-neighborhood. Searches for pre-existence of geometry information, pass-through if it already exists. | |
− | + | * vtkLevelSetMeshEvolver : take in poly data with a scalar array defining the current region boundaries. Update the boundaries with curve evolution and return poly data with updated scalar array. | |
</div> | </div> | ||
Line 35: | Line 50: | ||
<h3>Progress</h3> | <h3>Progress</h3> | ||
− | + | 1. Setup Slicer4 "superbuild", verified module consistency therein | |
− | + | 2. Signed up for ITK write access as there is some partial overlap and functions in this module perform tasks that ITK doesn't do: | |
+ | i. large neighborhood curvature computation via paraboloid fit | ||
+ | ii. unstructured graph sparse field level sets ) | ||
+ | 3. From discussion with Ron Kikinis and Karl Fritscher, going forward must branch the functionality: | ||
+ | i. don't compute 'global geometry' in Slicer, must look up neighbors as needed as user is only segmenting a small piece of large mesh | ||
+ | ii. allow more geometric information to be returned and stored for statistical analysis and registration of surfaces | ||
+ | 4. Curvature overlay in Slicer: | ||
<gallery> | <gallery> | ||
− | Image: | + | Image:Surface_H_c.png|surface curvature display inside slicer (vtkFloatArray attached to returned vtkPolyData) |
</gallery> | </gallery> | ||
+ | 5. | ||
+ | Implemented a helpful re-factor, convert a beefy struct with bunch of global functions to a class with member functions plus non-member non-friend helper functions in anonymous namespace | ||
+ | <pre> | ||
+ | |||
+ | /* NEW */ | ||
+ | namespace { | ||
+ | TestFunc1( const MeshData& data ) { ... } | ||
+ | } | ||
− | + | class MeshData{ | |
+ | public: | ||
+ | functionA( ); | ||
+ | functionB( ); | ||
+ | ... | ||
+ | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | * | + | /* OLD */ |
+ | struct MeshData{ | ||
+ | |||
+ | member1; | ||
+ | member2; | ||
+ | .... | ||
+ | } | ||
+ | |||
+ | functionA( MeshData* ) { ... } | ||
+ | functionB( MeshData* ) { ... } | ||
+ | ... | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | 6. Learn about and setup qtcreator, continue development of stand-alone frontend and module there (it blows Eclipse away for C/C++) | ||
+ | <gallery> | ||
+ | Image:lsvtk_qtcreator.png|Module development in QT Creator (in Ubuntu Linux 9.10) | ||
+ | </gallery> | ||
+ | |||
− | + | Some implementation specifics | |
Development is much easier now for two reasons: | Development is much easier now for two reasons: | ||
Line 87: | Line 133: | ||
<pre> | <pre> | ||
// Input: mesh and indices of vertices for initialization | // Input: mesh and indices of vertices for initialization | ||
− | vtkPolyData* MeshContourEvolver::entry_main( vtkPolyData* inputMesh, const vector<int>& initPointVertexIndices ) | + | vtkPolyData* MeshContourEvolver::entry_main( vtkPolyData* inputMesh, |
+ | const vector<int>& initPointVertexIndices ) | ||
{ | { | ||
// instantiate output mesh | // instantiate output mesh | ||
Line 116: | Line 163: | ||
</div> | </div> | ||
</div> | </div> | ||
− | + | <div style="width: 95%; float: left;"> | |
− | <div style="width: | ||
==References== | ==References== | ||
P.A. Karasev, J.G. Malcolm, M. Niethammer, R. Kikinis, A. Tannenbaum. User-Driven 3D Mesh Region Targeting. SPIE Medical Imaging 2010. | P.A. Karasev, J.G. Malcolm, M. Niethammer, R. Kikinis, A. Tannenbaum. User-Driven 3D Mesh Region Targeting. SPIE Medical Imaging 2010. | ||
</div> | </div> |
Latest revision as of 14:30, 25 June 2010
Home < 2010 Summer Project Week SegmentationMeshEmbeddedContoursKey Investigators
- Georgia Tech: Peter Karasev, Karol Chudy, Allen Tannenbaum
- BWH: Ron Kikinis
Objective
We are developing methods for segmentation of surfaces defined by polygonal meshes. In image or volume-slice segmentation, 'information' comes from image intensity, while in mesh surface segmentation the information is purely geometric. The goal of this project is to develop algorithms allowing a user to quickly and robustly segment one or several regions on a surface. Specifically, it is required to reconcile some concepts in classical differential geometry and embedded curves with the numerical and discrete-space constraints of polygon meshes.
Approach, Plan
Surface Geometry Computation
Closest Path Between Initial Points
Fast Level Set Implementation for Unstructured Mesh
Support 'global geometry' estimation for statistical analysis versus local-only for fast segmentation
Extend Functionality in VTK and ITK to perform needed operations
The module pipeline now contains three classes that extend vtkPolyDataAlgorithm. It now makes use of vtkSmartPointer.
- vtkInitClosedPath : take in poly data and set of fiducial points, create a closed path including the closest points on the mesh to the given fiducials. Searches for pre-existence of geometry information, pass-through if it already exists.
- vtkComputeLocalGeometry : take in poly data, compute curvature, its derivatives, and related differential geometric quantities. Uses its own version of curvature computation- vtk versions are not useable because they only consider 1-neighborhood. Searches for pre-existence of geometry information, pass-through if it already exists.
- vtkLevelSetMeshEvolver : take in poly data with a scalar array defining the current region boundaries. Update the boundaries with curve evolution and return poly data with updated scalar array.
Progress
1. Setup Slicer4 "superbuild", verified module consistency therein
2. Signed up for ITK write access as there is some partial overlap and functions in this module perform tasks that ITK doesn't do:
i. large neighborhood curvature computation via paraboloid fit ii. unstructured graph sparse field level sets )
3. From discussion with Ron Kikinis and Karl Fritscher, going forward must branch the functionality:
i. don't compute 'global geometry' in Slicer, must look up neighbors as needed as user is only segmenting a small piece of large mesh ii. allow more geometric information to be returned and stored for statistical analysis and registration of surfaces
4. Curvature overlay in Slicer:
5. Implemented a helpful re-factor, convert a beefy struct with bunch of global functions to a class with member functions plus non-member non-friend helper functions in anonymous namespace
/* NEW */ namespace { TestFunc1( const MeshData& data ) { ... } } class MeshData{ public: functionA( ); functionB( ); ... } /* OLD */ struct MeshData{ member1; member2; .... } functionA( MeshData* ) { ... } functionB( MeshData* ) { ... } ...
6. Learn about and setup qtcreator, continue development of stand-alone frontend and module there (it blows Eclipse away for C/C++)
Some implementation specifics
Development is much easier now for two reasons:
1. After the reformulation of external interface, the standalone application which can be built easily in windows has virtually identical interface to the module as the Slicer CLI entry point. This allows rapid development in the standalone demo in windows to be copied directly to Slicer in linux.
2. Much improved knowledge of linux development, particularly being able to execute the various scripts for Slicer without doing getbuildtest.tcl; saves time.
The namespace:
namespace MeshContourEvolver { // Input: mesh and indices of vertices for initialization vtkPolyData* entry_main( vtkPolyData* inputMesh, const vector<int>& initPointVertexIndices ); // Input: mesh and 3D points for initialization. This is what you get // when inputting 'fiducials' in Slicer GUI. The 3D points // are not on the mesh, you need to first find closest points on the mesh. vtkPolyData* entry_main( vtkPolyData* inputMesh, const vector< vector<float> >& initPoints3D ); // Input: mesh only. No initialization of points; either continue // evolution of existing curve or only pre-compute geometry! vtkPolyData* entry_main( vtkPolyData* inputMesh ); }
The pipeline code; e.g. external interface. Functionality is encapsulated in the vtkPolyDataAlgorithm subclasses.
// Input: mesh and indices of vertices for initialization vtkPolyData* MeshContourEvolver::entry_main( vtkPolyData* inputMesh, const vector<int>& initPointVertexIndices ) { // instantiate output mesh vtkPolyData* outputMesh = vtkPolyData::New(); // algorithm #1: initialization of path vtkSmartPointer<vtkInitClosedPath> initPath = vtkSmartPointer<vtkInitClosedPath>::New(); initPath->SetInput( inputMesh ); // algorithm #2: computing the geometry (if the input data // does NOT already have a scalar data set containing it) vtkSmartPointer<vtkComputeLocalGeometry> computeGeometry = vtkSmartPointer<vtkComputeLocalGeometry>::New(); computeGeometry->SetInputConnection( initPath->GetOutputPort() ); // algorithm #3: run curve evolution and update the scalar dataset for display vtkSmartPointer<vtkLevelSetMeshEvolver> evolver = vtkSmartPointer<vtkLevelSetMeshEvolver>::New(); evolver->SetInputConnection( computeGeometry->GetOutputPort() ); evolver->Update(); // register and return the result of the pipeline of algorithms vtkSmartPointer<vtkPolyData> result = evolver->GetOutput(); outputMesh->DeepCopy( result ); return outputMesh; }
References
P.A. Karasev, J.G. Malcolm, M. Niethammer, R. Kikinis, A. Tannenbaum. User-Driven 3D Mesh Region Targeting. SPIE Medical Imaging 2010.