OTB  6.1.0
Orfeo Toolbox
otbFrostImageFilter.txx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2017 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 otbFrostImageFilter_txx
22 #define otbFrostImageFilter_txx
23 
24 #include "otbFrostImageFilter.h"
25 
26 #include "itkDataObject.h"
29 #include "itkImageRegionIterator.h"
31 #include "itkOffset.h"
32 #include "itkProgressReporter.h"
33 
34 namespace otb
35 {
36 
40 template <class TInputImage, class TOutputImage>
42 {
43  m_Radius.Fill(1);
44  m_Deramp = 2;
45 }
47 
48 template <class TInputImage, class TOutputImage>
50  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 = const_cast<TInputImage *>(this->GetInput());
57  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
58 
59  if (!inputPtr || !outputPtr)
60  {
61  return;
62  }
63 
64  // get a copy of the input requested region (should equal the output
65  // requested region)
66  typename TInputImage::RegionType inputRequestedRegion;
67  inputRequestedRegion = inputPtr->GetRequestedRegion();
68 
69  // pad the input requested region by the operator radius
70  inputRequestedRegion.PadByRadius(m_Radius);
71 
72  // crop the input requested region at the input's largest possible region
73  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
74  {
75  inputPtr->SetRequestedRegion(inputRequestedRegion);
76  return;
77  }
78  else
79  {
80  // Couldn't crop the region (requested region is outside the largest
81  // possible region). Throw an exception.
82 
83  // store what we tried to request (prior to trying to crop)
84  inputPtr->SetRequestedRegion(inputRequestedRegion);
85 
86  // build an exception
87  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
88  std::ostringstream msg;
89  msg << static_cast<const char *>(this->GetNameOfClass())
90  << "::GenerateInputRequestedRegion()";
91  e.SetLocation(msg.str().c_str());
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>
100  const OutputImageRegionType& outputRegionForThread,
101  itk::ThreadIdType threadId
102  )
103 {
104  unsigned int i;
109 
110  // Allocate output
111  typename OutputImageType::Pointer output = this->GetOutput();
112  typename InputImageType::ConstPointer input = this->GetInput();
113 
114  // Find the data-set boundary "faces"
117 
119  faceList = bC(input, outputRegionForThread, m_Radius);
120 
121  // support progress methods/callbacks
122  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
123 
124  InputRealType sum;
125  InputRealType sum2;
126 
127  double Mean, Variance;
128  double Alpha;
129  double NormFilter;
130  double FrostFilter;
131  double CoefFilter;
132  double dPixel;
133 
134  // Process each of the boundary faces. These are N-d regions which border
135  // the edge of the buffer.
136  for (fit = faceList.begin(); fit != faceList.end(); ++fit)
137  {
138  bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
139  unsigned int neighborhoodSize = bit.Size();
141  bit.OverrideBoundaryCondition(&nbc);
142 
143  bit.GoToBegin();
144  it.GoToBegin();
145 
146  while (!bit.IsAtEnd())
147  {
150 
151  for (i = 0; i < neighborhoodSize; ++i)
152  {
153  dPixel = static_cast<double>(bit.GetPixel(i));
154  sum += dPixel;
155  }
156  Mean = sum / static_cast<double>(neighborhoodSize);
157 
158  for (i = 0; i < neighborhoodSize; ++i)
159  {
160  dPixel = static_cast<double>(bit.GetPixel(i));
161  sum2 += (dPixel-Mean) * (dPixel-Mean);
162  }
163  Variance = sum2 / double(neighborhoodSize-1);
164 
165  const double epsilon = 0.0000000001;
166  if (vcl_abs(Mean) < epsilon)
167  {
169  }
170  else if (vcl_abs(Variance) < epsilon)
171  {
172  dPixel = Mean;
173  }
174  else
175  {
176  Alpha = m_Deramp * Variance / (Mean * Mean);
177 
178  NormFilter = 0.0;
179  FrostFilter = 0.0;
180 
181  const int rad_x = m_Radius[0];
182  const int rad_y = m_Radius[1];
183 
184  for (int x = -rad_x; x <= rad_x; ++x)
185  {
186  for (int y = -rad_y; y <= rad_y; ++y)
187  {
188  double Dist = vcl_sqrt(static_cast<double>(x * x + y * y));
189  off[0] = x;
190  off[1] = y;
191 
192  dPixel = static_cast<double>(bit.GetPixel(off));
193 
194  CoefFilter = vcl_exp(-Alpha * Dist);
195  NormFilter += CoefFilter;
196  FrostFilter += (CoefFilter * dPixel);
197  }
198  }
199 
200  dPixel = FrostFilter / NormFilter;
201  }
202 
203  it.Set(static_cast<OutputPixelType>(dPixel));
204 
205  ++bit;
206  ++it;
207  progress.CompletedPixel();
208 
209  }
210  }
211 }
212 
216 template <class TInputImage, class TOutput>
217 void
219 {
220  Superclass::PrintSelf(os, indent);
221  os << indent << "Radius: " << m_Radius << std::endl;
222 }
224 
225 } // end namespace otb
226 
227 #endif
virtual bool IsAtEnd() const
itk::NumericTraits< InputPixelType >::RealType InputRealType
void SetDataObject(DataObject *dobj)
virtual void SetDescription(const std::string &s)
virtual void SetLocation(const std::string &s)
void GenerateInputRequestedRegion() ITK_OVERRIDE
void Set(const PixelType &value) const
virtual void OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i)
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
virtual PixelType GetPixel(NeighborIndexType i, bool &IsInBounds) const
unsigned int ThreadIdType
OutputImageType::RegionType OutputImageRegionType
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) ITK_OVERRIDE