OTB  6.7.0
Orfeo Toolbox
otbConvolutionImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbConvolutionImageFilter_hxx
22 #define otbConvolutionImageFilter_hxx
24 
26 #include "itkImageRegionIterator.h"
27 #include "itkOffset.h"
28 #include "itkProgressReporter.h"
30 
31 #include "otbMacro.h"
32 
33 
34 namespace otb
35 {
36 
37 template <class TInputImage, class TOutputImage, class TBoundaryCondition, class TFilterPrecision>
40 {
41  m_Radius.Fill(1);
42  m_Filter.SetSize(3 * 3);
43  m_Filter.Fill(1);
44  m_NormalizeFilter = false;
45 }
46 
47 template <class TInputImage, class TOutputImage, class TBoundaryCondition, class TFilterPrecision>
48 void
50 ::GenerateInputRequestedRegion() throw (itk::InvalidRequestedRegionError)
51  {
52  // call the superclass' implementation of this method
53  Superclass::GenerateInputRequestedRegion();
54 
55  // get pointers to the input and output
56  typename Superclass::InputImagePointer inputPtr =
57  const_cast<TInputImage *>(this->GetInput());
58  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
59 
60  if (!inputPtr || !outputPtr)
61  {
62  return;
63  }
64 
65  // get a copy of the input requested region (should equal the output
66  // requested region)
67  typename TInputImage::RegionType inputRequestedRegion;
68  inputRequestedRegion = inputPtr->GetRequestedRegion();
69 
70  // pad the input requested region by the operator radius
71  inputRequestedRegion.PadByRadius(m_Radius);
72  otbMsgDevMacro(<< "Padding by " << m_Radius);
73  otbMsgDevMacro(<< "Region is now " << inputRequestedRegion.GetIndex() << ", " << inputRequestedRegion.GetSize());
74 
75  // crop the input requested region at the input's largest possible region
76  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
77  {
78  inputPtr->SetRequestedRegion(inputRequestedRegion);
79  return;
80  }
81  else
82  {
83  // Couldn't crop the region (requested region is outside the largest
84  // possible region). Throw an exception.
85 
86  // store what we tried to request (prior to trying to crop)
87  inputPtr->SetRequestedRegion(inputRequestedRegion);
88 
89  // build an exception
90  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
91  e.SetLocation(ITK_LOCATION);
92  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
93  e.SetDataObject(inputPtr);
94  throw e;
95  }
96  }
97 
98 template<class TInputImage, class TOutputImage, class TBoundaryCondition, class TFilterPrecision>
99 void
101 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
102  itk::ThreadIdType threadId)
103 {
104  // Allocate output
105  typename OutputImageType::Pointer output = this->GetOutput();
106  typename InputImageType::ConstPointer input = this->GetInput();
107 
108  // support progress methods/callbacks
109  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
110 
112 
113  InputImageRegionType inputRegionForThread;
114  this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
115 
116  itk::ConstNeighborhoodIterator<InputImageType, BoundaryConditionType> inputIt(m_Radius, input, inputRegionForThread);
117  itk::ImageRegionIterator<OutputImageType> outputIt(output, outputRegionForThread);
118 
119  inputIt.GoToBegin();
120  const unsigned int neighborhoodSize = inputIt.Size();
121 
122 
123  // Compute the norm of the filter
124  if (m_NormalizeFilter)
125  {
127  for (unsigned int i = 0; i < neighborhoodSize; ++i)
128  {
129  norm += static_cast<InputRealType>(std::abs(m_Filter(i)));
130  }
131  const double norm_double = 1. / static_cast<double>(std::abs(norm));
132 
133  while (!inputIt.IsAtEnd())
134  {
136 
137  for (unsigned int i = 0; i < neighborhoodSize; ++i)
138  {
139  sum += static_cast<InputRealType>(inputIt.GetPixel(i) * m_Filter(i));
140  }
141 
142  // get the mean value
143  outputIt.Set(static_cast<OutputPixelType>(sum * norm_double));
144 
145  ++inputIt;
146  ++outputIt;
147  progress.CompletedPixel();
148  }
149  }
150  else
151  {
152  while (!inputIt.IsAtEnd())
153  {
155 
156  for (unsigned int i = 0; i < neighborhoodSize; ++i)
157  {
158  sum += static_cast<InputRealType>(inputIt.GetPixel(i) * m_Filter(i));
159  }
160 
161  outputIt.Set(static_cast<OutputPixelType>(sum));
162 
163  ++inputIt;
164  ++outputIt;
165  progress.CompletedPixel();
166  }
167  }
168 }
169 
173 template <class TInputImage, class TOutput, class TBoundaryCondition, class TFilterPrecision>
174 void
176 ::PrintSelf(std::ostream& os, itk::Indent indent) const
177 {
178  Superclass::PrintSelf(os, indent);
179  os << indent << "Radius: " << m_Radius << '\n';
181 
182 }
183 
184 } // end namespace otb
185 
186 #endif
virtual bool IsAtEnd() const
void SetDataObject(DataObject *dobj)
void PrintSelf(std::ostream &os, itk::Indent indent) const override
virtual void SetDescription(const std::string &s)
virtual void SetLocation(const std::string &s)
void Set(const PixelType &value) const
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
itk::NumericTraits< InputPixelType >::RealType InputRealType
InputImageType::RegionType InputImageRegionType
virtual PixelType GetPixel(NeighborIndexType i, bool &IsInBounds) const
unsigned int ThreadIdType
OutputImageType::RegionType OutputImageRegionType
#define otbMsgDevMacro(x)
Definition: otbMacro.h:66