OTB  5.5.0
Orfeo Toolbox
otbFrostImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 #ifndef __otbFrostImageFilter_txx
19 #define __otbFrostImageFilter_txx
20 
21 #include "otbFrostImageFilter.h"
22 
23 #include "itkDataObject.h"
26 #include "itkImageRegionIterator.h"
28 #include "itkOffset.h"
29 #include "itkProgressReporter.h"
30 
31 namespace otb
32 {
33 
37 template <class TInputImage, class TOutputImage>
39 {
40  m_Radius.Fill(1);
41  m_Deramp = 2;
42 }
44 
45 template <class TInputImage, class TOutputImage>
47  itk::InvalidRequestedRegionError)
48  {
49  // call the superclass' implementation of this method
50  Superclass::GenerateInputRequestedRegion();
51 
52  // get pointers to the input and output
53  typename Superclass::InputImagePointer inputPtr = const_cast<TInputImage *>(this->GetInput());
54  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
55 
56  if (!inputPtr || !outputPtr)
57  {
58  return;
59  }
60 
61  // get a copy of the input requested region (should equal the output
62  // requested region)
63  typename TInputImage::RegionType inputRequestedRegion;
64  inputRequestedRegion = inputPtr->GetRequestedRegion();
65 
66  // pad the input requested region by the operator radius
67  inputRequestedRegion.PadByRadius(m_Radius);
68 
69  // crop the input requested region at the input's largest possible region
70  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
71  {
72  inputPtr->SetRequestedRegion(inputRequestedRegion);
73  return;
74  }
75  else
76  {
77  // Couldn't crop the region (requested region is outside the largest
78  // possible region). Throw an exception.
79 
80  // store what we tried to request (prior to trying to crop)
81  inputPtr->SetRequestedRegion(inputRequestedRegion);
82 
83  // build an exception
84  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
85  std::ostringstream msg;
86  msg << static_cast<const char *>(this->GetNameOfClass())
87  << "::GenerateInputRequestedRegion()";
88  e.SetLocation(msg.str().c_str());
89  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
90  e.SetDataObject(inputPtr);
91  throw e;
92  }
93  }
94 
95 template<class TInputImage, class TOutputImage>
97  const OutputImageRegionType& outputRegionForThread,
98  itk::ThreadIdType threadId
99  )
100 {
101  unsigned int i;
106 
107  // Allocate output
108  typename OutputImageType::Pointer output = this->GetOutput();
109  typename InputImageType::ConstPointer input = this->GetInput();
110 
111  // Find the data-set boundary "faces"
114 
116  faceList = bC(input, outputRegionForThread, m_Radius);
117 
118  // support progress methods/callbacks
119  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
120 
121  InputRealType sum;
122  InputRealType sum2;
123 
124  double Mean, Variance;
125  double Alpha;
126  double NormFilter;
127  double FrostFilter;
128  double CoefFilter;
129  double dPixel;
130 
131  // Process each of the boundary faces. These are N-d regions which border
132  // the edge of the buffer.
133  for (fit = faceList.begin(); fit != faceList.end(); ++fit)
134  {
135  bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
136  unsigned int neighborhoodSize = bit.Size();
138  bit.OverrideBoundaryCondition(&nbc);
139 
140  bit.GoToBegin();
141  it.GoToBegin();
142 
143  while (!bit.IsAtEnd())
144  {
147 
148  for (i = 0; i < neighborhoodSize; ++i)
149  {
150  dPixel = static_cast<double>(bit.GetPixel(i));
151  sum += dPixel;
152  }
153  Mean = sum / static_cast<double>(neighborhoodSize);
154 
155  for (i = 0; i < neighborhoodSize; ++i)
156  {
157  dPixel = static_cast<double>(bit.GetPixel(i));
158  sum2 += (dPixel-Mean) * (dPixel-Mean);
159  }
160  Variance = sum2 / double(neighborhoodSize-1);
161 
162  const double epsilon = 0.0000000001;
163  if (vcl_abs(Mean) < epsilon)
164  {
166  }
167  else if (vcl_abs(Variance) < epsilon)
168  {
169  dPixel = Mean;
170  }
171  else
172  {
173  Alpha = m_Deramp * Variance / (Mean * Mean);
174 
175  NormFilter = 0.0;
176  FrostFilter = 0.0;
177 
178  const int rad_x = m_Radius[0];
179  const int rad_y = m_Radius[1];
180 
181  for (int x = -rad_x; x <= rad_x; ++x)
182  {
183  for (int y = -rad_y; y <= rad_y; ++y)
184  {
185  double Dist = vcl_sqrt(static_cast<double>(x * x + y * y));
186  off[0] = x;
187  off[1] = y;
188 
189  dPixel = static_cast<double>(bit.GetPixel(off));
190 
191  CoefFilter = vcl_exp(-Alpha * Dist);
192  NormFilter += CoefFilter;
193  FrostFilter += (CoefFilter * dPixel);
194  }
195  }
196 
197  dPixel = FrostFilter / NormFilter;
198  }
199 
200  it.Set(static_cast<OutputPixelType>(dPixel));
201 
202  ++bit;
203  ++it;
204  progress.CompletedPixel();
205 
206  }
207  }
208 }
209 
213 template <class TInputImage, class TOutput>
214 void
216 {
217  Superclass::PrintSelf(os, indent);
218  os << indent << "Radius: " << m_Radius << std::endl;
219 }
221 
222 } // end namespace otb
223 
224 #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 Set(const PixelType &value) const
void PrintSelf(std::ostream &os, itk::Indent indent) const
virtual void OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i)
virtual void GenerateInputRequestedRegion()
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId)
virtual PixelType GetPixel(NeighborIndexType i, bool &IsInBounds) const
unsigned int ThreadIdType
OutputImageType::RegionType OutputImageRegionType