OTB  9.0.0
Orfeo Toolbox
otbNeighborhoodMajorityVotingImageFilter.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 otbNeighborhoodMajorityVotingImageFilter_hxx
22 #define otbNeighborhoodMajorityVotingImageFilter_hxx
23 
24 // First make sure that the configuration is available.
25 // This line can be removed once the optimized versions
26 // gets integrated into the main directories.
27 
29 #include "itkDefaultConvertPixelTraits.h"
30 #include "itkMetaDataObject.h"
31 #include "otbMetaDataKey.h"
32 #include "otbNoDataHelper.h"
33 
34 namespace otb
35 {
39 template <class TInputImage, class TOutputImage, class TKernel>
41 {
42  this->SetLabelForNoDataPixels(itk::NumericTraits<PixelType>::NonpositiveMin()); // m_LabelForNoDataPixels = 0
43  this->SetLabelForUndecidedPixels(itk::NumericTraits<PixelType>::NonpositiveMin()); // m_LabelForUndecidedPixels = 0
44  this->SetKeepOriginalLabelBool(true); // m_KeepOriginalLabelBool = true
45  this->SetOnlyIsolatedPixels(false); // process all pixels
46  this->SetIsolatedThreshold(1);
47 }
49 
50 
51 template <class TInputImage, class TOutputImage, class TKernel>
54  const KernelIteratorType kernelEnd)
55 {
56  const PixelType centerPixel = nit.GetCenterPixel();
57  if (centerPixel == m_LabelForNoDataPixels)
58  {
59  return m_LabelForNoDataPixels;
60  }
61  else
62  {
63  // Get a histogram of label frequencies where the 2 highest are at the beginning and sorted
64  const HistoSummary histoSummary = this->ComputeNeighborhoodHistogramSummary(nit, kernelBegin, kernelEnd);
65  if (m_OnlyIsolatedPixels && histoSummary.freqCenterLabel > m_IsolatedThreshold)
66  {
67  // If we want to filter only isolated pixels, keep the label if
68  // there are enough pixels with the center label to consider that
69  // it is not isolated
70  return centerPixel;
71  }
72  else
73  {
74  // If the majorityLabel is NOT unique in the neighborhood
75  if (!histoSummary.majorityUnique)
76  {
77  if (m_KeepOriginalLabelBool == true)
78  {
79  return centerPixel;
80  }
81  else
82  {
83  return m_LabelForUndecidedPixels;
84  }
85  }
86  // Extraction of the more representative Label in the neighborhood (majorityLabel)
87  return histoSummary.majorityLabel;
88  }
89  } // END if (centerPixel != m_LabelForNoDataPixels)
90 }
91 
92 template <class TInputImage, class TOutputImage, class TKernel>
95  const KernelIteratorType kernelBegin,
96  const KernelIteratorType kernelEnd) const
97 {
98  typedef std::map<PixelType, unsigned int> HistogramType;
99  typedef std::vector<std::pair<PixelType, unsigned int>> HistoAsVectorType;
100  HistogramType histoNeigh;
101  unsigned int i = 0;
102  for (KernelIteratorType kernel_it = kernelBegin; kernel_it < kernelEnd; ++kernel_it, ++i)
103  {
104  // if structuring element is positive, use the pixel under that element
105  // in the image
106  // note we use GetPixel() on the SmartNeighborhoodIterator to
107  // respect boundary conditions
108  const PixelType label = nit.GetPixel(i);
109  if ((*kernel_it > itk::NumericTraits<KernelPixelType>::Zero) && (label != m_LabelForNoDataPixels))
110  {
111  histoNeigh[label] += 1;
112  }
113  }
115  assert(!histoNeigh.empty());
116  if (histoNeigh.size() == 1)
117  {
118  result.freqCenterLabel = histoNeigh.begin()->second;
119  result.majorityLabel = histoNeigh.begin()->first;
120  result.majorityUnique = true;
121  }
122  else
123  {
124  HistoAsVectorType histoNeighVec(histoNeigh.begin(), histoNeigh.end());
125  // Sort the 2 max elements to the beginning
126  std::nth_element(histoNeighVec.begin(), histoNeighVec.begin() + 1, histoNeighVec.end(), CompareHistoFequencies());
127  result.freqCenterLabel = histoNeigh[nit.GetCenterPixel()];
128  result.majorityLabel = histoNeighVec[0].first;
129  result.majorityUnique = (histoNeighVec[0].second != histoNeighVec[1].second);
130  }
131  return result;
132 }
133 
134 template <class TInputImage, class TOutputImage, class TKernel>
136 {
137  Superclass::GenerateOutputInformation();
138 
139  TOutputImage* outputPtr = this->GetOutput();
140 
141  // Set the NoData value using the background
142  const unsigned int& nbBands = outputPtr->GetNumberOfComponentsPerPixel();
143  std::vector<bool> noDataValueAvailable;
144  noDataValueAvailable.resize(nbBands, true);
145  std::vector<double> noDataValue;
146  noDataValue.resize(nbBands, 0.0);
147  for (unsigned int i = 0; i < nbBands; ++i)
148  {
149  noDataValue[i] = itk::DefaultConvertPixelTraits<PixelType>::GetNthComponent(i, m_LabelForNoDataPixels);
150  }
151 
152  WriteNoDataFlags(noDataValueAvailable, noDataValue, outputPtr->GetImageMetadata());
153 }
154 
155 } // end namespace otb
156 
157 #endif
otb::NeighborhoodMajorityVotingImageFilter::ComputeNeighborhoodHistogramSummary
const HistoSummary ComputeNeighborhoodHistogramSummary(const NeighborhoodIteratorType &nit, const KernelIteratorType kernelBegin, const KernelIteratorType kernelEnd) const
Definition: otbNeighborhoodMajorityVotingImageFilter.hxx:94
otb::NeighborhoodMajorityVotingImageFilter::CompareHistoFequencies
Definition: otbNeighborhoodMajorityVotingImageFilter.h:171
otb::WriteNoDataFlags
void OTBMetadata_EXPORT WriteNoDataFlags(const std::vector< bool > &flags, const std::vector< double > &values, ImageMetadata &imd)
otb::NeighborhoodMajorityVotingImageFilter::NeighborhoodMajorityVotingImageFilter
NeighborhoodMajorityVotingImageFilter()
Definition: otbNeighborhoodMajorityVotingImageFilter.hxx:40
otb::NeighborhoodMajorityVotingImageFilter::NeighborhoodIteratorType
Superclass::NeighborhoodIteratorType NeighborhoodIteratorType
Definition: otbNeighborhoodMajorityVotingImageFilter.h:91
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::NeighborhoodMajorityVotingImageFilter::HistoSummary
Definition: otbNeighborhoodMajorityVotingImageFilter.h:164
otbNoDataHelper.h
otb::NeighborhoodMajorityVotingImageFilter::HistoSummary::majorityLabel
PixelType majorityLabel
Definition: otbNeighborhoodMajorityVotingImageFilter.h:167
otbMetaDataKey.h
otb::NeighborhoodMajorityVotingImageFilter::HistoSummary::majorityUnique
bool majorityUnique
Definition: otbNeighborhoodMajorityVotingImageFilter.h:168
otbNeighborhoodMajorityVotingImageFilter.h
otb::NeighborhoodMajorityVotingImageFilter::HistoSummary::freqCenterLabel
unsigned int freqCenterLabel
Definition: otbNeighborhoodMajorityVotingImageFilter.h:166
otb::NeighborhoodMajorityVotingImageFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbNeighborhoodMajorityVotingImageFilter.hxx:135
otb::NeighborhoodMajorityVotingImageFilter::PixelType
Superclass::PixelType PixelType
Definition: otbNeighborhoodMajorityVotingImageFilter.h:81
otb::NeighborhoodMajorityVotingImageFilter::KernelIteratorType
Superclass::KernelIteratorType KernelIteratorType
Definition: otbNeighborhoodMajorityVotingImageFilter.h:88
otb::NeighborhoodMajorityVotingImageFilter::Evaluate
PixelType Evaluate(const NeighborhoodIteratorType &nit, const KernelIteratorType kernelBegin, const KernelIteratorType kernelEnd) override
Definition: otbNeighborhoodMajorityVotingImageFilter.hxx:53