CustusX  18.04
An IGT application
cxBinaryThinningImageFilter3DFilter.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) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
13 
15 
16 #include "cxLogger.h"
18 #include "cxMesh.h"
19 #include "cxImage.h"
20 #include "cxColorProperty.h"
23 #include "cxAlgorithmHelpers.h"
24 #include "cxPatientModelService.h"
25 #include "cxVolumeHelpers.h"
26 #include "cxVisServices.h"
27 
28 namespace cx
29 {
31  FilterImpl(services)
32 {
33 }
34 
36 {
37  return "Centerline";
38 }
39 
41 {
42  return "binary_thinning_image_filter_3d_filter";
43 }
44 
46 {
47  return "<html>"
48  "<h3>itk::BinaryThinningImageFilter3D</h3>"
49  "<p>"
50  "This filter computes one-pixel-wide skeleton of a 3D input image."
51  "</p><p>"
52  "This class is parametrized over the type of the input image "
53  "and the type of the output image."
54  "</p><p>"
55  "The input is assumed to be a binary image. All non-zero valued voxels "
56  "are set to 1 internally to simplify the computation. The filter will "
57  "produce a skeleton of the object. The output background values are 0, "
58  "and the foreground values are 1."
59  "</p><p>"
60  "A 26-neighbourhood configuration is used for the foreground and a "
61  "6-neighbourhood configuration for the background. Thinning is performed "
62  "symmetrically in order to guarantee that the skeleton lies medial within "
63  "the object."
64  "</p><p>"
65  "This filter is a parallel thinning algorithm and is an implementation "
66  "of the algorithm described in:"
67  "</p><p>"
68  "T.C. Lee, R.L. Kashyap, and C.N. Chu.<br>"
69  "Building skeleton models via 3-D medial surface/axis thinning algorithms.<br>"
70  "Computer Vision, Graphics, and Image Processing, 56(6):462--478, 1994."
71  "</p></html>";
72 }
73 
75 {
76  return ColorProperty::initialize("Color", "",
77  "Color of output model.",
78  QColor("green"), root);
79 }
80 
82 {
83  mOptionsAdapters.push_back(this->getColorOption(mOptions));
84 }
85 
87 {
89 
90  temp = StringPropertySelectImage::New(mServices->patient());
91  temp->setValueName("Input");
92  temp->setHelp("Select binary volume input for thinning");
93  // connect(temp.get(), SIGNAL(dataChanged(QString)), this, SLOT(imageChangedSlot(QString)));
94  mInputTypes.push_back(temp);
95 }
96 
98 {
100 
101  temp = StringPropertySelectMesh::New((mServices->patient()));
102  temp->setValueName("Output");
103  temp->setHelp("Output centerline model");
104  mOutputTypes.push_back(temp);
105 }
106 
108 {
109  bool retval = FilterImpl::preProcess();
110  if (!retval)
111  return false;
112 
113  ImagePtr input = this->getCopiedInputImage();
114  if (!input)
115  return false;
116 
117  if (input->getMax() != 1 || input->getMin() != 0)
118  {
119  reportWarning(QString("Centerline: Input image %1 must be binary, aborting.").arg(input->getName()));
120  return false;
121  }
122 
123  return true;
124 }
125 
127 {
128  ImagePtr input = this->getCopiedInputImage();
129  if (!input)
130  return false;
131 
132  if (input->getMax() != 1 || input->getMin() != 0)
133  {
134  return false;
135  }
136 
137  // report(QString("Creating centerline from \"%1\"...").arg(input->getName()));
138 
139  itkImageType::ConstPointer itkImage = AlgorithmHelper::getITKfromSSCImage(input);
140 
141  //Centerline extraction
143  centerlineFilterType::Pointer centerlineFilter = centerlineFilterType::New();
144  centerlineFilter->SetInput(itkImage);
145  centerlineFilter->Update();
146  itkImage = centerlineFilter->GetOutput();
147 
148  //Convert ITK to VTK
149  itkToVtkFilterType::Pointer itkToVtkFilter = itkToVtkFilterType::New();
150  itkToVtkFilter->SetInput(itkImage);
151  itkToVtkFilter->Update();
152 
153  vtkImageDataPtr rawResult = vtkImageDataPtr::New();
154  rawResult->DeepCopy(itkToVtkFilter->GetOutput());
155 
156  mRawResult = rawResult;
157  return true;
158 }
159 
161 {
162  bool success = false;
163  if(!mRawResult)
164  return success;
165 
167 
168  ImagePtr input = this->getCopiedInputImage();
169 
170  ImagePtr outImage = createDerivedImage(mServices->patient(),
171  input->getUid() + "_cl_temp%1", input->getName()+" cl_temp%1",
172  mRawResult, input);
173 
174  mRawResult = NULL;
175  outImage->resetTransferFunctions();
176 
177  //automatically generate a mesh from the centerline
178  vtkPolyDataPtr centerlinePolyData = SeansVesselReg::extractPolyData(outImage, 1, 0);
179 
180  QString uid = input->getUid() + "_cl%1";
181  QString name = input->getName()+" cl%1";
182  MeshPtr mesh = mServices->patient()->createSpecificData<Mesh>(uid, name);
183  mesh->setVtkPolyData(centerlinePolyData);
184  mesh->setColor(outputColor->getValue());
185  mesh->get_rMd_History()->setParentSpace(input->getUid());
186  mServices->patient()->insertData(mesh);
187 
188  // set output
189  mOutputTypes.front()->setValue(mesh->getUid());
190  success = true;
191 
192  return success;
193 }
194 
195 
196 
197 } // namespace cx
198 
std::vector< SelectDataStringPropertyBasePtr > mInputTypes
Definition: cxFilterImpl.h:73
QDomElement mCopiedOptions
Definition: cxFilterImpl.h:80
A mesh data set.
Definition: cxMesh.h:45
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:40
virtual bool preProcess()
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
std::vector< PropertyPtr > mOptionsAdapters
Definition: cxFilterImpl.h:75
VisServicesPtr mServices
Definition: cxFilterImpl.h:82
ImagePtr createDerivedImage(PatientModelServicePtr dataManager, QString uid, QString name, vtkImageDataPtr raw, ImagePtr parent)
boost::shared_ptr< class SelectDataStringPropertyBase > SelectDataStringPropertyBasePtr
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
void setVtkPolyData(const vtkPolyDataPtr &polyData)
Definition: cxMesh.cpp:91
ColorPropertyBasePtr getColorOption(QDomElement root)
ImagePtr getCopiedInputImage(int index=0)
QDomElement mOptions
Definition: cxFilterImpl.h:76
static vtkPolyDataPtr extractPolyData(ImagePtr image, int p_neighborhoodFilterThreshold, double p_BoundingBox[6])
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
std::vector< SelectDataStringPropertyBasePtr > mOutputTypes
Definition: cxFilterImpl.h:74
boost::shared_ptr< class ColorPropertyBase > ColorPropertyBasePtr
static StringPropertySelectMeshPtr New(PatientModelServicePtr patientModelService)
static itkImageType::ConstPointer getITKfromSSCImage(ImagePtr image)
static StringPropertySelectImagePtr New(PatientModelServicePtr patientModelService)
static ColorPropertyPtr initialize(const QString &uid, QString name, QString help, QColor value, QDomNode root=QDomNode())
boost::shared_ptr< class Mesh > MeshPtr
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
This filter computes one-pixel-wide skeleton of a 3D input image.
Namespace for all CustusX production code.