Fraxinus  16.5.0-fx-rc3
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 #include "cxUtilHelpers.h"
55 // Test
56 #include "FAST/Algorithms/AirwaySegmentation/AirwaySegmentation.hpp"
57 #include "FAST/Algorithms/CenterlineExtraction/CenterlineExtraction.hpp"
58 #include "FAST/Importers/ImageFileImporter.hpp"
59 #include "FAST/Exporters/VTKImageExporter.hpp"
60 #include "FAST/Exporters/VTKLineSetExporter.hpp"
61 #include "FAST/Data/Segmentation.hpp"
62 #include "FAST/SceneGraph.hpp"
63 
64 namespace cx {
65 
67  FilterImpl(services)
68 {
69 
70 }
71 
72 QString AirwaysFilter::getName() const
73 {
74  return "Airway Segmentation Filter";
75 }
76 
77 QString AirwaysFilter::getType() const
78 {
79  return "AirwaysFilter";
80 }
81 
82 QString AirwaysFilter::getHelp() const
83 {
84  return "<html>"
85  "<h3>Airway Segmentation.</h3>"
86  "<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>"
87  "</html>";
88 }
89 
91 {
92  CX_LOG_INFO() << "EXECUTING AIRWAYS FILTER";
93  ImagePtr input = this->getCopiedInputImage();
94  if (!input)
95  return false;
96  mInputImage = input;
97  std::string filename = (patientService()->getActivePatientFolder()+"/"+mInputImage->getFilename()).toStdString();
98 
99  try {
100  // Import image data from disk
101  fast::ImageFileImporter::pointer importer = fast::ImageFileImporter::New();
102  importer->setFilename(filename);
103 
104  // Need to know the data type
105  importer->update();
106  fast::Image::pointer image = importer->getOutputData<fast::Image>();
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  CX_LOG_SUCCESS() << "FINISHED AIRWAY SEGMENTATION";
118 
119  //HACK: there is some kind of race condition where data is not ready to be accessed, thus we need to wait a bit
120  //This only happens on mac release build (disapears if cout's are added for example.)
121  sleep_ms(500);
122 
123  // Get output segmentation data
124  fast::Segmentation::pointer segmentationData = segmentation->getOutputData<fast::Segmentation>(0);
125 
126  // Get the transformation of the segmentation
127  Eigen::Affine3f T = fast::SceneGraph::getEigenAffineTransformationFromData(segmentationData);
128  mTransformation.matrix() = T.matrix().cast<double>(); // cast to double
129 
130  // Extract centerline
131  fast::CenterlineExtraction::pointer centerline = fast::CenterlineExtraction::New();
132  centerline->setInputConnection(segmentation->getOutputPort());
133 
134  // Get centerline
135  vtkSmartPointer<fast::VTKLineSetExporter> vtkCenterlineExporter = fast::VTKLineSetExporter::New();
136  vtkCenterlineExporter->setInputConnection(centerline->getOutputPort());
137  mCenterlineOutput = vtkCenterlineExporter->GetOutput();
138  vtkCenterlineExporter->Update();
139 
140  } catch(fast::Exception& e) {
141  std::string error = e.what();
142  reportError("fast::Exception: "+qstring_cast(error));
143 
144  return false;
145  } catch(cl::Error& e) {
146  reportError("cl::Error:"+qstring_cast(e.what()));
147 
148  return false;
149  } catch (std::exception& e){
150  reportError("std::exception:"+qstring_cast(e.what()));
151 
152  return false;
153  } catch (...){
154  reportError("Airway segmentation algorithm threw a unknown exception.");
155 
156  return false;
157  }
158  return true;
159 }
160 
162 {
163  if(!mSegmentationOutput)
164  return false;
165 
166  std::cout << "POST PROCESS" << std::endl;
167 
168  // Make contour of segmented volume
169  double threshold = 1;
171  mSegmentationOutput,
172  threshold,
173  false, // reduce resolution
174  true, // smoothing
175  true, // keep topology
176  0 // target decimation
177  );
178  //outputSegmentation->get_rMd_History()->setRegistration(rMd_i);
179  //patientService()->insertData(outputSegmentation);
180 
181  // Add contour internally to cx
183  patientService(),
184  rawContour,
185  mInputImage,
186  QColor("green")
187  );
188  contour->get_rMd_History()->setRegistration(mTransformation);
189 
190  // Set output
191  mOutputTypes[1]->setValue(contour->getUid());
192 
193  // TODO get centerline somehow
194  QString uid = mInputImage->getUid() + "_centerline%1";
195  QString name = mInputImage->getName() + " centerline%1";
196  MeshPtr centerline = patientService()->createSpecificData<Mesh>(uid, name);
197  centerline->setVtkPolyData(mCenterlineOutput);
198  centerline->get_rMd_History()->setParentSpace(mInputImage->getUid());
199  centerline->get_rMd_History()->setRegistration(mTransformation);
200  patientService()->insertData(centerline);
201  mOutputTypes[0]->setValue(centerline->getUid());
202 
203  return true;
204 }
205 
207 {
208  //mOptionsAdapters.push_back(getNoiseLevelOption(mOptions));
209 }
210 
212 {
214 
216  temp->setValueName("Input");
217  temp->setHelp("Select input to run airway segmentation on.");
218  mInputTypes.push_back(temp);
219 }
220 
222 {
223  StringPropertySelectMeshPtr tempMeshStringAdapter;
224 
225  //0
226  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
227  tempMeshStringAdapter->setValueName("Centerline");
228  tempMeshStringAdapter->setHelp("Generated centerline mesh (vtk-format).");
229  mOutputTypes.push_back(tempMeshStringAdapter);
230 
231  //1
232  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
233  tempMeshStringAdapter->setValueName("Segmentation");
234  tempMeshStringAdapter->setHelp("Generated surface of the segmented volume.");
235  mOutputTypes.push_back(tempMeshStringAdapter);
236 
237 }
238 
239 /*
240 DoublePropertyPtr AirwaysFilter::getNoiseLevelOption(QDomElement root)
241 {
242  DoublePropertyPtr retval = DoubleProperty::initialize("Noise level",
243  "", "Select the amount of noise present in the image", 0.5,
244  DoubleRange(0.0, 2, 0.5), 1, root);
245  retval->setGuiRepresentation(DoubleProperty::grSLIDER);
246  return retval;
247 }
248 */
249 
251 }
252 
253 } /* namespace cx */
254 
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
#define CX_LOG_INFO
Definition: cxLogger.h:111
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)
#define CX_LOG_SUCCESS
Definition: cxLogger.h:112
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
void sleep_ms(int ms)
boost::shared_ptr< class StringPropertySelectMesh > StringPropertySelectMeshPtr
virtual QString getName() const
virtual QString getHelp() const