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