Orfeo ToolBox  4.2
Orfeo ToolBox is not a black box
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"
24 #include "itkMacro.h"
27 #include "itkImageRegionIterator.h"
30 #include "itkOffset.h"
31 #include "itkProgressReporter.h"
32 
33 namespace otb
34 {
35 
39 template <class TInputImage, class TOutputImage>
41 {
42  m_Radius.Fill(1);
43  m_Deramp = 0.1;
44 }
45 
46 template <class TInputImage, class TOutputImage>
48  itk::InvalidRequestedRegionError)
49  {
50  // call the superclass' implementation of this method
51  Superclass::GenerateInputRequestedRegion();
52 
53  // get pointers to the input and output
54  typename Superclass::InputImagePointer inputPtr = const_cast<TInputImage *>(this->GetInput());
55  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
56 
57  if (!inputPtr || !outputPtr)
58  {
59  return;
60  }
61 
62  // get a copy of the input requested region (should equal the output
63  // requested region)
64  typename TInputImage::RegionType inputRequestedRegion;
65  inputRequestedRegion = inputPtr->GetRequestedRegion();
66 
67  // pad the input requested region by the operator radius
68  inputRequestedRegion.PadByRadius(m_Radius);
69 
70  // crop the input requested region at the input's largest possible region
71  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
72  {
73  inputPtr->SetRequestedRegion(inputRequestedRegion);
74  return;
75  }
76  else
77  {
78  // Couldn't crop the region (requested region is outside the largest
79  // possible region). Throw an exception.
80 
81  // store what we tried to request (prior to trying to crop)
82  inputPtr->SetRequestedRegion(inputRequestedRegion);
83 
84  // build an exception
85  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
86  std::ostringstream msg;
87  msg << static_cast<const char *>(this->GetNameOfClass())
88  << "::GenerateInputRequestedRegion()";
89  e.SetLocation(msg.str().c_str());
90  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
91  e.SetDataObject(inputPtr);
92  throw e;
93  }
94  }
95 
96 template<class TInputImage, class TOutputImage>
98  const OutputImageRegionType& outputRegionForThread,
99  itk::ThreadIdType threadId
100  )
101 {
102  unsigned int i;
107 
108  // Allocate output
109  typename OutputImageType::Pointer output = this->GetOutput();
110  typename InputImageType::ConstPointer input = this->GetInput();
111 
112  // Find the data-set boundary "faces"
115 
117  faceList = bC(input, outputRegionForThread, m_Radius);
118 
119  // support progress methods/callbacks
120  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
121 
122  InputRealType sum;
123  InputRealType sum2;
124 
125  double Mean, Variance;
126  double Alpha;
127  double NormFilter;
128  double FrostFilter;
129  double CoefFilter;
130  double dPixel;
131 
132  // Process each of the boundary faces. These are N-d regions which border
133  // the edge of the buffer.
134  for (fit = faceList.begin(); fit != faceList.end(); ++fit)
135  {
136  bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, input, *fit);
137  unsigned int neighborhoodSize = bit.Size();
139  bit.OverrideBoundaryCondition(&nbc);
140  bit.GoToBegin();
141 
142  while (!bit.IsAtEnd())
143  {
146  for (i = 0; i < neighborhoodSize; ++i)
147  {
148  dPixel = static_cast<double>(bit.GetPixel(i));
149  sum += dPixel;
150  sum2 += dPixel * dPixel;
151  }
152  Mean = sum / double(neighborhoodSize);
153  Variance = sum2 / double(neighborhoodSize) - Mean * Mean;
154 
155  if (Mean == 0)
156  {
157  Alpha = 0;
158  }
159  else
160  {
161  Alpha = m_Deramp * Variance / (Mean * Mean);
162  }
163 
164  NormFilter = 0.0;
165  FrostFilter = 0.0;
166 
167  const int rad_x = m_Radius[0];
168  const int rad_y = m_Radius[1];
169 
170  for (int x = -rad_x; x <= rad_x; ++x)
171  {
172  for (int y = -rad_y; y <= rad_y; ++y)
173  {
174  double Dist = vcl_sqrt(static_cast<double>(x * x + y * y));
175  off[0] = x;
176  off[1] = y;
177 
178  dPixel = static_cast<double>(bit.GetPixel(off));
179 
180  CoefFilter = Alpha * vcl_exp(-Alpha * Dist);
181  NormFilter += CoefFilter;
182  FrostFilter += (CoefFilter * dPixel);
183  }
184  }
185 
186  if (NormFilter == 0.) dPixel = 0.;
187  else dPixel = FrostFilter / NormFilter;
188 
189  it.Set(static_cast<OutputPixelType>(dPixel));
190 
191  ++bit;
192  ++it;
193  progress.CompletedPixel();
194 
195  }
196  }
197 }
198 
202 template <class TInputImage, class TOutput>
203 void
205 {
206  Superclass::PrintSelf(os, indent);
207  os << indent << "Radius: " << m_Radius << std::endl;
208 }
209 
210 } // end namespace otb
211 
212 #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()
OutputImageType::RegionType OutputImageRegionType
NeighborIndexType Size() const
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId)
virtual PixelType GetPixel(NeighborIndexType i, bool &IsInBounds) const
unsigned int ThreadIdType
Superclass::OffsetType OffsetType