CustusX  15.8
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  this->stopPreview();
148 }
149 
150 void BinaryThresholdImageFilter::imageChangedSlot(QString uid)
151 {
152  this->stopPreview();
153  this->updateThresholdPairFromImageChange(uid, mThresholdOption);
154 }
155 
156 void BinaryThresholdImageFilter::stopPreview()
157 {
158  if(mPreviewImage)
159  mPreviewImage->stopThresholdPreview();
160  mPreviewImage.reset();
161 }
162 
163 void BinaryThresholdImageFilter::thresholdSlot()
164 {
165 // this->stopPreview();
166  if (mActive)
167  {
168  mPreviewImage = boost::dynamic_pointer_cast<Image>(mInputTypes[0]->getData());
169  Eigen::Vector2d threshold = Eigen::Vector2d(mThresholdOption->getValue()[0], mThresholdOption->getValue()[1]);
170  mPreviewImage->startThresholdPreview(threshold);
171  }
172 }
173 
175 {
176  this->stopPreview();
177  return FilterImpl::preProcess();
178 
179 }
180 
182 {
183  ImagePtr input = this->getCopiedInputImage();
184  if (!input)
185  return false;
186 
189 
190  itkImageType::ConstPointer itkImage = AlgorithmHelper::getITKfromSSCImage(input);
191 
192  //Binary Thresholding
193  typedef itk::BinaryThresholdImageFilter<itkImageType, itkImageType> thresholdFilterType;
194  thresholdFilterType::Pointer thresholdFilter = thresholdFilterType::New();
195  thresholdFilter->SetInput(itkImage);
196  thresholdFilter->SetOutsideValue(0);
197  thresholdFilter->SetInsideValue(1);
198  thresholdFilter->SetLowerThreshold(thresholds->getValue()[0]);
199  thresholdFilter->SetUpperThreshold(thresholds->getValue()[1]);
200  thresholdFilter->Update();
201  itkImage = thresholdFilter->GetOutput();
202 
203  //Convert ITK to VTK
204  itkToVtkFilterType::Pointer itkToVtkFilter = itkToVtkFilterType::New();
205  itkToVtkFilter->SetInput(itkImage);
206  itkToVtkFilter->Update();
207 
208  vtkImageDataPtr rawResult = vtkImageDataPtr::New();
209  rawResult->DeepCopy(itkToVtkFilter->GetOutput());
210 
211  vtkImageCastPtr imageCast = vtkImageCastPtr::New();
212  imageCast->SetInputData(rawResult);
213  imageCast->SetOutputScalarTypeToUnsignedChar();
214  imageCast->Update();
215  rawResult = imageCast->GetOutput();
216 
217  // TODO: possible memory problem here - check debug mem system of itk/vtk
218 
219  mRawResult = rawResult;
220 
221  if (generateSurface->getValue())
222  {
223  double threshold = 1;
224  mRawContour = ContourFilter::execute(mRawResult, threshold);
225  }
226 
227  return true;
228 }
229 
231 {
232  if (!mRawResult)
233  return false;
234 
235  ImagePtr input = this->getCopiedInputImage();
236 
237  if (!input)
238  return false;
239 
240  QString uid = input->getUid() + "_seg%1";
241  QString name = input->getName()+" seg%1";
242  ImagePtr output = createDerivedImage(mServices->getPatientService(),
243  uid, name,
244  mRawResult, input);
245 
246  mRawResult = NULL;
247 
248  output->resetTransferFunctions();
249  mServices->getPatientService()->insertData(output);
250 
251  // set output
252  mOutputTypes.front()->setValue(output->getUid());
253 
254  // set contour output
255  if (mRawContour!=NULL)
256  {
257  ColorPropertyPtr colorOption = this->getColorOption(mOptions);
258  MeshPtr contour = ContourFilter::postProcess(mServices->getPatientService(), mRawContour, output, colorOption->getValue());
259  mOutputTypes[1]->setValue(contour->getUid());
260  mRawContour = vtkPolyDataPtr();
261  }
262 
263  return true;
264 }
265 
266 
267 }//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:62
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:103
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()