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 itkUnsharpMaskImageFilter_hxx
19 #define itkUnsharpMaskImageFilter_hxx
20 
21 #include "itkUnsharpMaskImageFilter.h"
22 #include "itkBinaryGeneratorImageFilter.h"
23 #include "itkNumericTraits.h"
24 #include "itkProgressAccumulator.h"
25 
26 namespace itk
27 {
28 
29 template< typename TInputImage, typename TOutputImage, typename TInternalPrecision >
30 UnsharpMaskImageFilter< TInputImage, TOutputImage, TInternalPrecision >
UnsharpMaskImageFilter()31 ::UnsharpMaskImageFilter()
32   :m_Amount(0.5),
33   m_Threshold(0),
34   m_Clamp(NumericTraits<OutputPixelType>::IsInteger)
35   // clamping is on for integral types, and off for floating types
36   // this gives intuitive behavior for integral types
37   // and skips min/max checks for floating types
38 {
39   m_Sigmas.Fill(1.0);
40 }
41 
42 template< typename TInputImage, typename TOutputImage, typename TInternalPrecision >
43 void
44 UnsharpMaskImageFilter< TInputImage, TOutputImage, TInternalPrecision >
GenerateInputRequestedRegion()45 ::GenerateInputRequestedRegion()
46 {
47   // call the superclass' implementation of this method. this should
48   // copy the output requested region to the input requested region
49   Superclass::GenerateInputRequestedRegion();
50 
51   // This filter needs all of the input
52   InputImagePointer image = const_cast<InputImageType *>(this->GetInput());
53   if ( image )
54     {
55     image->SetRequestedRegion(this->GetInput()->GetLargestPossibleRegion());
56     }
57 }
58 
59 
60 template< typename TInputImage, typename TOutputImage, typename TInternalPrecision >
61 void
62 UnsharpMaskImageFilter< TInputImage, TOutputImage, TInternalPrecision >
VerifyPreconditions()63 ::VerifyPreconditions() ITKv5_CONST
64 {
65   Superclass::VerifyPreconditions();
66   if (m_Threshold < 0.0)
67     {
68     itkExceptionMacro(<< "Threshold must be non-negative!");
69     }
70 }
71 
72 
73 template< typename TInputImage, typename TOutputImage, typename TInternalPrecision >
74 void
75 UnsharpMaskImageFilter< TInputImage, TOutputImage, TInternalPrecision >
GenerateData()76 ::GenerateData()
77 {
78   typename TInputImage::Pointer input = TInputImage::New();
79   input->Graft(const_cast<TInputImage *>(this->GetInput()));
80   typename GaussianType::Pointer gaussianF = GaussianType::New();
81   gaussianF->SetInput(input);
82   gaussianF->SetSigmaArray(m_Sigmas);
83   gaussianF->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
84 
85   using USMType = UnsharpMaskingFunctor< InputPixelType,
86                                          TInternalPrecision,
87                                          OutputPixelType >;
88   using BinaryFunctorType = BinaryGeneratorImageFilter< TInputImage,
89                                                         typename GaussianType::OutputImageType,
90                                                         TOutputImage >;
91   typename BinaryFunctorType::Pointer functorF = BinaryFunctorType::New();
92   functorF->SetInput1(this->GetInput());
93   functorF->SetInput2(gaussianF->GetOutput());
94   USMType usmT(m_Amount, m_Threshold, m_Clamp);
95   functorF->SetFunctor(usmT);
96   functorF->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
97 
98   ProgressAccumulator::Pointer progress = ProgressAccumulator::New();
99   progress->SetMiniPipelineFilter(this);
100   progress->RegisterInternalFilter(gaussianF, 0.7);
101   progress->RegisterInternalFilter(functorF, 0.3);
102 
103   functorF->GraftOutput(this->GetOutput());
104   functorF->Update();
105   this->GraftOutput(functorF->GetOutput());
106 }
107 
108 
109 template< typename TInputImage, typename TOutputImage, typename TInternalPrecision >
110 void
111 UnsharpMaskImageFilter< TInputImage, TOutputImage, TInternalPrecision >
PrintSelf(std::ostream & os,Indent indent) const112 ::PrintSelf(std::ostream & os, Indent indent) const
113 {
114   Superclass::PrintSelf(os, indent);
115   os << indent << "Sigmas: " << m_Sigmas << std::endl;
116   os << indent << "Amount: " << m_Amount << std::endl;
117   os << indent << "Threshold: " << m_Threshold << std::endl;
118   os << indent << "Clamp: " << m_Clamp << std::endl;
119 }
120 
121 } // end namespace itk
122 
123 #endif
124