CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxConnectedThresholdImageFilter.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 
14 #include "itkConnectedThresholdImageFilter.h"
15 #include "cxLogger.h"
16 #include "cxTypeConversions.h"
17 #include "cxAlgorithmHelpers.h"
19 #include "cxImage.h"
20 #include "cxPatientModelService.h"
21 #include "cxVolumeHelpers.h"
22 #include "cxVisServices.h"
23 
24 namespace cx
25 {
26 
28  ThreadedTimedAlgorithm<vtkImageDataPtr>("segmenting", 10),
29  mServices(services)
30 {
31 }
32 
34 {
35 }
36 
37 void ConnectedThresholdImageFilter::setInput(ImagePtr image, QString outputBasePath, float lowerThreshold, float upperThreshold, int replaceValue, itkImageType::IndexType seed)
38 {
39  mInput = image;
40  mOutputBasePath = outputBasePath;
41 
42  mLowerThreshold = lowerThreshold;
43  mUpperTheshold = upperThreshold;
44  mReplaceValue = replaceValue;
45  mSeed = seed;
46 
47  this->generate();
48 }
49 
51 {
52  return mOutput;
53 }
54 
55 void ConnectedThresholdImageFilter::postProcessingSlot()
56 {
57  //get the result from the thread
58  vtkImageDataPtr rawResult = this->getResult();
59 
60  if(!rawResult)
61  {
62  reportError("Segmentation failed.");
63  return;
64  }
65 
66  //generate a new name and unique id for the newly created object
67  QString uid = mInput->getUid() + "_seg%1";
68  QString name = mInput->getName()+" seg%1";
69 
70  //create a Image
71  ImagePtr result = createDerivedImage(mServices->patient(),
72  uid, name,
73  rawResult, mInput);
74  mOutput->resetTransferFunctions();
75 
76  mServices->patient()->insertData(mOutput);
77 
78  //let the user know you are finished
79  reportSuccess("Done segmenting: \"" + mOutput->getName()+"\"");
80 
81  //let the system know you're finished
82  // emit finished();
83 }
84 
85 vtkImageDataPtr ConnectedThresholdImageFilter::calculate()
86 {
87  //Connected Thresholding
88 
89  //Documentation:
90  // http://www.na-mic.org/svn/Slicer3-lib-mirrors/trunk/Insight/Examples/Segmentation/ConnectedThresholdImageFilter.cxx
91 
92  // The ConnectedThresholdImageFilter has two main parameters to be
93  // defined. They are the lower and upper thresholds of the interval in
94  // which intensity values should fall in order to be included in the
95  // region. Setting these two values too close will not allow enough
96  // flexibility for the region to grow. Setting them too far apart will
97  // result in a region that engulfs the image.
98 
99  // The output of this filter is a binary image with zero-value pixels
100  // everywhere except on the extracted region. The intensity value set
101  // inside the region is selected with the method SetReplaceValue()
102 
103  // The initialization of the algorithm requires the user to provide a seed
104  // point. It is convenient to select this point to be placed in a
105  // typical region of the anatomical structure to be segmented. The
106  // seed is passed in the form of a IndexType to the SetSeed()
107  // method.
108 
109  // Another option for segmenting regions is to take advantage of the
110  // functionality provided by the ConnectedThresholdImageFilter for
111  // managing multiple seeds. The seeds can be passed one by one to the
112  // filter using the AddSeed() method. You could imagine a user
113  // interface in which an operator clicks on multiple points of the object
114  // to be segmented and each selected point is passed as a seed to this
115  // filter.
116 
117  itkImageType::ConstPointer itkImage = AlgorithmHelper::getITKfromSSCImage(mInput);
118 
119  typedef itk::ConnectedThresholdImageFilter<itkImageType, itkImageType> thresholdFilterType;
120  thresholdFilterType::Pointer thresholdFilter = thresholdFilterType::New();
121  thresholdFilter->SetInput(itkImage);
122 
123  //set thresholds
124  thresholdFilter->SetLower(mLowerThreshold);
125  thresholdFilter->SetUpper(mUpperTheshold);
126  thresholdFilter->SetReplaceValue(mReplaceValue);
127 
128  //set seeds
129  thresholdFilter->SetSeed(mSeed);
130 
131  //calculate
132  try
133  {
134  thresholdFilter->Update();
135  }
136  catch( itk::ExceptionObject & excep )
137  {
138  reportError("Error when setting seed for Connected Threshold Image Filter:");
139  reportError(qstring_cast(excep.GetDescription()));
140  }
141 
142  itkImage = thresholdFilter->GetOutput();
143 
144  //Convert ITK to VTK
145  itkToVtkFilterType::Pointer itkToVtkFilter = itkToVtkFilterType::New();
146  itkToVtkFilter->SetInput(itkImage);
147  itkToVtkFilter->Update();
148 
149  vtkImageDataPtr rawResult = vtkImageDataPtr::New();
150  rawResult->DeepCopy(itkToVtkFilter->GetOutput());
151  // TODO: possible memory problem here - check debug mem system of itk/vtk
152 
153  return rawResult;
154 }
155 
156 }
QString qstring_cast(const T &val)
void reportError(QString msg)
Definition: cxLogger.cpp:71
Base class for algorithms that wants to thread and time their execution. T is the return type of the ...
boost::shared_ptr< class VisServices > VisServicesPtr
Definition: cxMainWindow.h:40
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:27
ImagePtr createDerivedImage(PatientModelServicePtr dataManager, QString uid, QString name, vtkImageDataPtr raw, ImagePtr parent)
void reportSuccess(QString msg)
Definition: cxLogger.cpp:72
static itkImageType::ConstPointer getITKfromSSCImage(ImagePtr image)
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
void setInput(ImagePtr image, QString outputBasePath, float lowerThreshold, float upperThreshold, int replaceValue, itkImageType::IndexType seed)
Namespace for all CustusX production code.