Fraxinus  16.5.0-fx-rc1
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxAirwaysFilterService.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. 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 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxAirwaysFilterService.h"
34 
35 #include <QTimer>
36 
37 #include <vtkImageImport.h>
38 #include <vtkImageData.h>
39 #include <vtkImageShiftScale.h>
40 #include <ctkPluginContext.h>
41 
42 #include "cxTime.h"
43 #include "cxTypeConversions.h"
44 #include "cxLogger.h"
45 #include "cxDataReaderWriter.h"
47 #include "cxDoubleProperty.h"
48 #include "cxContourFilter.h"
49 #include "cxDataLocations.h"
51 #include "vtkForwardDeclarations.h"
53 #include "cxVisServices.h"
54 // Test
55 #include "FAST/Algorithms/AirwaySegmentation/AirwaySegmentation.hpp"
56 #include "FAST/Algorithms/CenterlineExtraction/CenterlineExtraction.hpp"
57 #include "FAST/Importers/ImageFileImporter.hpp"
58 #include "FAST/Exporters/VTKImageExporter.hpp"
59 #include "FAST/Exporters/VTKLineSetExporter.hpp"
60 #include "FAST/Data/Segmentation.hpp"
61 #include "FAST/SceneGraph.hpp"
62 
63 namespace cx {
64 
66  FilterImpl(services)
67 {
68 
69 }
70 
71 QString AirwaysFilter::getName() const
72 {
73  return "Airway Segmentation Filter";
74 }
75 
76 QString AirwaysFilter::getType() const
77 {
78  return "AirwaysFilter";
79 }
80 
81 QString AirwaysFilter::getHelp() const
82 {
83  return "<html>"
84  "<h3>Airway Segmentation.</h3>"
85  "<p><i>Extracts segmentation and centerline from a CT volume. If method fails, try to crop volume. </br>Algorithm written by Erik Smistad.</i></p>"
86  "</html>";
87 }
88 
90 {
91  std::cout << "EXECUTING AIRWAYS FILTER" << std::endl;
92  ImagePtr input = this->getCopiedInputImage();
93  if (!input)
94  return false;
95  mInputImage = input;
96  std::string filename = (patientService()->getActivePatientFolder()+"/"+mInputImage->getFilename()).toStdString();
97 
98  try {
99  // Import image data from disk
100  fast::ImageFileImporter::pointer importer = fast::ImageFileImporter::New();
101  importer->setFilename(filename);
102 
103  // Need to know the data type
104  importer->update();
105  fast::Image::pointer image = importer->getOutputData<fast::Image>();
106  std::cout << "IMAGE LOADED" << std::endl;
107 
108  // Do segmentation
109  fast::AirwaySegmentation::pointer segmentation = fast::AirwaySegmentation::New();
110  segmentation->setInputConnection(importer->getOutputPort());
111 
112  // Convert fast segmentation data to VTK data which CX can use
113  vtkSmartPointer<fast::VTKImageExporter> vtkExporter = fast::VTKImageExporter::New();
114  vtkExporter->setInputConnection(segmentation->getOutputPort());
115  vtkExporter->Update();
116  mSegmentationOutput = vtkExporter->GetOutput();
117  std::cout << "FINISHED AIRWAY SEGMENTATION" << std::endl;
118 
119  // Get output segmentation data
120  fast::Segmentation::pointer segmentationData = segmentation->getOutputData<fast::Segmentation>(0);
121 
122  // Get the transformation of the segmentation
123  Eigen::Affine3f T = fast::SceneGraph::getEigenAffineTransformationFromData(segmentationData);
124  mTransformation.matrix() = T.matrix().cast<double>(); // cast to double
125 
126  // Extract centerline
127  fast::CenterlineExtraction::pointer centerline = fast::CenterlineExtraction::New();
128  centerline->setInputConnection(segmentation->getOutputPort());
129 
130  // Get centerline
131  vtkSmartPointer<fast::VTKLineSetExporter> vtkCenterlineExporter = fast::VTKLineSetExporter::New();
132  vtkCenterlineExporter->setInputConnection(centerline->getOutputPort());
133  mCenterlineOutput = vtkCenterlineExporter->GetOutput();
134  vtkCenterlineExporter->Update();
135 
136  } catch(fast::Exception& e) {
137  std::string error = e.what();
138  reportError("fast::Exception: "+qstring_cast(error));
139 
140  return false;
141  } catch(cl::Error& e) {
142  reportError("cl::Error:"+qstring_cast(e.what()));
143 
144  return false;
145  } catch (std::exception& e){
146  reportError("std::exception:"+qstring_cast(e.what()));
147 
148  return false;
149  } catch (...){
150  reportError("Airway segmentation algorithm threw a unknown exception.");
151 
152  return false;
153  }
154  return true;
155 }
156 
158 {
159  if(!mSegmentationOutput)
160  return false;
161 
162  std::cout << "POST PROCESS" << std::endl;
163 
164  // Make contour of segmented volume
165  double threshold = 1;
167  mSegmentationOutput,
168  threshold,
169  false, // reduce resolution
170  true, // smoothing
171  true, // keep topology
172  0 // target decimation
173  );
174  //outputSegmentation->get_rMd_History()->setRegistration(rMd_i);
175  //patientService()->insertData(outputSegmentation);
176 
177  // Add contour internally to cx
179  patientService(),
180  rawContour,
181  mInputImage,
182  QColor("green")
183  );
184  contour->get_rMd_History()->setRegistration(mTransformation);
185 
186  // Set output
187  mOutputTypes[1]->setValue(contour->getUid());
188 
189  // TODO get centerline somehow
190  QString uid = mInputImage->getUid() + "_centerline%1";
191  QString name = mInputImage->getName() + " centerline%1";
192  MeshPtr centerline = patientService()->createSpecificData<Mesh>(uid, name);
193  centerline->setVtkPolyData(mCenterlineOutput);
194  centerline->get_rMd_History()->setParentSpace(mInputImage->getUid());
195  centerline->get_rMd_History()->setRegistration(mTransformation);
196  patientService()->insertData(centerline);
197  mOutputTypes[0]->setValue(centerline->getUid());
198 
199  return true;
200 }
201 
203 {
204  //mOptionsAdapters.push_back(getNoiseLevelOption(mOptions));
205 }
206 
208 {
210 
212  temp->setValueName("Input");
213  temp->setHelp("Select input to run airway segmentation on.");
214  mInputTypes.push_back(temp);
215 }
216 
218 {
219  StringPropertySelectMeshPtr tempMeshStringAdapter;
220 
221  //0
222  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
223  tempMeshStringAdapter->setValueName("Centerline");
224  tempMeshStringAdapter->setHelp("Generated centerline mesh (vtk-format).");
225  mOutputTypes.push_back(tempMeshStringAdapter);
226 
227  //1
228  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
229  tempMeshStringAdapter->setValueName("Segmentation");
230  tempMeshStringAdapter->setHelp("Generated surface of the segmented volume.");
231  mOutputTypes.push_back(tempMeshStringAdapter);
232 
233 }
234 
235 /*
236 DoublePropertyPtr AirwaysFilter::getNoiseLevelOption(QDomElement root)
237 {
238  DoublePropertyPtr retval = DoubleProperty::initialize("Noise level",
239  "", "Select the amount of noise present in the image", 0.5,
240  DoubleRange(0.0, 2, 0.5), 1, root);
241  retval->setGuiRepresentation(DoubleProperty::grSLIDER);
242  return retval;
243 }
244 */
245 
247 }
248 
249 } /* namespace cx */
250 
QString qstring_cast(const T &val)
std::vector< SelectDataStringPropertyBasePtr > mInputTypes
Definition: cxFilterImpl.h:94
void reportError(QString msg)
Definition: cxLogger.cpp:92
A mesh data set.
Definition: cxMesh.h:61
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:62
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
virtual void createOutputTypes()
AirwaysFilter(VisServicesPtr services)
vtkSmartPointer< class vtkPolyData > vtkPolyDataPtr
boost::shared_ptr< class SelectDataStringPropertyBase > SelectDataStringPropertyBasePtr
PatientModelServicePtr patientService()
virtual bool execute()
void setVtkPolyData(const vtkPolyDataPtr &polyData)
Definition: cxMesh.cpp:100
ImagePtr getCopiedInputImage(int index=0)
virtual QString getType() const
std::vector< SelectDataStringPropertyBasePtr > mOutputTypes
Definition: cxFilterImpl.h:95
static StringPropertySelectMeshPtr New(PatientModelServicePtr patientModelService)
virtual bool postProcess()
static StringPropertySelectImagePtr New(PatientModelServicePtr patientModelService)
boost::shared_ptr< class Mesh > MeshPtr
boost::shared_ptr< class StringPropertySelectMesh > StringPropertySelectMeshPtr
virtual QString getName() const
virtual QString getHelp() const