OTB  6.7.0
Orfeo Toolbox
otbApplyGainFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 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 otbApplyGainFilter_hxx
22 #define otbApplyGainFilter_hxx
23 
24 #include "otbApplyGainFilter.h"
25 #include "itkImageRegionIterator.h"
27 #include "itkContinuousIndex.h"
28 
29 #include <limits>
30 
31 namespace otb
32 {
33 template <class TInputImage , class TLut , class TOutputImage >
34 ApplyGainFilter < TInputImage , TLut , TOutputImage >
36 {
37  this->SetNumberOfRequiredInputs(2);
38  m_Min = std::numeric_limits< InputPixelType >::quiet_NaN();
39  m_Max = std::numeric_limits< InputPixelType >::quiet_NaN();
40  m_NoData = std::numeric_limits< InputPixelType >::quiet_NaN();
41  m_NoDataFlag = false;
42  m_ThumbSizeFromSpacing = true;
43  m_Step = -1;
44 }
45 
46 template <class TInputImage , class TLut , class TOutputImage >
48 ::SetInputImage(const InputImageType * input)
49 {
50  // Process object is not const-correct so the const casting is required.
51  this->SetNthInput( 0 , const_cast<InputImageType *>( input ) );
52 }
53 
54 template <class TInputImage , class TLut , class TOutputImage >
56 ::GetInputImage() const
57 {
58  return static_cast< const InputImageType * >
59  ( this->itk::ProcessObject::GetInput(0) );
60 }
61 
62 template <class TInputImage , class TLut , class TOutputImage >
64 ::SetInputLut(const LutType * lut)
65 {
66  // Process object is not const-correct so the const casting is required.
67  this->SetNthInput( 1 , const_cast<LutType *>( lut ) );
68 }
69 
70 template <class TInputImage , class TLut , class TOutputImage >
72 ::GetInputLut() const
73 {
74  return static_cast< const LutType * >
75  ( this->itk::ProcessObject::GetInput(1) );
76 }
77 
78 template <class TInputImage , class TLut , class TOutputImage >
80 ::GenerateInputRequestedRegion()
81 {
82  typename InputImageType::Pointer input (
83  const_cast<InputImageType *>( GetInputImage() ) );
84  typename LutType::Pointer lut ( const_cast<LutType *>( GetInputLut() ) );
85  typename OutputImageType::Pointer output ( this->GetOutput() );
86 
87  lut->SetRequestedRegion( lut->GetLargestPossibleRegion() );
88  input->SetRequestedRegion( output->GetRequestedRegion() );
89  if ( input->GetRequestedRegion().GetNumberOfPixels() == 0 )
90  {
91  input->SetRequestedRegionToLargestPossibleRegion();
92  }
93 }
94 
95 template <class TInputImage , class TLut , class TOutputImage >
97 ::BeforeThreadedGenerateData()
98 {
99  typename LutType::ConstPointer lut ( GetInputLut() );
100  typename InputImageType::ConstPointer input ( GetInputImage() );
101  if ( m_ThumbSizeFromSpacing )
102  {
103  m_ThumbSize[0] = std::round( lut->GetSignedSpacing()[0]
104  / input->GetSignedSpacing()[0] );
105  m_ThumbSize[1] = std::round( lut->GetSignedSpacing()[1]
106  / input->GetSignedSpacing()[1] );
107  }
108  m_Step = static_cast<double>( m_Max - m_Min ) \
109  / static_cast<double>( lut->GetVectorLength() - 1 );
110 }
111 
112 template <class TInputImage , class TLut , class TOutputImage >
114 ::ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread ,
115  itk::ThreadIdType itkNotUsed(threadId) )
116 {
117  assert( m_Step > 0 );
118  // TODO error
119  // support progress methods/callbacks
120  // itk::ProgressReporter progress(this , threadId ,
121  // outputRegionForThread.GetNumberOfPixels() );
122 
123  typename InputImageType::ConstPointer input ( GetInputImage() );
124  typename LutType::ConstPointer lut ( GetInputLut() );
125  typename OutputImageType::Pointer output ( this->GetOutput() );
126  typename InputImageType::RegionType inputRegionForThread(
127  outputRegionForThread );
128 
129 
131  inputRegionForThread );
133  outputRegionForThread );
134 
135  unsigned int pixelLutValue(0);
136  double gain(0.0) , newValue(0);
137  InputPixelType currentPixel(0);
138 
139  for( it.GoToBegin() , oit.GoToBegin() ; !oit.IsAtEnd() || !it.IsAtEnd() ;
140  ++oit , ++it )
141  {
142  currentPixel = it.Get();
143  newValue = static_cast< double > ( currentPixel );
144  if( !( ( currentPixel == m_NoData && m_NoDataFlag ) ||
145  currentPixel > m_Max || currentPixel < m_Min ) )
146  {
147  pixelLutValue = static_cast< unsigned int > (
148  std::round( ( currentPixel - m_Min ) / m_Step ) );
149  gain = InterpolateGain( lut , pixelLutValue , it.GetIndex() );
150  newValue *= gain;
151  }
152  oit.Set( static_cast<OutputPixelType>( newValue ) );
153  }
154  assert ( oit.IsAtEnd() && it.IsAtEnd() );
155 }
156 
157 template <class TInputImage , class TLut , class TOutputImage >
159 ::InterpolateGain( typename LutType::ConstPointer gridLut,
160  unsigned int pixelLutValue ,
161  typename InputImageType::IndexType index)
162 {
163  typename InputImageType::PointType pixelPoint;
164  typename itk::ContinuousIndex< double , 2 > pixelIndex;
165  typename InputImageType::ConstPointer input ( GetInputImage() );
166  typename LutType::ConstPointer lut ( GetInputLut() );
167  input->TransformIndexToPhysicalPoint( index , pixelPoint );
168  lut->TransformPhysicalPointToContinuousIndex( pixelPoint , pixelIndex );
169  std::vector< typename LutType::IndexType > neighbors(4);
170  neighbors[0][0] = std::floor(pixelIndex[0]) ;
171  neighbors[0][1] = std::floor(pixelIndex[1]) ;
172  neighbors[1][0] = neighbors[0][0] + 1 ;
173  neighbors[1][1] = neighbors[0][1] ;
174  neighbors[2][0] = neighbors[0][0] ;
175  neighbors[2][1] = neighbors[0][1] + 1 ;
176  neighbors[3][0] = neighbors[0][0] + 1 ;
177  neighbors[3][1] = neighbors[0][1] + 1 ;
178  float gain(0.f) , w(0.f) , wtm(0.f);
179  typename LutType::IndexType maxIndex;
180  maxIndex[0] = lut->GetLargestPossibleRegion().GetSize()[0];
181  maxIndex[1] = lut->GetLargestPossibleRegion().GetSize()[1];
182  for ( auto i : neighbors )
183  {
184  if ( i[0] < 0 || i[1] < 0 || i[0] >= maxIndex[0] || i[1] >= maxIndex[1] )
185  continue;
186  if ( gridLut->GetPixel(i)[pixelLutValue] == -1 )
187  continue;
188  wtm = ( 1 - std::abs( pixelIndex[0] - i[0] ) )
189  * ( 1 - std::abs( pixelIndex[1] - i[1] ) );
190  gain += gridLut->GetPixel(i)[pixelLutValue] * wtm;
191  w += wtm;
192  }
193  if ( w == 0 )
194  {
195  w = 1;
196  gain = 1;
197  }
198 
199  return gain/w;
200 }
201 
205 template <class TInputImage , class TLut , class TOutputImage >
207 ::PrintSelf(std::ostream& os, itk::Indent indent) const
208 {
209  Superclass::PrintSelf(os, indent);
210  os << indent << "Is no data activated : " << m_NoDataFlag << std::endl;
211  os << indent << "No Data : " << m_NoData << std::endl;
212  os << indent << "Minimum : " << m_Min << std::endl;
213  os << indent << "Maximum : " << m_Max << std::endl;
214  os << indent << "Step : " << m_Step << std::endl;
215  os << indent << "Look up table size : " << m_LutSize << std::endl;
216  os << indent << "Is ThumbSize from sapcing is activated : "
217  << m_NoDataFlag << std::endl;
218  os << indent << "Thumbnail size : " << m_ThumbSize << std::endl;
219 }
221 
222 
223 } // End namespace otb
224 
225 #endif
PixelType Get(void) const
void Set(const PixelType &value) const
Apply gain on the input image with a bilineare interpolation.
const IndexType & GetIndex() const
itk::Index< Monteverdi_DIMENSION > IndexType
Definition: mvdTypes.h:133
TInputImage InputImageType
unsigned int ThreadIdType
DataObject * GetInput(const DataObjectIdentifierType &key)
OutputImageType::RegionType OutputImageRegionType
InputImageType::InternalPixelType InputPixelType
bool IsAtEnd(void) const
VectorImageType::PointType PointType
Definition: mvdTypes.h:189