CustusX  16.5
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 
65 AirwaysFilter::AirwaysFilter(ctkPluginContext *pluginContext) :
66  FilterImpl(VisServices::create(pluginContext))
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 
89 
91 {
92  std::cout << "EXECUTING AIRWAYS FILTER" << std::endl;
93  ImagePtr input = this->getCopiedInputImage();
94  if (!input)
95  return false;
96  mInputImage = input;
97 
98  std::string filename = (patientService()->getActivePatientFolder()+"/"+input->getFilename()).toStdString();
99 
100  try {
101  // Import image data from disk
102  fast::ImageFileImporter::pointer importer = fast::ImageFileImporter::New();
103  importer->setFilename(filename);
104 
105  // Need to know the data type
106  importer->update();
107  fast::Image::pointer image = importer->getOutputData<fast::Image>();
108  std::cout << "IMAGE LOADED" << std::endl;
109 
110  // Do segmentation
111  fast::AirwaySegmentation::pointer segmentation = fast::AirwaySegmentation::New();
112  segmentation->setInputConnection(importer->getOutputPort());
113 
114  // Convert fast segmentation data to VTK data which CX can use
115  vtkSmartPointer<fast::VTKImageExporter> vtkExporter = fast::VTKImageExporter::New();
116  vtkExporter->setInputConnection(segmentation->getOutputPort());
117  vtkExporter->Update();
118  mSegmentationOutput = vtkExporter->GetOutput();
119  std::cout << "FINISHED AIRWAY SEGMENTATION" << std::endl;
120 
121  // Get output segmentation data
122  fast::Segmentation::pointer segmentationData = segmentation->getOutputData<fast::Segmentation>(0);
123 
124  // Get the transformation of the segmentation
125  Eigen::Affine3f T = fast::SceneGraph::getEigenAffineTransformationFromData(segmentationData);
126  mTransformation.matrix() = T.matrix().cast<double>(); // cast to double
127 
128  // Extract centerline
129  fast::CenterlineExtraction::pointer centerline = fast::CenterlineExtraction::New();
130  centerline->setInputConnection(segmentation->getOutputPort());
131 
132  // Get centerline
133  vtkSmartPointer<fast::VTKLineSetExporter> vtkCenterlineExporter = fast::VTKLineSetExporter::New();
134  vtkCenterlineExporter->setInputConnection(centerline->getOutputPort());
135  mCenterlineOutput = vtkCenterlineExporter->GetOutput();
136  vtkCenterlineExporter->Update();
137 
138  } catch(fast::Exception& e) {
139  std::string error = e.what();
140  reportError("fast::Exception: "+qstring_cast(error));
141 
142  return false;
143  } catch(cl::Error& e) {
144  reportError("cl::Error:"+qstring_cast(e.what()));
145 
146  return false;
147  } catch (std::exception& e){
148  reportError("std::exception:"+qstring_cast(e.what()));
149 
150  return false;
151  } catch (...){
152  reportError("Airway segmentation algorithm threw a unknown exception.");
153 
154  return false;
155  }
156  return true;
157 }
158 
160 {
161  if(!mSegmentationOutput)
162  return false;
163 
164  std::cout << "POST PROCESS" << std::endl;
165 
166  // Make contour of segmented volume
167  double threshold = 1;
169  mSegmentationOutput,
170  threshold,
171  false, // reduce resolution
172  true, // smoothing
173  true, // keep topology
174  0 // target decimation
175  );
176  //outputSegmentation->get_rMd_History()->setRegistration(rMd_i);
177  //patientService()->insertData(outputSegmentation);
178 
179  // Add contour internally to cx
181  patientService(),
182  rawContour,
183  mInputImage,
184  QColor("green")
185  );
186  contour->get_rMd_History()->setRegistration(mTransformation);
187 
188  // Set output
189  mOutputTypes[1]->setValue(contour->getUid());
190 
191  // TODO get centerline somehow
192  QString uid = mInputImage->getUid() + "_centerline%1";
193  QString name = mInputImage->getName() + " centerline%1";
194  MeshPtr centerline = patientService()->createSpecificData<Mesh>(uid, name);
195  centerline->setVtkPolyData(mCenterlineOutput);
196  centerline->get_rMd_History()->setParentSpace(mInputImage->getUid());
197  centerline->get_rMd_History()->setRegistration(mTransformation);
198  patientService()->insertData(centerline);
199  mOutputTypes[0]->setValue(centerline->getUid());
200 
201  return true;
202 }
203 
205 {
206  //mOptionsAdapters.push_back(getNoiseLevelOption(mOptions));
207 }
208 
210 {
212 
214  temp->setValueName("Input");
215  temp->setHelp("Select input to run airway segmentation on.");
216  mInputTypes.push_back(temp);
217 }
218 
220 {
221  StringPropertySelectMeshPtr tempMeshStringAdapter;
222 
223  //0
224  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
225  tempMeshStringAdapter->setValueName("Centerline");
226  tempMeshStringAdapter->setHelp("Generated centerline mesh (vtk-format).");
227  mOutputTypes.push_back(tempMeshStringAdapter);
228 
229  //1
230  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
231  tempMeshStringAdapter->setValueName("Segmentation");
232  tempMeshStringAdapter->setHelp("Generated surface of the segmented volume.");
233  mOutputTypes.push_back(tempMeshStringAdapter);
234 
235 }
236 
237 /*
238 DoublePropertyPtr AirwaysFilter::getNoiseLevelOption(QDomElement root)
239 {
240  DoublePropertyPtr retval = DoubleProperty::initialize("Noise level",
241  "", "Select the amount of noise present in the image", 0.5,
242  DoubleRange(0.0, 2, 0.5), 1, root);
243  retval->setGuiRepresentation(DoubleProperty::grSLIDER);
244  return retval;
245 }
246 */
247 
249 }
250 
251 } /* namespace cx */
252 
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 Image > ImagePtr
Definition: cxDicomWidget.h:48
virtual void createOutputTypes()
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
AirwaysFilter(ctkPluginContext *pluginContext)
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