aimstil  5.0.5
EquivalenceChain.h
Go to the documentation of this file.
1 #ifndef TIL_EQUIVALENCECHAIN_H
2 #define TIL_EQUIVALENCECHAIN_H
3 
4 
5 // Standard library includes
6 
7 #include <iostream>
8 #include <stdexcept>
9 #include <time.h>
10 #include <vector>
11 
12 
13 // Local includes
14 #include "til/til_common.h"
15 
16 
17 
18 // Namespace
19 
20 namespace til {
21 
22 
23 
24 // This class stores equivalences between labels, coded with type T,
25 // typically used in segmented images (of type T).
26 // Equivalence is e.g. saying "object with label X and object with
27 // label Y are equivalent" (the meaning of equivalency is of course
28 // left to the user, e.g. equivalence = "exact same object")
29 
30 // Equivalence is stored a compact way, via a chain: a label points to
31 // an equivalent label.
32 // Memory usage is therefore very low (just N, the total # of labels)
33 // Update is reasonably quick (to add an equivalence between two labels,
34 // one has to link the end of the chain) if in practice
35 // equivalence are added between labels that are near the end of their
36 // respective chains
37 
38 // However some operations are in general slow, e.g. "are label X and Y
39 // equivalent?" need to go to the end of the chain for both labels (much
40 // slower than matrix look-up of course).
41 
42 // Label 0 is special and always represent the background. It cannot be
43 // part of any chain.
44 
45 
47 {
48 
49 public:
50 
51  // Allocate equivalence chain
52  // The maximum number of labels cannot be higher than the
53  // maximum of type T minus 1
54  EquivalenceChain(int maxNumberOfLabels);
55 
56 
57  // Destructor
59 
60 
61  // clear the chain (everything points to background zero)
62  void reset();
63 
64 
65  // clear the chain, with 'nLabels' valid and unique labels
66  // pointing to themselves
67  void reset(int nLabels);
68 
69 
70  // Set equivalence between label1 and label2
71  void setEquivalence(int label1, int label2);
72 
73 
74  // Create a new label value
75  // Returns 0 (background) if impossible (chain is already full)
76  int getNewLabel();
77 
78 
79  // All equivalent labels now point to the same new label
80  // Those new labels are compact, i.e. they form a sequence from
81  // 1 to N (N being the number returned by the function)
82  int mergeLabels();
83 
84 
85  // Get label pointed by label n
86  int operator[] (int n) { return m_chain[n]; }
87 
88 
89  // Get the end of the chain which label belongs to
90  int getLastLabel(int label)
91  {
92  if (label != m_chain[label])
93  {
94  return m_chain[label] = getLastLabel(m_chain[label]);
95  }
96  return label;
97  }
98 
99 /*
100  int getLastLabel(int label)
101  {
102  //int count = 0;
103 
104  if (label < 0 || label > m_maxLabel)
105  {
106  throw std::out_of_range("Label out of range");
107  }
108 
109  while (label != m_chain[label])
110  {
111  //++count;
112  label = m_chain[label];
113  }
114  return label;
115  }
116 */
117 
118  int getGreatestLabel() { return m_maxLabel; }
119 
120 public: // friends
121 
122  friend void print(const EquivalenceChain &);
123 
124 
125 private: // functions
126 
127  void allPointToLastLabel();
128  int _fillWithLastLabel(int i);
129 
130 
131 private: // data
132 
133  // The current maximum label used
134  int m_maxLabel;
135 
136  // The size of the equivalence chain
137  int m_size;
138 
139  // The equivalence chain
140  int * m_chain;
141 };
142 
143 
144 
145 
147 {
148  if (m_maxLabel == m_size) return 0;
149  ++m_maxLabel;
150  m_chain[m_maxLabel] = m_maxLabel;
151  return m_maxLabel;
152 }
153 
154 
155 INLINE void EquivalenceChain::setEquivalence(int label1, int label2)
156 {
157 
158  /*
159  if (label1 != label2)
160  {
161  std::vector<int> v1;
162  this->getChain(label1, v1);
163  std::vector<int> v2;
164  this->getChain(label2, v2);
165 
166  int last = *(v1.end());
167 
168  std::vector<int>::iterator i;
169  for (i=v1.begin(); i != v1.end(); ++i)
170  {
171  *i = last;
172  }
173  for (i=v2.begin(); i != v2.end(); ++i)
174  {
175  *i = last;
176  }
177  }
178  */
179  if (label1 != label2)
180  {
181  int last1 = this->getLastLabel(label1);
182  int last2 = this->getLastLabel(label2);
183 
184  if (last1 != last2)
185  {
186  m_chain[last1] = last2;
187  }
188  }
189 }
190 
191 
192 } // namespace
193 
194 #endif
195 
void print(const Affine< T > &a)
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
General macros, definitions and functions.
#define TIL_API
Definition: til_common.h:42
#define INLINE
Definition: til_common.h:26
int getLastLabel(int label)
void setEquivalence(int label1, int label2)