OTB  9.0.0
Orfeo Toolbox
otbGreyLevelCooccurrenceIndexedList.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 
22 #ifndef otbGreyLevelCooccurrenceIndexedList_hxx
23 #define otbGreyLevelCooccurrenceIndexedList_hxx
24 
26 
27 namespace otb
28 {
29 template <class TPixel>
31  : m_Size(), m_Symmetry(true), m_TotalFrequency(0), m_ClipBinsAtEnds(true), m_InputImageMinimum(0), m_InputImageMaximum(255)
32 {
33 }
34 
35 template <class TPixel>
36 void GreyLevelCooccurrenceIndexedList<TPixel>::Initialize(const unsigned int nbins, const PixelValueType min, const PixelValueType max, const bool symmetry)
37 {
38  PixelPairType lowerBound;
39  PixelPairType upperBound;
40 
41  m_Size.Fill(nbins);
42  m_InputImageMinimum = min;
43  m_InputImageMaximum = max;
44  lowerBound.Fill(min);
45  upperBound.Fill(max + 1);
46 
47  m_Symmetry = symmetry;
48  m_LookupArray = LookupArrayType(m_Size[0] * m_Size[1]);
49  m_LookupArray.Fill(-1);
50  m_TotalFrequency = 0;
51 
52  // adjust the sizes of min max value containers
53  unsigned int dim;
54  m_Min.resize(PixelPairSize);
55  for (dim = 0; dim < PixelPairSize; dim++)
56  {
57  m_Min[dim].resize(m_Size[dim]);
58  }
59 
60  m_Max.resize(PixelPairSize);
61  for (dim = 0; dim < PixelPairSize; dim++)
62  {
63  m_Max[dim].resize(m_Size[dim]);
64  }
65 
66  float interval;
67  for (unsigned int i = 0; i < PixelPairSize; i++)
68  {
69  if (m_Size[i] > 0)
70  {
71  interval = static_cast<float>(upperBound[i] - lowerBound[i]) / static_cast<PixelValueType>(m_Size[i]);
72 
73  // Set the min vector and max vector
74  for (unsigned int j = 0; j < static_cast<unsigned int>(m_Size[i] - 1); j++)
75  {
76  this->SetBinMin(i, j, (PixelValueType)(lowerBound[i] + ((float)j * interval)));
77  this->SetBinMax(i, j, (PixelValueType)(lowerBound[i] + (((float)j + 1) * interval)));
78  }
79  this->SetBinMin(i, m_Size[i] - 1, (PixelValueType)(lowerBound[i] + (((float)m_Size[i] - 1) * interval)));
80  this->SetBinMax(i, m_Size[i] - 1, (PixelValueType)(upperBound[i]));
81  }
82  }
83 }
84 
85 template <class TPixel>
87 {
88  m_Min[dimension][nbin] = min;
89 }
90 
91 template <class TPixel>
93 {
94  m_Max[dimension][nbin] = max;
95 }
96 
97 template <class TPixel>
99 {
100  // now using something similar to binary search to find
101  // index.
102  unsigned int dim;
103 
104  int begin;
105  int mid;
106  int end;
107 
109  PixelValueType tempPixelValue;
110 
111  for (dim = 0; dim < PixelPairSize; dim++)
112  {
113  tempPixelValue = pixelPair[dim];
114  begin = 0;
115 
116  if (tempPixelValue < m_Min[dim][begin])
117  {
118  // one of measurement is below the minimum
119  // its ok if we extend the bins to infinity.. not ok if we don't
120  if (!m_ClipBinsAtEnds)
121  {
122  index[dim] = (IndexValueType)0;
123  continue;
124  }
125  else
126  { // set an illegal value and return 0
127  index[dim] = (IndexValueType)m_Size[dim];
128  return false;
129  }
130  }
131 
132  end = m_Min[dim].size() - 1;
133  if (tempPixelValue >= m_Max[dim][end])
134  {
135  // one of measurement is above the maximum
136  // its ok if we extend the bins to infinity.. not ok if we don't
137  // Need to include the last endpoint in the last bin.
138  if (!m_ClipBinsAtEnds || tempPixelValue == m_Max[dim][end])
139  {
140  index[dim] = (IndexValueType)m_Size[dim] - 1;
141  continue;
142  }
143  else
144  { // set an illegal value and return 0
145  index[dim] = (IndexValueType)m_Size[dim];
146  return false;
147  }
148  }
149 
150  // Binary search for the bin where this measurement could be
151  mid = (end + 1) / 2;
152  median = m_Min[dim][mid];
153 
154  while (true)
155  {
156  if (tempPixelValue < median)
157  {
158  end = mid - 1;
159  }
160  else if (tempPixelValue > median)
161  {
162  // test whether it is inside the current bin by comparing to the max of
163  // this bin.
164  if (tempPixelValue < m_Max[dim][mid] && tempPixelValue >= m_Min[dim][mid])
165  {
166  index[dim] = mid;
167  break;
168  }
169  // otherwise, continue binary search
170  begin = mid + 1;
171  }
172  else
173  {
174  index[dim] = mid;
175  break;
176  }
177  mid = begin + (end - begin) / 2;
178  median = m_Min[dim][mid];
179  } // end of while
180  } // end of for()
181  return true;
182 }
183 
184 template <class TPixel>
186 {
187 
188  if (pixelvalue1 < m_InputImageMinimum || pixelvalue1 > m_InputImageMaximum)
189  {
190  return; // don't put a pixel in the co-occurrence list if pixelvalue1
191  // is out-of-bounds.
192  }
193 
194  if (pixelvalue2 < m_InputImageMinimum || pixelvalue2 > m_InputImageMaximum)
195  {
196  return; // don't put a pixel in the co-occurrence list if the pixelvalue2
197  // is out-of-bounds.
198  }
199 
200  IndexType index;
201  PixelPairType ppair(PixelPairSize);
202  ppair[0] = pixelvalue1;
203  ppair[1] = pixelvalue2;
204 
205  // Get Index of the given pixel pair;
206  this->GetIndex(ppair, index);
207  // Add the index and set/update the frequency of the pixel pair. if m_Symmetry
208  // is true the index is swapped and added to vector again.
209  this->AddPairToVector(index);
210  if (m_Symmetry)
211  {
212  IndexValueType temp;
213  temp = index[0];
214  index[0] = index[1];
215  index[1] = temp;
216  this->AddPairToVector(index);
217  }
218 }
219 
220 template <class TPixel>
222  IndexValueType j)
223 {
224  double frequency = 0;
225  InstanceIdentifier instanceId = i * m_Size[0] + j;
226  if (instanceId < m_LookupArray.size())
227  {
228  int findex = m_LookupArray[instanceId];
229  if (findex > -1)
230  frequency = m_Vector[findex].second / m_TotalFrequency;
231  }
232  return frequency;
233 }
234 
235 template <class TPixel>
238 {
239  double frequency = 0;
240  InstanceIdentifier instanceId = i * m_Size[0] + j;
241  if (instanceId < m_LookupArray.size())
242  {
243  int findex = m_LookupArray[instanceId];
244  if (findex > -1)
245  frequency = vect[findex].second;
246  }
247  return frequency;
248 }
249 
250 template <class TPixel>
252 {
253  return m_Vector;
254 }
255 
256 template <class TPixel>
258 {
259  InstanceIdentifier instanceId = 0;
260  instanceId = index[1] * m_Size[0] + index[0];
261  int vindex = m_LookupArray[instanceId];
262  if (vindex < 0)
263  {
264  m_LookupArray[instanceId] = m_Vector.size();
265 
266  CooccurrencePairType cooccur;
267  cooccur = std::make_pair(index, 1);
268  m_Vector.push_back(cooccur);
269  }
270  else
271  {
272  m_Vector[vindex].second++;
273  }
274  m_TotalFrequency = m_TotalFrequency + 1;
275 }
276 
277 template <class TPixel>
278 void GreyLevelCooccurrenceIndexedList<TPixel>::PrintSelf(std::ostream& os, itk::Indent indent) const
279 {
280  Superclass::PrintSelf(os, indent);
281  os << indent << "Symmetry: " << this->m_Symmetry << std::endl;
282  os << indent << "TotalFrequency: " << this->m_TotalFrequency << std::endl;
283  os << indent << "Size: " << m_Size;
284  os << indent << "CooccurrenceIndexedList: " << std::endl;
285  typename VectorType::const_iterator it;
286  for (it = m_Vector.begin(); it != m_Vector.end(); ++it)
287  {
288  std::cerr << "index=" << (*it).first << ", frequency=" << (*it).second << std::endl;
289  }
290  std::cerr << std::endl;
291 }
292 
293 } // end namespace otb
294 
295 #endif
otb::GreyLevelCooccurrenceIndexedList::GetIndex
bool GetIndex(const PixelPairType &pixelPair, IndexType &index) const
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:98
otb::GreyLevelCooccurrenceIndexedList::LookupArrayType
itk::Array< int > LookupArrayType
Definition: otbGreyLevelCooccurrenceIndexedList.h:107
otb::GreyLevelCooccurrenceIndexedList::RelativeFrequencyType
itk::NumericTraits< FrequencyType >::RealType RelativeFrequencyType
Definition: otbGreyLevelCooccurrenceIndexedList.h:91
otb::GreyLevelCooccurrenceIndexedList::SetBinMax
void SetBinMax(const unsigned int dimension, const InstanceIdentifier nbin, PixelValueType max)
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:92
otb::GreyLevelCooccurrenceIndexedList::PixelValueType
itk::NumericTraits< PixelType >::RealType PixelValueType
Definition: otbGreyLevelCooccurrenceIndexedList.h:94
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::GreyLevelCooccurrenceIndexedList::VectorType
std::vector< CooccurrencePairType > VectorType
Definition: otbGreyLevelCooccurrenceIndexedList.h:111
otb::GreyLevelCooccurrenceIndexedList::GetFrequency
RelativeFrequencyType GetFrequency(IndexValueType i, IndexValueType j)
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:221
otb::GreyLevelCooccurrenceIndexedList::InstanceIdentifier
itk::IdentifierType InstanceIdentifier
Definition: otbGreyLevelCooccurrenceIndexedList.h:89
otb::GreyLevelCooccurrenceIndexedList::AddPairToVector
void AddPairToVector(IndexType index)
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:257
otb::GreyLevelCooccurrenceIndexedList::IndexValueType
itk::IndexValueType IndexValueType
Definition: otbGreyLevelCooccurrenceIndexedList.h:87
otb::median
Definition: otbParserXPlugins.h:324
otbGreyLevelCooccurrenceIndexedList.h
otb::GreyLevelCooccurrenceIndexedList::SetBinMin
void SetBinMin(const unsigned int dimension, const InstanceIdentifier nbin, PixelValueType min)
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:86
otb::GreyLevelCooccurrenceIndexedList::GetVector
VectorType GetVector()
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:251
otb::GreyLevelCooccurrenceIndexedList::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:278
otb::GreyLevelCooccurrenceIndexedList::CooccurrencePairType
std::pair< IndexType, FrequencyType > CooccurrencePairType
Definition: otbGreyLevelCooccurrenceIndexedList.h:102
otb::GreyLevelCooccurrenceIndexedList::IndexType
itk::Index< PixelPairSize > IndexType
Definition: otbGreyLevelCooccurrenceIndexedList.h:85
otb::GreyLevelCooccurrenceIndexedList::GreyLevelCooccurrenceIndexedList
GreyLevelCooccurrenceIndexedList()
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:30
otb::GreyLevelCooccurrenceIndexedList::AddPixelPair
void AddPixelPair(const PixelValueType &pixelvalue1, const PixelValueType &pixelvalue2)
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:185
otb::GreyLevelCooccurrenceIndexedList::PixelPairType
itk::FixedArray< PixelValueType, PixelPairSize > PixelPairType
Definition: otbGreyLevelCooccurrenceIndexedList.h:95
otb::GreyLevelCooccurrenceIndexedList::Initialize
void Initialize(const unsigned int nbins, const PixelValueType min, const PixelValueType max, const bool symmetry=true)
Definition: otbGreyLevelCooccurrenceIndexedList.hxx:36