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