CustusX  15.3.4-beta
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxBinaryThresholdImageFilter.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 
34 
35 #include "cxAlgorithmHelpers.h"
36 #include <itkBinaryThresholdImageFilter.h>
37 #include <vtkImageCast.h>
38 #include "cxUtilHelpers.h"
40 #include "cxStringProperty.h"
41 #include "cxColorProperty.h"
42 #include "cxBoolProperty.h"
43 #include "cxTypeConversions.h"
44 #include "cxDoublePairProperty.h"
45 #include "cxContourFilter.h"
46 #include "cxMesh.h"
47 #include "cxImage.h"
49 #include "cxPatientModelService.h"
50 #include "cxViewService.h"
51 #include "cxVolumeHelpers.h"
52 #include "cxVisServices.h"
53 
54 namespace cx
55 {
56 
58  FilterImpl(services)
59 {
60 }
61 
63 {
64  return "Segmentation";
65 }
66 
68 {
69  return "BinaryThresholdImageFilter";
70 }
71 
73 {
74  return "<html>"
75  "<h3>Binary Threshold Image Filter.</h3>"
76  "<p><i>Segment out areas from the selected image using a threshold.</i></p>"
77  "<p>This filter produces an output image whose pixels are either one of two values"
78  "( OutsideValue or InsideValue ), depending on whether the corresponding input"
79  "image pixels lie between the two thresholds ( LowerThreshold and UpperThreshold )."
80  "Values equal to either threshold is considered to be between the thresholds.<p>"
81  "</html>";
82 }
83 
85 {
86  DoublePairPropertyPtr retval = DoublePairProperty::initialize("Thresholds", "",
87  "Select lower and upper threshold for the segmentation", DoubleRange(0, 100, 1), 0,
88  root);
89  return retval;
90 }
91 
93 {
94  BoolPropertyPtr retval = BoolProperty::initialize("Generate Surface", "",
95  "Generate a surface of the output volume", true,
96  root);
97  return retval;
98 }
99 
101 {
102  return ColorProperty::initialize("Color", "",
103  "Color of output model.",
104  QColor("green"), root);
105 }
106 
108 {
109  mThresholdOption = this->getThresholdOption(mOptions);
110  connect(mThresholdOption.get(), SIGNAL(changed()), this, SLOT(thresholdSlot()));
111  mOptionsAdapters.push_back(mThresholdOption);
113  mOptionsAdapters.push_back(this->getColorOption(mOptions));
114 }
115 
117 {
119 
120  temp = StringPropertySelectImage::New(mServices->getPatientService());
121  temp->setValueName("Input");
122  temp->setHelp("Select image input for thresholding");
123  connect(temp.get(), SIGNAL(dataChanged(QString)), this, SLOT(imageChangedSlot(QString)));
124  mInputTypes.push_back(temp);
125 }
126 
128 {
130 
131  temp = StringPropertySelectData::New(mServices->getPatientService());
132  temp->setValueName("Output");
133  temp->setHelp("Output thresholded binary image");
134  mOutputTypes.push_back(temp);
135 
136  temp = StringPropertySelectData::New(mServices->getPatientService());
137  temp->setValueName("Contour");
138  temp->setHelp("Output contour generated from thresholded binary image.");
139  mOutputTypes.push_back(temp);
140 }
141 
143 {
145 
146  if (!mActive)
147  mServices->visualizationService->removePreview();
148 }
149 
150 void BinaryThresholdImageFilter::imageChangedSlot(QString uid)
151 {
152  this->updateThresholdPairFromImageChange(uid, mThresholdOption);
153  mServices->visualizationService->removePreview();
154 }
155 
156 void BinaryThresholdImageFilter::thresholdSlot()
157 {
158  if (mActive)
159  {
160  ImagePtr image = boost::dynamic_pointer_cast<Image>(mInputTypes[0]->getData());
161  std::vector<double> threshold;
162  threshold.push_back(mThresholdOption->getValue()[0]);
163  threshold.push_back(mThresholdOption->getValue()[1]);
164  mServices->visualizationService->setPreview(image, threshold);
165  }
166 }
167 
169 {
170  mServices->visualizationService->removePreview();
171  return FilterImpl::preProcess();
172 
173 }
174 
176 {
177  ImagePtr input = this->getCopiedInputImage();
178  if (!input)
179  return false;
180 
183 
184  itkImageType::ConstPointer itkImage = AlgorithmHelper::getITKfromSSCImage(input);
185 
186  //Binary Thresholding
187  typedef itk::BinaryThresholdImageFilter<itkImageType, itkImageType> thresholdFilterType;
188  thresholdFilterType::Pointer thresholdFilter = thresholdFilterType::New();
189  thresholdFilter->SetInput(itkImage);
190  thresholdFilter->SetOutsideValue(0);
191  thresholdFilter->SetInsideValue(1);
192  thresholdFilter->SetLowerThreshold(thresholds->getValue()[0]);
193  thresholdFilter->SetUpperThreshold(thresholds->getValue()[1]);
194  thresholdFilter->Update();
195  itkImage = thresholdFilter->GetOutput();
196 
197  //Convert ITK to VTK
198  itkToVtkFilterType::Pointer itkToVtkFilter = itkToVtkFilterType::New();
199  itkToVtkFilter->SetInput(itkImage);
200  itkToVtkFilter->Update();
201 
202  vtkImageDataPtr rawResult = vtkImageDataPtr::New();
203  rawResult->DeepCopy(itkToVtkFilter->GetOutput());
204 
205  vtkImageCastPtr imageCast = vtkImageCastPtr::New();
206  imageCast->SetInputData(rawResult);
207  imageCast->SetOutputScalarTypeToUnsignedChar();
208  imageCast->Update();
209  rawResult = imageCast->GetOutput();
210 
211  // TODO: possible memory problem here - check debug mem system of itk/vtk
212 
213  mRawResult = rawResult;
214 
215  if (generateSurface->getValue())
216  {
217  double threshold = 1;
218  mRawContour = ContourFilter::execute(mRawResult, threshold);
219  }
220 
221  return true;
222 }
223 
225 {
226  if (!mRawResult)
227  return false;
228 
229  ImagePtr input = this->getCopiedInputImage();
230 
231  if (!input)
232  return false;
233 
234  QString uid = input->getUid() + "_seg%1";
235  QString name = input->getName()+" seg%1";
236  ImagePtr output = createDerivedImage(mServices->getPatientService(),
237  uid, name,
238  mRawResult, input);
239 
240  mRawResult = NULL;
241 
242  output->resetTransferFunctions();
243  mServices->getPatientService()->insertData(output);
244 
245  // set output
246  mOutputTypes.front()->setValue(output->getUid());
247 
248  // set contour output
249  if (mRawContour!=NULL)
250  {
251  ColorPropertyPtr colorOption = this->getColorOption(mOptions);
252  MeshPtr contour = ContourFilter::postProcess(mServices->getPatientService(), mRawContour, output, colorOption->getValue());
253  mOutputTypes[1]->setValue(contour->getUid());
254  mRawContour = vtkPolyDataPtr();
255  }
256 
257  return true;
258 }
259 
260 
261 }//namespace cx
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
std::vector< SelectDataStringPropertyBasePtr > mInputTypes
Definition: cxFilterImpl.h:94
QDomElement mCopiedOptions
Definition: cxFilterImpl.h:101
boost::shared_ptr< class ColorProperty > ColorPropertyPtr
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:61
virtual bool preProcess()
void updateThresholdPairFromImageChange(QString uid, DoublePairPropertyPtr threshold)
Utility class for describing a bounded numeric range.
Definition: cxDoubleRange.h:53
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
BoolPropertyPtr getGenerateSurfaceOption(QDomElement root)
vtkSmartPointer< class vtkPolyData > vtkPolyDataPtr
Definition: cxProbeSector.h:47
std::vector< PropertyPtr > mOptionsAdapters
Definition: cxFilterImpl.h:96
VisServicesPtr mServices
Definition: cxFilterImpl.h:104
ImagePtr createDerivedImage(PatientModelServicePtr dataManager, QString uid, QString name, vtkImageDataPtr raw, ImagePtr parent)
boost::shared_ptr< class SelectDataStringPropertyBase > SelectDataStringPropertyBasePtr
virtual bool execute()
DoublePairPropertyPtr getThresholdOption(QDomElement root)
ImagePtr getCopiedInputImage(int index=0)
virtual void setActive(bool on)
QDomElement mOptions
Definition: cxFilterImpl.h:97
vtkSmartPointer< class vtkImageCast > vtkImageCastPtr
static StringPropertySelectDataPtr New(PatientModelServicePtr patientModelService)
ColorPropertyPtr getColorOption(QDomElement root)
std::vector< SelectDataStringPropertyBasePtr > mOutputTypes
Definition: cxFilterImpl.h:95
boost::shared_ptr< class DoublePairProperty > DoublePairPropertyPtr
static DoublePairPropertyPtr initialize(const QString &uid, QString name, QString help, DoubleRange range, int decimals, QDomNode root=QDomNode())
virtual bool postProcess()
static itkImageType::ConstPointer getITKfromSSCImage(ImagePtr image)
static StringPropertySelectImagePtr New(PatientModelServicePtr patientModelService)
BinaryThresholdImageFilter(VisServicesPtr services)
static ColorPropertyPtr initialize(const QString &uid, QString name, QString help, QColor value, QDomNode root=QDomNode())
boost::shared_ptr< class BoolProperty > BoolPropertyPtr
boost::shared_ptr< class Mesh > MeshPtr
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
void changed()