OTB  9.0.0
Orfeo Toolbox
otbLabelMapWithAdjacency.h
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 otbLabelMapWithAdjacency_h
22 #define otbLabelMapWithAdjacency_h
23 
24 #include "itkLabelMap.h"
26 
27 #include <set>
28 
29 namespace otb
30 {
40 template <class TLabelObject>
41 class ITK_EXPORT LabelMapWithAdjacency : public itk::LabelMap<TLabelObject>
42 {
43 public:
46  typedef itk::LabelMap<TLabelObject> Superclass;
47  typedef itk::SmartPointer<Self> Pointer;
48  typedef itk::SmartPointer<const Self> ConstPointer;
49  typedef itk::WeakPointer<const Self> ConstWeakPointer;
50 
52  itkNewMacro(Self);
53 
55  itkTypeMacro(LabelMapWithAdjacency, LabelMap);
56 
58  typedef TLabelObject LabelObjectType;
59 
64  itkStaticConstMacro(ImageDimension, unsigned int, LabelObjectType::ImageDimension);
65 
67  typedef typename LabelObjectType::LabelType LabelType;
68 
70  typedef std::set<LabelType> AdjacentLabelsContainerType;
71 
73  typedef std::map<LabelType, AdjacentLabelsContainerType> AdjacencyMapType;
74 
77 
79  typedef std::pair<LabelType, LabelType> LabelPairType;
80 
82  typedef std::vector<LabelPairType> LabelPairVectorType;
83 
86  {
87  m_AdjacencyMap = amap;
88  }
89 
91  {
92  return m_AdjacencyMap;
93  }
94 
96  void AddAdjacentLabel(LabelType label1, LabelType label2)
97  {
98  if (m_AdjacencyMap.find(label1) != m_AdjacencyMap.end())
99  {
100  m_AdjacencyMap[label1].insert(label2);
101  }
102  else
103  {
104  AdjacentLabelsContainerType newContainer;
105  newContainer.insert(label2);
106  m_AdjacencyMap[label1] = newContainer;
107  }
108  }
110 
113  {
114  if (m_AdjacencyMap.find(label) != m_AdjacencyMap.end())
115  {
116  m_AdjacencyMap[label].clear();
117  }
118  }
120 
123  {
124  if (m_AdjacencyMap.find(label1) != m_AdjacencyMap.end())
125  {
126  m_AdjacencyMap[label1].erase(label2);
127  }
128  }
130 
133  {
134  typename AdjacencyMapType::const_iterator it = m_AdjacencyMap.find(label);
135  if (it != m_AdjacencyMap.end())
136  {
137  return it->second;
138  }
139  else
140  {
141  itkExceptionMacro(<< "No Adjacency set for label " << label << ".");
142  }
143  }
145 
147  void MergeLabels(const LabelType& label1, const LabelType& label2)
148  {
149  // Check if source and destination labels are the same
150  if (label1 == label2)
151  {
152  // If so, there is nothing to merge
153  return;
154  }
155 
156  // Check if two labels are adjacent
157  if (m_AdjacencyMap.find(label1) != m_AdjacencyMap.end() && !m_AdjacencyMap[label1].count(label2))
158  {
159  itkExceptionMacro(<< "Labels " << label1 << " and " << label2 << " are not adjacent, can not merge.");
160  }
161 
162  // Retrieve the two label objects
163  typename LabelObjectType::Pointer lo1 = this->GetLabelObject(label1);
164  typename LabelObjectType::Pointer lo2 = this->GetLabelObject(label2);
165 
166  // Merges label object
167  MergeFunctorType mergeFunctor;
168  typename LabelObjectType::Pointer loOut = mergeFunctor(lo1, lo2);
169 
170  // Move every occurrence of label2 to label1 in adjacency map
171  for (typename AdjacentLabelsContainerType::iterator it = m_AdjacencyMap[label2].begin(); it != m_AdjacencyMap[label2].end(); ++it)
172  {
173  m_AdjacencyMap[*it].erase(label2);
174  if (*it != label1)
175  {
176  m_AdjacencyMap[*it].insert(label1);
177  m_AdjacencyMap[label1].insert(*it);
178  }
179  }
180 
181  // Remove label2 from adjancency map
182  m_AdjacencyMap.erase(label2);
183 
184  // Remove label object corresponding to label2
185  this->RemoveLabel(label2);
186 
187  // Replace label object corresponding to label1
188  this->RemoveLabel(label1);
189  this->AddLabelObject(loOut);
190  }
191 
194  void MergeLabels(const LabelPairVectorType& labels)
195  {
196  LabelPairVectorType internalLabelPairs = labels;
197 
198  typename LabelPairVectorType::iterator lpit1, lpit2;
199 
200  for (lpit1 = internalLabelPairs.begin(); lpit1 != internalLabelPairs.end(); ++lpit1)
201  {
202  // Merge the current label pair
203  this->MergeLabels(lpit1->first, lpit1->second);
204 
205  // Update the remaining label pairs
206  for (lpit2 = lpit1 + 1; lpit2 != internalLabelPairs.end(); ++lpit2)
207  {
208  if (lpit2->first == lpit1->second)
209  {
210  lpit2->first = lpit1->first;
211  }
212  if (lpit2->second == lpit1->second)
213  {
214  lpit2->second = lpit1->first;
215  }
216  }
217  }
218  }
219 
220 protected:
223  {
224  }
225 
228  {
229  }
230 
232  void PrintSelf(std::ostream& os, itk::Indent indent) const override
233  {
234  Superclass::PrintSelf(os, indent);
235  }
236 
239  void CopyInformation(const itk::DataObject* data) override
240  {
241  // Call superclass implementation
242  Superclass::CopyInformation(data);
243 
244  // Try to cast to LabelMapWithAdjacency
245  const Self* selfData = dynamic_cast<const Self*>(data);
246 
247  // If cast succeed
248  if (selfData)
249  m_AdjacencyMap = selfData->m_AdjacencyMap;
250  }
251 
252 private:
253  LabelMapWithAdjacency(const Self&) = delete;
254  void operator=(const Self&) = delete;
255 
258 };
259 
260 } // end namespace otb
261 
262 #endif
otb::LabelMapWithAdjacency::RemoveAdjacentLabel
void RemoveAdjacentLabel(LabelType label1, LabelType label2)
Definition: otbLabelMapWithAdjacency.h:122
otb::LabelMapWithAdjacency::LabelType
LabelObjectType::LabelType LabelType
Definition: otbLabelMapWithAdjacency.h:67
otb::LabelMapWithAdjacency::AddAdjacentLabel
void AddAdjacentLabel(LabelType label1, LabelType label2)
Definition: otbLabelMapWithAdjacency.h:96
otb::LabelMapWithAdjacency::Self
LabelMapWithAdjacency Self
Definition: otbLabelMapWithAdjacency.h:45
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::LabelMapWithAdjacency::CopyInformation
void CopyInformation(const itk::DataObject *data) override
Definition: otbLabelMapWithAdjacency.h:239
otb::LabelMapWithAdjacency::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbLabelMapWithAdjacency.h:232
otb::LabelMapWithAdjacency::GetAdjacencyMap
const AdjacencyMapType & GetAdjacencyMap() const
Definition: otbLabelMapWithAdjacency.h:90
otbMergeLabelObjectFunctor.h
otb::LabelMapWithAdjacency::LabelObjectType
TLabelObject LabelObjectType
Definition: otbLabelMapWithAdjacency.h:55
otb::LabelMapWithAdjacency::LabelPairType
std::pair< LabelType, LabelType > LabelPairType
Definition: otbLabelMapWithAdjacency.h:79
otb::LabelMapWithAdjacency::ConstPointer
itk::SmartPointer< const Self > ConstPointer
Definition: otbLabelMapWithAdjacency.h:48
otb::LabelMapWithAdjacency::AdjacencyMapType
std::map< LabelType, AdjacentLabelsContainerType > AdjacencyMapType
Definition: otbLabelMapWithAdjacency.h:73
otb::LabelMapWithAdjacency::GetAdjacentLabels
const AdjacentLabelsContainerType & GetAdjacentLabels(LabelType label) const
Definition: otbLabelMapWithAdjacency.h:132
otb::LabelMapWithAdjacency::MergeLabels
void MergeLabels(const LabelPairVectorType &labels)
Definition: otbLabelMapWithAdjacency.h:194
otb::LabelMapWithAdjacency::LabelMapWithAdjacency
LabelMapWithAdjacency()
Definition: otbLabelMapWithAdjacency.h:222
otb::LabelMapWithAdjacency::Superclass
itk::LabelMap< TLabelObject > Superclass
Definition: otbLabelMapWithAdjacency.h:46
otb::LabelMapWithAdjacency::AdjacentLabelsContainerType
std::set< LabelType > AdjacentLabelsContainerType
Definition: otbLabelMapWithAdjacency.h:70
otb::LabelMapWithAdjacency::MergeFunctorType
Functor::MergeLabelObjectFunctor< TLabelObject > MergeFunctorType
Definition: otbLabelMapWithAdjacency.h:76
otb::Functor::MergeLabelObjectFunctor
Merge two LabelObjects.
Definition: otbMergeLabelObjectFunctor.h:48
otb::LabelMapWithAdjacency::Pointer
itk::SmartPointer< Self > Pointer
Definition: otbLabelMapWithAdjacency.h:47
otb::LabelMapWithAdjacency::LabelPairVectorType
std::vector< LabelPairType > LabelPairVectorType
Definition: otbLabelMapWithAdjacency.h:82
otb::LabelMapWithAdjacency::SetAdjacencyMap
void SetAdjacencyMap(const AdjacencyMapType &amap)
Definition: otbLabelMapWithAdjacency.h:85
otb::LabelMapWithAdjacency
This class is a LabelMap with additional adjacency information.
Definition: otbLabelMapWithAdjacency.h:41
otb::LabelMapWithAdjacency::ClearAdjacentLabels
void ClearAdjacentLabels(LabelType label)
Definition: otbLabelMapWithAdjacency.h:112
otb::LabelMapWithAdjacency::m_AdjacencyMap
AdjacencyMapType m_AdjacencyMap
Definition: otbLabelMapWithAdjacency.h:257
otb::LabelMapWithAdjacency::~LabelMapWithAdjacency
~LabelMapWithAdjacency() override
Definition: otbLabelMapWithAdjacency.h:227
otb::LabelMapWithAdjacency::MergeLabels
void MergeLabels(const LabelType &label1, const LabelType &label2)
Definition: otbLabelMapWithAdjacency.h:147
otb::LabelMapWithAdjacency::ConstWeakPointer
itk::WeakPointer< const Self > ConstWeakPointer
Definition: otbLabelMapWithAdjacency.h:49