GOFIGURE2  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
QGoContourLevelSetAlgo.h
Go to the documentation of this file.
1 /*=========================================================================
2  Authors: The GoFigure Dev. Team.
3  at Megason Lab, Systems biology, Harvard Medical school, 2009-11
4 
5  Copyright (c) 2009-11, President and Fellows of Harvard College.
6  All rights reserved.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  Redistributions of source code must retain the above copyright notice,
12  this list of conditions and the following disclaimer.
13  Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16  Neither the name of the President and Fellows of Harvard College
17  nor the names of its contributors may be used to endorse or promote
18  products derived from this software without specific prior written
19  permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 
33 =========================================================================*/
34 #ifndef __QGoContourLevelSetAlgo_h
35 #define __QGoContourLevelSetAlgo_h
36 
37 #include "QGoLevelSetAlgo.h"
38 #include "QGoFilterChanAndVese.h"
39 #include "QGoAlgorithmWidget.h"
40 #include "QGoAlgoParameter.h"
41 #include "QGoGUILibConfigure.h"
42 #include "vtkSmartPointer.h"
43 #include "vtkPolyData.h"
44 #include "vtkImageData.h"
45 
46 #include "vtkTransform.h"
47 #include "vtkTransformPolyDataFilter.h"
48 
49 class GoImageProcessor;
50 
51 
58 {
59 public:
60  QGoContourLevelSetAlgo(std::vector< vtkPoints* >* iSeeds, QWidget *iParent = 0);
62 
63  std::vector<vtkPolyData*> ApplyAlgo(
64  GoImageProcessor* iImages,
65  std::string iChannel,
66  bool iIsInvertedOn = false);
67 
68 protected:
69 
70  template < class TPixel>
71  vtkPolyData * ApplyLevelSetFilter(
72  const std::vector<double>& iCenter,
73  typename itk::Image< TPixel, 3 >::Pointer iImages,
74  const unsigned int& iOrientation)
75  {
76  assert( iCenter.size() == 3);
77 
78  const unsigned int ImageDimension = 3;
79 
80  typedef TPixel PixelType;
81  typedef itk::Image< PixelType, ImageDimension > ImageType;
82  typedef typename ImageType::Pointer ImagePointer;
83  typedef itk::Image< PixelType, 2 > ImageType2D;
84  typedef typename ImageType2D::Pointer ImageType2DPointer;
85 
86  // let's compute the bounds of the region of interest
87  double radius = this->m_Radius->GetValue();
88 
89  std::vector< double > bounds( 2 * ImageDimension, 0. );
90  unsigned int k = 0;
91  for( unsigned int dim = 0; dim < ImageDimension; dim++ )
92  {
93  bounds[k++] = iCenter[dim] - 2. * radius;
94  bounds[k++] = iCenter[dim] + 2. * radius;
95  }
96 
97  bounds[2*iOrientation] = iCenter[iOrientation];
98  bounds[2*iOrientation +1] = iCenter[iOrientation];
99 
100  for(int i=0;i<6;++i)
101  {
102  std::cout << "bounds: " << bounds[i] << std::endl;
103  }
104 
105  // then let's extract the Slice of Interest
106  ImageType2DPointer ITK_Slice_Image =
107  this->ITKExtractSlice<PixelType>( bounds, iImages );
108 
109  // Compute the segmentation in 3D
110  // why no call to the filter itself...?
111  QGoFilterChanAndVese Filter;
112  Filter.Apply2DFilter< PixelType >( ITK_Slice_Image,
113  iCenter,
114  0, // we dont want to extract ROI from input since we already did
115  this->m_Iterations->GetValue(),
116  this->m_Curvature->GetValue());
117 
119  ItkOutPut = Filter.GetOutput2D();
120 
121  // Here it would be better if the mesh extraction would be performed directly
122  // in ITK instead.
123  vtkImageData * FilterOutPutToVTK =
124  this->ConvertITK2VTK<
126  2 // image dimension
127  >( ItkOutPut );
128 
129  vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0.5);
130 
131  // translation transform -----------------------
132  //------------------------------------------------------------------------
133  double temp_bounds[6];
134  FilterOutPutToVTK->GetBounds( temp_bounds );
135 
136  double temp_center[3];
137  temp_center[0] = ( temp_bounds[0] + temp_bounds[1] ) * 0.5;
138  temp_center[1] = ( temp_bounds[2] + temp_bounds[3] ) * 0.5;
139  temp_center[2] = ( temp_bounds[4] + temp_bounds[5] ) * 0.5;
140 
141  vtkSmartPointer< vtkTransform > translation2 =
142  vtkSmartPointer< vtkTransform >::New();
143 
144  translation2->Translate(-temp_center[0],
145  -temp_center[1],
146  -temp_center[2]);
147 
148  vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform2 =
149  vtkSmartPointer< vtkTransformPolyDataFilter >::New();
150  mesh_transform2->SetTransform(translation2);
151  mesh_transform2->SetInput( temp_output );
152  mesh_transform2->Update();
153 
154  // rotation transform -----------------------
155  //------------------------------------------------------------------------
156  vtkSmartPointer< vtkTransform > translation =
157  vtkSmartPointer< vtkTransform >::New();
158  // rotate polydata if necessary
159  if(iOrientation == 0)
160  {
161  translation->RotateY(-90); // check if + or - 90
162  }
163  else if(iOrientation == 1)
164  {
165  translation->RotateX(-90); // check if + or - 90
166  }
167  else if(iOrientation == 2)
168  {
169  // no rotation, we are in the good plan
170  }
171 
172  vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform =
173  vtkSmartPointer< vtkTransformPolyDataFilter >::New();
174  mesh_transform->SetTransform(translation);
175  mesh_transform->SetInput( mesh_transform2->GetOutput() );
176  mesh_transform->Update();
177 
178  // translate back -----------------------
179  //------------------------------------------------------------------------
180  double temp_center2[3];
181  temp_center2[0] = ( bounds[0] + bounds[1] ) * 0.5;
182  temp_center2[1] = ( bounds[2] + bounds[3] ) * 0.5;
183  temp_center2[2] = ( bounds[4] + bounds[5] ) * 0.5;
184 
185  vtkSmartPointer< vtkTransform > translation23 =
186  vtkSmartPointer< vtkTransform >::New();
187 
188  translation23->Translate(temp_center2[0],
189  temp_center2[1],
190  temp_center2[2]);
191 
192  vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform23 =
193  vtkSmartPointer< vtkTransformPolyDataFilter >::New();
194  mesh_transform23->SetTransform(translation23);
195  mesh_transform23->SetInput( mesh_transform->GetOutput() );
196  mesh_transform23->Update();
197 
198  //-----------------------------------------------------------------------
199 
200  // MIGHT LEAK! CHECK IT IS DELETED!
201  vtkPolyData* mesh = vtkPolyData::New();
202  mesh->DeepCopy( mesh_transform23->GetOutput() );
203 
204  temp_output->Delete();
205 
206  return mesh;
207  }
208 };
209 
210 #endif
Levelset segmentation algorithm implementation. Can generate contours and meshes. Will generate 2D ob...
Output2DType::Pointer Output2DPointer
class to be the interface between the levelset algo for contours and GoFigure
QGoContourLevelSetAlgo(std::vector< vtkPoints * > *iSeeds, QWidget *iParent=0)
void Apply2DFilter(typename itk::Image< TPixel, 2 >::Pointer iITKInput, const std::vector< double > &iCenter, const double &iRadius, const int &iIterations, const int &iCurvature)
std::vector< vtkPolyData * > ExtractPolyData(std::vector< vtkImageData * > &iInputImage, const double &iThreshold)
vtkPolyData * ApplyLevelSetFilter(const std::vector< double > &iCenter, typename itk::Image< TPixel, 3 >::Pointer iImages, const unsigned int &iOrientation)
QGoAlgoParameter< double > * m_Radius
QGoAlgoParameter< int > * m_Iterations
std::vector< vtkPolyData * > ApplyAlgo(GoImageProcessor *iImages, std::string iChannel, bool iIsInvertedOn=false)
return the vtkpolydata created by the algorithm
class to be the interface between the levelset algo for meshes, contours and set of contours and GoFi...
QGoAlgoParameter< int > * m_Curvature
Interface between image reader and vtkImageData.
vtkImageData * ConvertITK2VTK(typename itk::Image< PixelType, VImageDimension >::Pointer iInput)