16 #include <vtkImageImport.h> 17 #include <vtkImageData.h> 18 #include <vtkImageShiftScale.h> 19 #include <ctkPluginContext.h> 20 #include <vtkImplicitModeller.h> 21 #include <vtkContourFilter.h> 39 #include "FAST/Algorithms/LungSegmentation/LungSegmentation.hpp" 40 #include "FAST/Algorithms/AirwaySegmentation/AirwaySegmentation.hpp" 41 #include "FAST/Algorithms/CenterlineExtraction/CenterlineExtraction.hpp" 42 #include "FAST/Importers/ImageFileImporter.hpp" 43 #include "FAST/Exporters/VTKImageExporter.hpp" 44 #include "FAST/Exporters/VTKMeshExporter.hpp" 45 #include "FAST/Data/Segmentation.hpp" 46 #include "FAST/SceneGraph.hpp" 52 mDefaultStraightCLTubesOption(false)
54 fast::Reporter::setGlobalReportMethod(fast::Reporter::COUT);
56 fast::ImageFileImporter::pointer importer = fast::ImageFileImporter::New();
66 return "Airway Segmentation Filter";
71 return "airways_filter";
77 "<h3>Airway Segmentation.</h3>" 78 "<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>" 100 Vector3D point = spaceProvider->getActiveToolTipPoint(
101 spaceProvider->getD(data));
105 double spacingX, spacingY, spacingZ;
107 point(0) = point(0) * (1.0 / spacingX);
108 point(1) = point(1) * (1.0 / spacingY);
109 point(2) = point(2) * (1.0 / spacingZ);
111 std::cout <<
"the selected seed point is: " << point(0) <<
" " << point(1)
112 <<
" " << point(2) <<
"\n";
119 ImagePtr image = boost::dynamic_pointer_cast<
Image>(inputImage);
123 bool AirwaysFilter::isSeedPointInsideImage(
Vector3D seedPoint,
DataPtr image)
126 std::cout <<
"size of image is: " << size[0] <<
" " << size[1] <<
" " 128 int x = (int) seedPoint(0);
129 int y = (int) seedPoint(1);
130 int z = (int) seedPoint(2);
131 bool result = x >= 0 && y >= 0 && z >= 0 && x < size[0] && y < size[1]
145 if (inputImage->getType() !=
"image")
151 std::string filename = (
patientService()->getActivePatientFolder()
152 +
"/" + inputImage->getFilename()).toStdString();
155 bool useManualSeedPoint = getManualSeedPointOption(
mOptions)->getValue();
156 if(useManualSeedPoint)
158 seedPoint = getSeedPointFromTool(
mServices->spaceProvider(), inputImage);
159 if(!isSeedPointInsideImage(seedPoint, inputImage)) {
160 CX_LOG_ERROR() <<
"Seed point is not inside image. Use cursor to set seed point inside trachea in the CT image.";
176 QString q_filename =
"";
177 QString activePatienFolder =
patientService()->getActivePatientFolder();
178 QString inputImageFileName = mInputImage->getFilename();
179 if(!activePatienFolder.isEmpty())
180 q_filename = activePatienFolder+
"/"+inputImageFileName;
182 q_filename = inputImageFileName;
184 std::string filename = q_filename.toStdString();
186 fast::Config::getTestDataPath();
188 fast::Config::setKernelBinaryPath(cacheDir.toStdString());
190 fast::Config::setKernelSourcePath(kernelDir.toStdString());
193 fast::ImageFileImporter::pointer importer = fast::ImageFileImporter::New();
194 importer->setFilename(filename);
198 fast::Image::pointer image = importer->getOutputData<fast::Image>();
201 fast::Segmentation::pointer segmentationData;
202 bool doLungSegmentation = getLungSegmentationOption(
mOptions)->getValue();
203 bool useManualSeedPoint = getManualSeedPointOption(
mOptions)->getValue();
205 if(doLungSegmentation) {
206 fast::LungSegmentation::pointer segmentation = fast::LungSegmentation::New();
207 if(useManualSeedPoint) {
208 CX_LOG_INFO() <<
"Using seed point: " << seedPoint.transpose();
209 segmentation->setAirwaySeedPoint(seedPoint(0), seedPoint(1), seedPoint(2));
211 segmentation->setInputConnection(importer->getOutputPort());
212 segmentation->update();
213 segmentationData = segmentation->getOutputData<fast::Segmentation>(1);
216 vtkSmartPointer<fast::VTKImageExporter> vtkExporter = fast::VTKImageExporter::New();
217 vtkExporter->setInputConnection(segmentation->getOutputPort(1));
218 vtkExporter->Update();
219 mAirwaySegmentationOutput = vtkExporter->GetOutput();
222 vtkSmartPointer<fast::VTKImageExporter> vtkExporter2 = fast::VTKImageExporter::New();
223 vtkExporter2->setInputConnection(segmentation->getOutputPort(0));
224 vtkExporter2->Update();
225 mLungSegmentationOutput = vtkExporter2->GetOutput();
228 fast::AirwaySegmentation::pointer segmentation = fast::AirwaySegmentation::New();
229 if(useManualSeedPoint) {
230 CX_LOG_INFO() <<
"Using seed point: " << seedPoint.transpose();
231 segmentation->setSeedPoint(seedPoint(0), seedPoint(1), seedPoint(2));
233 segmentation->setInputConnection(importer->getOutputPort());
234 segmentation->update();
235 segmentationData = segmentation->getOutputData<fast::Segmentation>(0);
238 vtkSmartPointer<fast::VTKImageExporter> vtkExporter = fast::VTKImageExporter::New();
239 vtkExporter->setInputConnection(segmentation->getOutputPort());
240 vtkExporter->Update();
241 mAirwaySegmentationOutput = vtkExporter->GetOutput();
243 }
catch(fast::Exception & e)
247 if(!useManualSeedPoint)
248 CX_LOG_ERROR() <<
"Try to set the seed point manually.";
256 Eigen::Affine3f T = fast::SceneGraph::getEigenAffineTransformationFromData(segmentationData);
257 mTransformation.matrix() = T.matrix().cast<
double>();
260 fast::CenterlineExtraction::pointer centerline = fast::CenterlineExtraction::New();
261 centerline->setInputData(segmentationData);
264 vtkSmartPointer<fast::VTKMeshExporter> vtkCenterlineExporter = fast::VTKMeshExporter::New();
265 vtkCenterlineExporter->setInputConnection(centerline->getOutputPort());
266 mCenterlineOutput = vtkCenterlineExporter->GetOutput();
267 vtkCenterlineExporter->Update();
269 }
catch(fast::Exception& e) {
270 std::string error = e.what();
274 }
catch(cl::Error& e) {
278 }
catch (std::exception& e){
283 reportError(
"Airway segmentation algorithm threw a unknown exception.");
292 if(!mAirwaySegmentationOutput)
295 std::cout <<
"POST PROCESS" << std::endl;
298 double threshold = 1;
300 mAirwaySegmentationOutput,
317 contour->get_rMd_History()->setRegistration(mTransformation);
322 if(getLungSegmentationOption(
mOptions)->getValue()) {
324 mLungSegmentationOutput,
343 contour->get_rMd_History()->setRegistration(mTransformation);
354 centerline->get_rMd_History()->setParentSpace(mInputImage->getUid());
355 centerline->get_rMd_History()->setRegistration(mTransformation);
359 this->createAirwaysFromCenterline();
365 void AirwaysFilter::createAirwaysFromCenterline()
369 airwaysFromCLPtr->processCenterline(mCenterlineOutput);
376 airwayWalls->get_rMd_History()->setParentSpace(mInputImage->getUid());
377 airwayWalls->get_rMd_History()->setRegistration(mTransformation);
378 airwayWalls->setColor(QColor(253, 173, 136, 255));
388 centerline->get_rMd_History()->setParentSpace(mInputImage->getUid());
389 centerline->get_rMd_History()->setRegistration(mTransformation);
396 mDefaultStraightCLTubesOption = defaultStraightCLTubesOption;
410 temp->setValueName(
"Input");
411 temp->setHelp(
"Select input to run airway segmentation on.");
418 std::vector<std::pair<QString, QString>> valueHelpPairs;
419 valueHelpPairs.push_back(std::make_pair(tr(
"Airway Centerline"), tr(
"Generated centerline mesh (vtk-format).")));
420 valueHelpPairs.push_back(std::make_pair(tr(
"Airway Segmentation"), tr(
"Generated surface of the airway segmentation volume.")));
421 valueHelpPairs.push_back(std::make_pair(tr(
"Lung Segmentation"), tr(
"Generated surface of the lung segmentation volume.")));
422 valueHelpPairs.push_back(std::make_pair(tr(
"Straight Airway Centerline"), tr(
"A centerline with straight lines between the branch points.")));
423 valueHelpPairs.push_back(std::make_pair(tr(
"Straight Airway Tubes"), tr(
"Tubes based on the straight centerline")));
425 foreach(
auto pair, valueHelpPairs)
428 tempMeshStringAdapter->setValueName(pair.first);
429 tempMeshStringAdapter->setHelp(pair.second);
435 BoolPropertyPtr AirwaysFilter::getManualSeedPointOption(QDomElement root)
440 "If the automatic seed point detection algorithm fails you can use cursor to set the seed point " 441 "inside trachea of the patient. " 442 "Then tick this checkbox to use the manual seed point in the airways filter.",
448 BoolPropertyPtr AirwaysFilter::getLungSegmentationOption(QDomElement root)
453 "Selecting this option will also segment the two lung sacs",
boost::shared_ptr< class SpaceProvider > SpaceProviderPtr
QString qstring_cast(const T &val)
boost::shared_ptr< AirwaysFromCenterline > AirwaysFromCenterlinePtr
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
std::vector< SelectDataStringPropertyBasePtr > mInputTypes
void reportError(QString msg)
boost::shared_ptr< class VisServices > VisServicesPtr
boost::shared_ptr< class Image > ImagePtr
virtual vtkImageDataPtr getBaseVtkImageData()
virtual void createOutputTypes()
virtual void createOptions()
virtual bool postProcess()
AirwaysFilter(VisServicesPtr services)
std::vector< PropertyPtr > mOptionsAdapters
boost::shared_ptr< class Data > DataPtr
static QString findConfigFolder(QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
boost::shared_ptr< class SelectDataStringPropertyBase > SelectDataStringPropertyBasePtr
PatientModelServicePtr patientService()
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)
int * getImageSize(DataPtr inputImage)
virtual void createInputTypes()
virtual QString getType() const
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
static QString getNameSuffixCenterline()
std::vector< SelectDataStringPropertyBasePtr > mOutputTypes
static QString getNameSuffixStraight()
void setDefaultStraightCLTubesOption(bool defaultStraightCLTubesOption)
static StringPropertySelectMeshPtr New(PatientModelServicePtr patientModelService)
virtual bool postProcess()
static StringPropertySelectImagePtr New(PatientModelServicePtr patientModelService)
boost::shared_ptr< class BoolProperty > BoolPropertyPtr
boost::shared_ptr< class Mesh > MeshPtr
static QString getNameSuffixTubes()
boost::shared_ptr< class StringPropertySelectMesh > StringPropertySelectMeshPtr
virtual QString getName() const
virtual QString getHelp() const
Namespace for all CustusX production code.