GOFIGURE2  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
QGoSetOfContoursWaterShedAlgo.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 __QGoSetOfContoursWaterShedAlgo_h
35 #define __QGoSetOfContoursWaterShedAlgo_h
36 
37 // external files
38 #include "vtkSmartPointer.h"
39 #include "vtkPolyData.h"
40 #include "vtkImageData.h"
41 #include "vtkTransform.h"
42 #include "vtkTransformPolyDataFilter.h"
43 
44 // project files
45 #include "QGoWaterShedAlgo.h"
46 #include "QGoAlgorithmWidget.h"
47 #include "QGoAlgoParameter.h"
48 #include "QGoGUILibConfigure.h"
49 #include "QGoFilterWatershed.h"
50 
51 // temp for debug purpose
52 #include "vtkPolyDataMapper.h"
53 #include "vtkActor.h"
54 #include "vtkRenderer.h"
55 #include "vtkRenderWindow.h"
56 #include "vtkRenderWindowInteractor.h"
57 #include "itkImageFileWriter.h"
58 
59 
60 #include "vtkPointData.h"
61 
62 class GoImageProcessor;
63 
64 
71 {
72 public:
73  QGoSetOfContoursWaterShedAlgo(std::vector< vtkPoints* >* iSeeds,
74  int iMaxThreshold,
75  QWidget* iParent = 0);
77 
78  // should not be virutal pure since we dont implement it....
79  std::vector<vtkPolyData*> ApplyAlgo(
80  GoImageProcessor* iImages,
81  std::string iChannel,
82  bool iIsInvertedOn = false);
83 
84  std::vector<std::vector<vtkPolyData*> > ApplyAlgoSeveralSeeds(
85  GoImageProcessor* iImages, std::string iChannel);
86 
87 protected:
88 
90 
91  template < class TPixel >
92  // note this will work only in 3D, so we can remove the template
93  // parameter on the image dimension
94  //unsigned int VImageDimension >
95  std::vector<vtkPolyData *> ApplyWaterShedFilter(
96  const std::vector<double>& iCenter,
97  typename itk::Image< TPixel, 3 >::Pointer iImages,
98  const unsigned int& iOrientation)
99  {
100  assert( iCenter.size() == 3);
101 
102  const unsigned int ImageDimension = 3;
103 
104  typedef TPixel PixelType;
105  typedef itk::Image< PixelType, ImageDimension > ImageType;
106  typedef typename ImageType::Pointer ImagePointer;
107  typedef itk::Image< PixelType, 2 > ImageType2D;
108  typedef typename ImageType2D::Pointer ImageType2DPointer;
109  typedef typename ImageType::SpacingType ImageSpacingType;
110 
111  std::vector<vtkPolyData*> output;
112 
113  ImageSpacingType spacing = iImages->GetSpacing();
114 
115  for(int i= 0; i<this->m_Sampling->GetValue(); ++i)
116  {
117  // let's compute the bounds of the region of interest
118  double radius = this->m_Radius->GetValue();
119 
120  std::vector< double > bounds( 2 * ImageDimension, 0. );
121  unsigned int k = 0;
122  for( unsigned int dim = 0; dim < ImageDimension; dim++ )
123  {
124  bounds[k++] = iCenter[dim] - 2. * radius;
125  bounds[k++] = iCenter[dim] + 2. * radius;
126  }
127 
128  int pair = i+ i%2 -1;
129  if(pair < 0)
130  {
131  pair = 0;
132  }
133 
134  bounds[2*iOrientation] =
135  iCenter[iOrientation] + (pair*(pow(-1., static_cast<int>(i) ) )*spacing[iOrientation]);
136  bounds[2*iOrientation +1] =
137  iCenter[iOrientation] + (pair*(pow(-1., static_cast<int>(i) ) )*spacing[iOrientation]);
138 
139  // then let's extract the Slice of Interest
140  ImageType2DPointer ITK_Slice_Image =
141  this->ITKExtractSlice<PixelType>( bounds, iImages );
142 
143  // Compute the segmentation in 3D
144  QGoFilterWatershed Filter;
145  Filter.Apply2DFilter< PixelType >(
146  ITK_Slice_Image,
147  this->m_ThresMin->GetValue(),
148  this->m_ThresMax->GetValue(),
149  this->m_CorrThres->GetValue(),
150  this->m_Alpha->GetValue(),
151  this->m_Beta->GetValue());
152 
154  ItkOutPut = Filter.GetOutput2D();
155 
156  // Here it would be better if the mesh extraction would be performed directly
157  // in ITK instead.
158  vtkImageData * FilterOutPutToVTK =
159  this->ConvertITK2VTK<
161  2>( ItkOutPut );
162 
163  // Nicolas- should be able to tune the parameter -0.5-
164  vtkPolyData* temp_output = this->ExtractPolyData(FilterOutPutToVTK, 0.5);
165 
166  // translation transform -----------------------
167  //------------------------------------------------------------------------
168  double temp_bounds[6];
169  FilterOutPutToVTK->GetBounds( temp_bounds );
170 
171  double temp_center[3];
172  temp_center[0] = ( temp_bounds[0] + temp_bounds[1] ) * 0.5;
173  temp_center[1] = ( temp_bounds[2] + temp_bounds[3] ) * 0.5;
174  temp_center[2] = ( temp_bounds[4] + temp_bounds[5] ) * 0.5;
175 
176  vtkSmartPointer< vtkTransform > translation2 =
177  vtkSmartPointer< vtkTransform >::New();
178 
179  translation2->Translate(-temp_center[0],
180  -temp_center[1],
181  -temp_center[2]);
182 
183  vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform2 =
184  vtkSmartPointer< vtkTransformPolyDataFilter >::New();
185  mesh_transform2->SetTransform(translation2);
186  mesh_transform2->SetInput( temp_output );
187  mesh_transform2->Update();
188 
189  // rotation transform -----------------------
190  //------------------------------------------------------------------------
191  vtkSmartPointer< vtkTransform > translation =
192  vtkSmartPointer< vtkTransform >::New();
193  // rotate polydata if necessary
194  if(iOrientation == 0)
195  {
196  translation->RotateY(-90); // check if + or - 90
197  }
198  else if(iOrientation == 1)
199  {
200  translation->RotateX(-90); // check if + or - 90
201  }
202  else if(iOrientation == 2)
203  {
204  // no rotation, we are in the good plan
205  }
206 
207  vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform =
208  vtkSmartPointer< vtkTransformPolyDataFilter >::New();
209  mesh_transform->SetTransform(translation);
210  mesh_transform->SetInput( mesh_transform2->GetOutput() );
211  mesh_transform->Update();
212 
213  // translate back -----------------------
214  //------------------------------------------------------------------------
215  double temp_center2[3];
216  temp_center2[0] = ( bounds[0] + bounds[1] ) * 0.5;
217  temp_center2[1] = ( bounds[2] + bounds[3] ) * 0.5;
218  temp_center2[2] = ( bounds[4] + bounds[5] ) * 0.5;
219 
220  vtkSmartPointer< vtkTransform > translation23 =
221  vtkSmartPointer< vtkTransform >::New();
222 
223  translation23->Translate(temp_center2[0],
224  temp_center2[1],
225  temp_center2[2]);
226 
227  vtkSmartPointer< vtkTransformPolyDataFilter > mesh_transform23 =
228  vtkSmartPointer< vtkTransformPolyDataFilter >::New();
229  mesh_transform23->SetTransform(translation23);
230  mesh_transform23->SetInput( mesh_transform->GetOutput() );
231  mesh_transform23->Update();
232 
233  //-----------------------------------------------------------------------
234 
235  temp_output->Delete();
236 
237  vtkPolyData* testt = vtkPolyData::New();
238  testt->DeepCopy(mesh_transform23->GetOutput());
239 
240  output.push_back(testt);
241  }
242 
243  return output;
244  }
245 };
246 
247 #endif
QGoAlgoParameter< double > * m_Beta
QGoSetOfContoursWaterShedAlgo(std::vector< vtkPoints * > *iSeeds, int iMaxThreshold, QWidget *iParent=0)
QGoAlgoParameter< int > * m_ThresMin
QGoAlgoParameter< int > * m_ThresMax
std::vector< std::vector< vtkPolyData * > > ApplyAlgoSeveralSeeds(GoImageProcessor *iImages, std::string iChannel)
std::vector< vtkPolyData * > ExtractPolyData(std::vector< vtkImageData * > &iInputImage, const double &iThreshold)
QGoAlgoParameter< double > * m_CorrThres
QGoAlgoParameter< double > * m_Radius
std::vector< vtkPolyData * > ApplyWaterShedFilter(const std::vector< double > &iCenter, typename itk::Image< TPixel, 3 >::Pointer iImages, const unsigned int &iOrientation)
class to be the interface between the watershed algo for set of contours and GoFigure ...
void Apply2DFilter(typename itk::Image< TPixel, 2 >::Pointer iITKInput, const int &iThresMin, const int &iThresMax, const double &iCorrTresh, const double &iAlpha, const double &iBeta)
std::vector< vtkPolyData * > ApplyAlgo(GoImageProcessor *iImages, std::string iChannel, bool iIsInvertedOn=false)
return the vtkpolydata created by the algorithm
QGoAlgoParameter< double > * m_Alpha
Output2DType::Pointer Output2DPointer
Watershed segmentation algorithm implementation. Can generate contours and meshes. Will generate 2D objects if m_Dimension&lt;2, 3D objects in the other case.
Interface between image reader and vtkImageData.
vtkImageData * ConvertITK2VTK(typename itk::Image< PixelType, VImageDimension >::Pointer iInput)
class to be the interface between the watershed algo for meshes and GoFigure