CustusX  18.04
An IGT application
cxDilationFilter.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 
12 #include "cxDilationFilter.h"
13 
14 #include "cxDoubleProperty.h"
15 #include "cxColorProperty.h"
16 #include "cxBoolProperty.h"
17 #include "cxStringProperty.h"
19 
20 #include <itkBinaryDilateImageFilter.h>
21 #include <itkBinaryBallStructuringElement.h>
22 #include "cxAlgorithmHelpers.h"
23 #include <vtkImageCast.h>
24 #include "cxUtilHelpers.h"
25 #include "cxContourFilter.h"
26 #include "cxMesh.h"
27 #include "cxImage.h"
28 #include "cxPatientModelService.h"
29 #include "cxVolumeHelpers.h"
30 #include "cxVisServices.h"
31 
32 
33 namespace cx {
34 
36  FilterImpl(services)
37 {
38 }
39 
40 QString DilationFilter::getName() const
41 {
42  return "Dilation";
43 }
44 
45 QString DilationFilter::getType() const
46 {
47  return "dilation_filter";
48 }
49 
50 QString DilationFilter::getHelp() const
51 {
52  return "<html>"
53  "<h3>Dilation Filter.</h3>"
54  "<p>This filter dilates a binary volume with a given radius in mm.<p>"
55  "<p>The dilation is performed using a ball structuring element<p>"
56  "</html>";
57 }
58 
60 {
61  DoublePropertyPtr retval = DoubleProperty::initialize("Dilation radius (mm)", "",
62  "Set dilation radius in mm", 1, DoubleRange(1, 20, 1), 0,
63  root);
64  retval->setGuiRepresentation(DoublePropertyBase::grSLIDER);
65  return retval;
66 }
67 
69 {
70  BoolPropertyPtr retval = BoolProperty::initialize("Generate Surface", "",
71  "Generate a surface of the output volume", true,
72  root);
73  return retval;
74 }
75 
77 {
78  return ColorProperty::initialize("Color", "",
79  "Color of output model.",
80  QColor("green"), root);
81 }
82 
83 
85 {
88  mOptionsAdapters.push_back(this->getColorOption(mOptions));
89 }
90 
92 {
94 
95  temp = StringPropertySelectImage::New(mServices->patient());
96  temp->setValueName("Input");
97  temp->setHelp("Select segmentation input for dilation");
98  mInputTypes.push_back(temp);
99 }
100 
102 {
104 
105  temp = StringPropertySelectData::New(mServices->patient());
106  temp->setValueName("Output");
107  temp->setHelp("Dilated segmentation image");
108  mOutputTypes.push_back(temp);
109 
110  temp = StringPropertySelectData::New(mServices->patient());
111  temp->setValueName("Contour");
112  temp->setHelp("Output contour generated from dilated segmentation image.");
113  mOutputTypes.push_back(temp);
114 }
115 
117 
118  return FilterImpl::preProcess();
119 }
120 
122  ImagePtr input = this->getCopiedInputImage();
123  if (!input)
124  return false;
125 
126  double radius = this->getDilationRadiusOption(mCopiedOptions)->getValue();
127 
128  // Convert radius in mm to radius in voxels for the structuring element
129  Eigen::Array3d spacing = input->getSpacing();
130  itk::Size<3> radiusInVoxels;
131  radiusInVoxels[0] = radius/spacing(0);
132  radiusInVoxels[1] = radius/spacing(1);
133  radiusInVoxels[2] = radius/spacing(2);
134 
135  itkImageType::ConstPointer itkImage = AlgorithmHelper::getITKfromSSCImage(input);
136 
137  // Create structuring element
138  typedef itk::BinaryBallStructuringElement<unsigned char,3> StructuringElementType;
139  StructuringElementType structuringElement;
140  structuringElement.SetRadius(radiusInVoxels);
141  structuringElement.CreateStructuringElement();
142 
143  // Dilation
144  typedef itk::BinaryDilateImageFilter<itkImageType, itkImageType, StructuringElementType> dilateFilterType;
145  dilateFilterType::Pointer dilationFilter = dilateFilterType::New();
146  dilationFilter->SetInput(itkImage);
147  dilationFilter->SetKernel(structuringElement);
148  dilationFilter->SetDilateValue(1);
149  dilationFilter->Update();
150  itkImage = dilationFilter->GetOutput();
151 
152  //Convert ITK to VTK
153  itkToVtkFilterType::Pointer itkToVtkFilter = itkToVtkFilterType::New();
154  itkToVtkFilter->SetInput(itkImage);
155  itkToVtkFilter->Update();
156 
157  vtkImageDataPtr rawResult = vtkImageDataPtr::New();
158  rawResult->DeepCopy(itkToVtkFilter->GetOutput());
159 
160  vtkImageCastPtr imageCast = vtkImageCastPtr::New();
161  imageCast->SetInputData(rawResult);
162  imageCast->SetOutputScalarTypeToUnsignedChar();
163  imageCast->Update();
164  rawResult = imageCast->GetOutput();
165 
166  // TODO: possible memory problem here - check debug mem system of itk/vtk
167 
168  mRawResult = rawResult;
169 
171  if (generateSurface->getValue())
172  {
173  double threshold = 1;
174  mRawContour = ContourFilter::execute(mRawResult, threshold);
175  }
176 
177  return true;
178 }
179 
181 {
182  if (!mRawResult)
183  return false;
184 
185  ImagePtr input = this->getCopiedInputImage();
186 
187  if (!input)
188  return false;
189 
190  QString uid = input->getUid() + "_seg%1";
191  QString name = input->getName()+" seg%1";
192  ImagePtr output = createDerivedImage(mServices->patient(),
193  uid, name,
194  mRawResult, input);
195  mRawResult = NULL;
196  if (!output)
197  return false;
198 
199  output->resetTransferFunctions();
200  mServices->patient()->insertData(output);
201 
202  // set output
203  mOutputTypes.front()->setValue(output->getUid());
204 
205  // set contour output
206  if (mRawContour!=NULL)
207  {
208  ColorPropertyPtr colorOption = this->getColorOption(mOptions);
209  MeshPtr contour = ContourFilter::postProcess(mServices->patient(), mRawContour, output, colorOption->getValue());
210  mOutputTypes[1]->setValue(contour->getUid());
211  mRawContour = vtkPolyDataPtr();
212  }
213 
214  return true;
215 }
216 
217 
218 
219 } // namespace cx
DilationFilter(VisServicesPtr services)
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
std::vector< SelectDataStringPropertyBasePtr > mInputTypes
Definition: cxFilterImpl.h:73
QDomElement mCopiedOptions
Definition: cxFilterImpl.h:80
virtual QString getName() const
virtual void createOutputTypes()
DoublePropertyPtr getDilationRadiusOption(QDomElement root)
virtual void createInputTypes()
boost::shared_ptr< class ColorProperty > ColorPropertyPtr
virtual void createOptions()
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:40
virtual bool preProcess()
static StringPropertySelectDataPtr New(PatientModelServicePtr patientModelService, QString typeRegexp=".*")
Utility class for describing a bounded numeric range.
Definition: cxDoubleRange.h:32
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
virtual bool postProcess()
virtual bool execute()
virtual QString getHelp() const
ColorPropertyPtr getColorOption(QDomElement root)
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
virtual bool execute()
ImagePtr getCopiedInputImage(int index=0)
QDomElement mOptions
Definition: cxFilterImpl.h:76
vtkSmartPointer< class vtkImageCast > vtkImageCastPtr
vtkSmartPointer< vtkPolyData > vtkPolyDataPtr
boost::shared_ptr< class DoubleProperty > DoublePropertyPtr
std::vector< SelectDataStringPropertyBasePtr > mOutputTypes
Definition: cxFilterImpl.h:74
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
virtual QString getType() const
virtual bool postProcess()
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())
BoolPropertyPtr getGenerateSurfaceOption(QDomElement root)
boost::shared_ptr< class BoolProperty > BoolPropertyPtr
boost::shared_ptr< class Mesh > MeshPtr
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
Namespace for all CustusX production code.