1 /*=========================================================================
2 *
3 * Copyright Insight Software Consortium
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18 #ifndef itkDoubleThresholdImageFilter_hxx
19 #define itkDoubleThresholdImageFilter_hxx
20
21 #include "itkDoubleThresholdImageFilter.h"
22 #include "itkReconstructionByDilationImageFilter.h"
23 #include "itkBinaryThresholdImageFilter.h"
24 #include "itkProgressAccumulator.h"
25
26 namespace itk
27 {
28 template< typename TInputImage, typename TOutputImage >
29 DoubleThresholdImageFilter< TInputImage, TOutputImage >
DoubleThresholdImageFilter()30 ::DoubleThresholdImageFilter()
31
32 {
33 m_Threshold1 = NumericTraits< InputPixelType >::NonpositiveMin();
34 m_Threshold2 = NumericTraits< InputPixelType >::NonpositiveMin();
35 m_Threshold3 = NumericTraits< InputPixelType >::max();
36 m_Threshold4 = NumericTraits< InputPixelType >::max();
37
38 m_OutsideValue = NumericTraits< OutputPixelType >::ZeroValue();
39 m_InsideValue = NumericTraits< OutputPixelType >::max();
40
41 m_FullyConnected = false;
42 }
43
44 template< typename TInputImage, typename TOutputImage >
45 void
46 DoubleThresholdImageFilter< TInputImage, TOutputImage >
GenerateInputRequestedRegion()47 ::GenerateInputRequestedRegion()
48 {
49 // call the superclass' implementation of this method
50 Superclass::GenerateInputRequestedRegion();
51
52 // We need all the input.
53 InputImagePointer input = const_cast< InputImageType * >( this->GetInput() );
54 if ( input )
55 {
56 input->SetRequestedRegion( input->GetLargestPossibleRegion() );
57 }
58 }
59
60 template< typename TInputImage, typename TOutputImage >
61 void
62 DoubleThresholdImageFilter< TInputImage, TOutputImage >
EnlargeOutputRequestedRegion(DataObject *)63 ::EnlargeOutputRequestedRegion(DataObject *)
64 {
65 this->GetOutput()
66 ->SetRequestedRegion( this->GetOutput()->GetLargestPossibleRegion() );
67 }
68
69 template< typename TInputImage, typename TOutputImage >
70 void
71 DoubleThresholdImageFilter< TInputImage, TOutputImage >
GenerateData()72 ::GenerateData()
73 {
74 // Allocate the output
75 this->AllocateOutputs();
76
77 // Build a mini-pipeline that involves two thresholds filters and a
78 // geodesic dilation.
79 using ThresholdFilterType = BinaryThresholdImageFilter< TInputImage, TOutputImage >;
80 using DilationFilterType = ReconstructionByDilationImageFilter< TOutputImage, TOutputImage >;
81
82 typename ThresholdFilterType::Pointer narrowThreshold = ThresholdFilterType::New();
83
84 // Create a process accumulator for tracking the progress of this minipipeline
85 ProgressAccumulator::Pointer progress = ProgressAccumulator::New();
86 progress->SetMiniPipelineFilter(this);
87
88 narrowThreshold->SetLowerThreshold(m_Threshold2);
89 narrowThreshold->SetUpperThreshold(m_Threshold3);
90 narrowThreshold->SetInsideValue(m_InsideValue);
91 narrowThreshold->SetOutsideValue(m_OutsideValue);
92 narrowThreshold->SetInput( this->GetInput() );
93
94 typename ThresholdFilterType::Pointer wideThreshold = ThresholdFilterType::New();
95 wideThreshold->SetLowerThreshold(m_Threshold1);
96 wideThreshold->SetUpperThreshold(m_Threshold4);
97 wideThreshold->SetInsideValue(m_InsideValue);
98 wideThreshold->SetOutsideValue(m_OutsideValue);
99 wideThreshold->SetInput( this->GetInput() );
100
101 typename DilationFilterType::Pointer dilate = DilationFilterType::New();
102 dilate->SetMarkerImage( narrowThreshold->GetOutput() );
103 dilate->SetMaskImage( wideThreshold->GetOutput() );
104 dilate->SetFullyConnected(m_FullyConnected);
105 //dilate->RunOneIterationOff(); // run to convergence
106
107 progress->RegisterInternalFilter(narrowThreshold, .1f);
108 progress->RegisterInternalFilter(wideThreshold, .1f);
109 progress->RegisterInternalFilter(dilate, .8f);
110
111 // graft our output to the dilate filter to force the proper regions
112 // to be generated
113 dilate->GraftOutput( this->GetOutput() );
114
115 // reconstruction by dilation
116 dilate->Update();
117
118 // graft the output of the dilate filter back onto this filter's
119 // output. this is needed to get the appropriate regions passed
120 // back.
121 this->GraftOutput( dilate->GetOutput() );
122 }
123
124 template< typename TInputImage, typename TOutputImage >
125 void
126 DoubleThresholdImageFilter< TInputImage, TOutputImage >
PrintSelf(std::ostream & os,Indent indent) const127 ::PrintSelf(std::ostream & os, Indent indent) const
128 {
129 Superclass::PrintSelf(os, indent);
130
131 os << indent << "Threshold1: "
132 << static_cast< typename NumericTraits< InputPixelType >::PrintType >( m_Threshold1 )
133 << std::endl;
134 os << indent << "Threshold2: "
135 << static_cast< typename NumericTraits< InputPixelType >::PrintType >( m_Threshold2 )
136 << std::endl;
137 os << indent << "Threshold3: "
138 << static_cast< typename NumericTraits< InputPixelType >::PrintType >( m_Threshold3 )
139 << std::endl;
140 os << indent << "Threshold4: "
141 << static_cast< typename NumericTraits< InputPixelType >::PrintType >( m_Threshold4 )
142 << std::endl;
143 os << indent << "InsideValue: "
144 << static_cast< typename NumericTraits< OutputPixelType >::PrintType >( m_InsideValue )
145 << std::endl;
146 os << indent << "OutsideValue: "
147 << static_cast< typename NumericTraits< OutputPixelType >::PrintType >( m_OutsideValue )
148 << std::endl;
149 os << indent << "Number of iterations used to produce current output: "
150 << m_NumberOfIterationsUsed << std::endl;
151 os << indent << "FullyConnected: " << m_FullyConnected << std::endl;
152 }
153 } // end namespace itk
154 #endif
155