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