Fraxinus  16.5.0-fx-rc9
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  //Need to create OpenGL context of fast in main thread, this is done in the constructor of DeviceManger
70  fast::ImageFileImporter::pointer importer = fast::ImageFileImporter::New();
71  Q_UNUSED(importer)
72 }
73 
74 
76 }
77 
78 QString AirwaysFilter::getName() const
79 {
80  return "Airway Segmentation Filter";
81 }
82 
83 QString AirwaysFilter::getType() const
84 {
85  return "AirwaysFilter";
86 }
87 
88 QString AirwaysFilter::getHelp() const
89 {
90  return "<html>"
91  "<h3>Airway Segmentation.</h3>"
92  "<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>"
93  "</html>";
94 }
95 
97 {
98  CX_LOG_INFO() << "EXECUTING AIRWAYS FILTER";
99  ImagePtr input = this->getCopiedInputImage();
100  if (!input)
101  return false;
102  mInputImage = input;
103 
104  QString q_filename = "";
105  QString activePatienFolder = patientService()->getActivePatientFolder();
106  QString inputImageFileName = mInputImage->getFilename();
107  if(!activePatienFolder.isEmpty())
108  q_filename = activePatienFolder+"/"+inputImageFileName;
109  else
110  q_filename = inputImageFileName;
111 
112  std::string filename = q_filename.toStdString();
113  try {
114  QString kernelDir = cx::DataLocations::findConfigFolder("/FAST", FAST_SOURCE_DIR);
115  fast::DeviceManager::getInstance().setKernelRootPath(kernelDir.toStdString());
116  QString cacheDir = cx::DataLocations::getCachePath();
117  fast::DeviceManager::getInstance().setWritableCachePath(cacheDir.toStdString());
118 
119  // Import image data from disk
120  fast::ImageFileImporter::pointer importer = fast::ImageFileImporter::New();
121  importer->setFilename(filename);
122 
123  // Need to know the data type
124  importer->update();
125  fast::Image::pointer image = importer->getOutputData<fast::Image>();
126 
127  // Do segmentation
128  fast::AirwaySegmentation::pointer segmentation = fast::AirwaySegmentation::New();
129  segmentation->setInputConnection(importer->getOutputPort());
130 
131  // Convert fast segmentation data to VTK data which CX can use
132  vtkSmartPointer<fast::VTKImageExporter> vtkExporter = fast::VTKImageExporter::New();
133  vtkExporter->setInputConnection(segmentation->getOutputPort());
134  vtkExporter->Update();
135  mSegmentationOutput = vtkExporter->GetOutput();
136  CX_LOG_SUCCESS() << "FINISHED AIRWAY SEGMENTATION";
137 
138  // Get output segmentation data
139  fast::Segmentation::pointer segmentationData = segmentation->getOutputData<fast::Segmentation>(0);
140 
141  // Get the transformation of the segmentation
142  Eigen::Affine3f T = fast::SceneGraph::getEigenAffineTransformationFromData(segmentationData);
143  mTransformation.matrix() = T.matrix().cast<double>(); // cast to double
144 
145  // Extract centerline
146  fast::CenterlineExtraction::pointer centerline = fast::CenterlineExtraction::New();
147  centerline->setInputConnection(segmentation->getOutputPort());
148 
149  // Get centerline
150  vtkSmartPointer<fast::VTKLineSetExporter> vtkCenterlineExporter = fast::VTKLineSetExporter::New();
151  vtkCenterlineExporter->setInputConnection(centerline->getOutputPort());
152  mCenterlineOutput = vtkCenterlineExporter->GetOutput();
153  vtkCenterlineExporter->Update();
154 
155  } catch(fast::Exception& e) {
156  std::string error = e.what();
157  reportError("fast::Exception: "+qstring_cast(error));
158 
159  return false;
160  } catch(cl::Error& e) {
161  reportError("cl::Error:"+qstring_cast(e.what()));
162 
163  return false;
164  } catch (std::exception& e){
165  reportError("std::exception:"+qstring_cast(e.what()));
166 
167  return false;
168  } catch (...){
169  reportError("Airway segmentation algorithm threw a unknown exception.");
170 
171  return false;
172  }
173  return true;
174 }
175 
177 {
178  if(!mSegmentationOutput)
179  return false;
180 
181  std::cout << "POST PROCESS" << std::endl;
182 
183  // Make contour of segmented volume
184  double threshold = 1;
186  mSegmentationOutput,
187  threshold,
188  false, // reduce resolution
189  true, // smoothing
190  true, // keep topology
191  0 // target decimation
192  );
193  //outputSegmentation->get_rMd_History()->setRegistration(rMd_i);
194  //patientService()->insertData(outputSegmentation);
195 
196  // Add contour internally to cx
198  patientService(),
199  rawContour,
200  mInputImage,
201  QColor("green")
202  );
203  contour->get_rMd_History()->setRegistration(mTransformation);
204 
205  // Set output
206  mOutputTypes[1]->setValue(contour->getUid());
207 
208  // TODO get centerline somehow
209  QString uid = mInputImage->getUid() + "_centerline%1";
210  QString name = mInputImage->getName() + " centerline%1";
211  MeshPtr centerline = patientService()->createSpecificData<Mesh>(uid, name);
212  centerline->setVtkPolyData(mCenterlineOutput);
213  centerline->get_rMd_History()->setParentSpace(mInputImage->getUid());
214  centerline->get_rMd_History()->setRegistration(mTransformation);
215  patientService()->insertData(centerline);
216  mOutputTypes[0]->setValue(centerline->getUid());
217 
218  return true;
219 }
220 
222 {
223 }
224 
226 {
228 
230  temp->setValueName("Input");
231  temp->setHelp("Select input to run airway segmentation on.");
232  mInputTypes.push_back(temp);
233 }
234 
236 {
237  StringPropertySelectMeshPtr tempMeshStringAdapter;
238 
239  //0
240  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
241  tempMeshStringAdapter->setValueName("Centerline");
242  tempMeshStringAdapter->setHelp("Generated centerline mesh (vtk-format).");
243  mOutputTypes.push_back(tempMeshStringAdapter);
244 
245  //1
246  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
247  tempMeshStringAdapter->setValueName("Segmentation");
248  tempMeshStringAdapter->setHelp("Generated surface of the segmented volume.");
249  mOutputTypes.push_back(tempMeshStringAdapter);
250 
251 }
252 
253 
254 } /* namespace cx */
255 
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()
static QString getCachePath()
return path to a folder that is used during execution, will be cleared at start and stop...
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