OTB  6.1.0
Orfeo Toolbox
otbPixelSuppressionByDirectionImageFilter.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 otbPixelSuppressionByDirectionImageFilter_txx
22 #define otbPixelSuppressionByDirectionImageFilter_txx
23 
25 
26 #include "itkDataObject.h"
29 #include "itkImageRegionIterator.h"
32 #include "itkOffset.h"
33 #include "itkProgressReporter.h"
34 #include "otbMath.h"
35 
36 namespace otb
37 {
38 
42 template <class TInputImage, class TOutputImage>
44 {
45 
46  m_Radius.Fill(1);
47  m_AngularBeam = static_cast<double>(0.);
48 
49 }
50 
51 template <class TInputImage, class TOutputImage>
52 void
55 {
56  this->SetInput(0, input);
57 }
58 
59 template <class TInputImage, class TOutputImage>
60 void
63 {
64  this->SetInput(1, input);
65 }
66 
67 template <class TInputImage, class TOutputImage>
68 const
72 {
73  if (this->GetNumberOfInputs() < 1)
74  {
75  return ITK_NULLPTR;
76  }
77 
78  return static_cast<const TInputImage *>
79  (this->GetInput(0));
80 }
81 
82 template <class TInputImage, class TOutputImage>
83 const
87 {
88  if (this->GetNumberOfInputs() < 1)
89  {
90  return ITK_NULLPTR;
91  }
92 
93  return static_cast<const TInputImage *>
94  (this->GetInput(1));
95 }
96 
97 template <class TInputImage, class TOutputImage>
99  itk::InvalidRequestedRegionError)
100  {
101  // call the superclass' implementation of this method
102  Superclass::GenerateInputRequestedRegion();
103 
104  // get pointers to the input and output
105  typename Superclass::InputImagePointer inputPtr = const_cast<TInputImage *>(this->GetInputImageDirection());
106  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
107 
108  if (!inputPtr || !outputPtr)
109  {
110  return;
111  }
112 
113  // get a copy of the input requested region (should equal the output
114  // requested region)
115  typename TInputImage::RegionType inputRequestedRegion;
116  inputRequestedRegion = inputPtr->GetRequestedRegion();
117 
118  // pad the input requested region by the operator radius
119  inputRequestedRegion.PadByRadius(m_Radius);
120 
121  // crop the input requested region at the input's largest possible region
122  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
123  {
124  inputPtr->SetRequestedRegion(inputRequestedRegion);
125  return;
126  }
127  else
128  {
129  // Couldn't crop the region (requested region is outside the largest
130  // possible region). Throw an exception.
131 
132  // store what we tried to request (prior to trying to crop)
133  inputPtr->SetRequestedRegion(inputRequestedRegion);
134 
135  // build an exception
136  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
137  std::ostringstream msg;
138  msg << static_cast<const char *>(this->GetNameOfClass())
139  << "::GenerateInputRequestedRegion()";
140  e.SetLocation(msg.str().c_str());
141  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
142  e.SetDataObject(inputPtr);
143  throw e;
144  }
145  }
146 
147 template<class TInputImage, class TOutputImage>
149  const OutputImageRegionType& outputRegionForThread,
150  itk::ThreadIdType threadId
151  )
152 {
153 
155  const InputPixelType cvalue = 255;
156  cbc.SetConstant(cvalue);
157 
161 
162  // Allocate output
163  typename OutputImageType::Pointer output = this->GetOutput();
164  typename InputImageType::ConstPointer input = this->GetInputImage();
165  typename InputImageType::ConstPointer inputDirection = this->GetInputImageDirection();
166 
167  // Find the data-set boundary "faces"
170 
172  faceList = bC(inputDirection, outputRegionForThread, m_Radius);
173 
174  // support progress methods/callbacks
175  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
176 
177  //typename TInputImage::IndexType bitIndex;
178 
179  //---------------------------------------------------------------------------
180 
181  InputPixelType PixelValue;
182 
183  // Location of the central pixel in the input image
184 // int Xc, Yc;
185 
186  // Pixel location in the system axis of the region
187  int x, y;
188 
189  // Pixel location in the system axis of the region after rotation of theta
190  // where theta is the direction of the cantral pixel
191 
192  // Pixel Direction
193  double ThetaXcYc, Thetaxtyt;
194 
195  //---------------------------------------------------------------------------
196 
197  // Process each of the boundary faces. These are N-d regions which border
198  // the edge of the buffer.
199  for (fit = faceList.begin(); fit != faceList.end(); ++fit)
200  {
201  bit = itk::ConstNeighborhoodIterator<InputImageType>(m_Radius, inputDirection, *fit);
202 
204  itout = itk::ImageRegionIterator<OutputImageType>(output, *fit);
205 
206  bit.OverrideBoundaryCondition(&cbc);
207  bit.GoToBegin();
208 
209  while (!bit.IsAtEnd())
210  {
211 
212  /*// Location of the central pixel of the region in the input image
213  bitIndex = bit.GetIndex();
214 
215  Xc = bitIndex[0];
216  Yc = bitIndex[1];
217  */
218  // Get Pixel Direction from the image of directions
219  ThetaXcYc = static_cast<double>(bit.GetCenterPixel());
220 
221  // Pixel intensity in the input image
222  PixelValue = itin.Get();
223 
224  bool IsLine = false;
225 
227  // Loop on the region
228  for (unsigned int i = 0; i < 2 * m_Radius[0] + 1; ++i)
229  for (unsigned int j = 0; j < 2 * m_Radius[1] + 1; ++j)
230  {
231 
232  off[0] = i - m_Radius[0];
233  off[1] = j - m_Radius[1];
234 
235  x = off[0];
236  y = off[1];
237 
238  // No calculation on the central pixel
239  if ((x == 0) && (y == 0)) continue;
240 
241  Thetaxtyt = vcl_atan2(static_cast<double>(y), static_cast<double>(x)); //result is [-PI, PI]
242  while (Thetaxtyt < 0)
243  Thetaxtyt = CONST_PI + Thetaxtyt; // Theta is now [0, PI] as is
244  // the result of detectors
245  while (Thetaxtyt > CONST_PI_2)
246  Thetaxtyt = Thetaxtyt - CONST_PI; // Theta is now [-PI/2, PI/2]
247 
248  if ((vcl_abs(vcl_cos(Thetaxtyt - ThetaXcYc)) >= vcl_cos(m_AngularBeam)) // this
249  // pixel
250  // is
251  // in
252  // the
253  // angular beam
254  && (vcl_abs(vcl_cos(bit.GetPixel(off) - ThetaXcYc)) >= vcl_cos(m_AngularBeam))) //and
255  //its
256  //direction
257  //is
258  //also
259  //in
260  //the beam
261  {
262  IsLine = true;
263  continue;
264  }
265 
266  }
267 
268  // end of the loop on the pixels of the region
269 
270  // Assignment of this value to the output pixel
271  if (IsLine == true)
272  {
273  itout.Set(static_cast<OutputPixelType>(PixelValue));
274  }
275  else
276  {
277  itout.Set(static_cast<OutputPixelType>(0.));
278  }
279 
280  ++bit;
281  ++itin;
282  ++itout;
283  progress.CompletedPixel();
284 
285  }
286 
287  }
288 }
289 
293 template <class TInputImage, class TOutput>
294 void
296 {
297  Superclass::PrintSelf(os, indent);
298  os << indent << "Radius: " << m_Radius << std::endl;
299 }
301 
302 } // end namespace otb
303 
304 #endif
const double CONST_PI
Definition: otbMath.h:48
virtual bool IsAtEnd() const
void SetConstant(const OutputPixelType &c)
void SetDataObject(DataObject *dobj)
const double CONST_PI_2
Definition: otbMath.h:49
virtual void SetDescription(const std::string &s)
virtual void SetLocation(const std::string &s)
virtual void OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i)
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) ITK_OVERRIDE
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
PixelType GetCenterPixel() const
virtual PixelType GetPixel(NeighborIndexType i, bool &IsInBounds) const
TInputImage InputImageType
unsigned int ThreadIdType
OutputImageType::RegionType OutputImageRegionType