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