Tree.cpp
Go to the documentation of this file.
1 
18 #include "Tree.hpp"
19 #include "utility/Util.hpp"
20 
21 
22 namespace ISM
23 {
24 
25  Tree::Tree(std::string pattern, unsigned clusterId, const TrackPtr reference,
26  std::vector<ClusterPtr> &clustersLeft, const std::vector<ClusterPtr> &allClusters,
27  IsmPtr &ism, bool naive)
28  {
29  build(pattern, clusterId, reference, clustersLeft, allClusters, ism, naive);
30  }
31 
32  Tree::Tree(const std::string &pattern, ObjectRelations topology, bool naive)
33  {
34  LogHelper::logMessage("Generating Tree: ", LOG_INFO, LOG_COLOR_TREE);
35  std::vector<ClusterPtr> clusters = buildClusters(topology);
36  unsigned clusterId = 0;
37  std::stringstream subPatternNameStream;
38  subPatternNameStream<<pattern;
39  std::string subPatternName = subPatternNameStream.str();
41  std::vector<ClusterPtr> copy = clusters;
42  std::vector<ClusterPtr> allClusters = clusters;
43  std::sort(clusters.begin(), clusters.end(), compareClusters);
44  std::sort(allClusters.begin(), allClusters.end(), compareClusters);
45  for (ClusterPtr& it : clusters)
46  {
47  LogHelper::logMessage("Recommended Height is " + std::to_string(it->getRecommendedLevel()), LOG_DEBUG, LOG_COLOR_TREE);
48  }
49  build(subPatternName, clusterId, (*clusters.begin())->getReference(), copy, allClusters, ism, naive);
50 
51 
52  for (std::map<std::string, std::vector<VoteSpecifierPtr> >::iterator it = ism->voteSpecifiersPerObject.begin();
53  it != ism->voteSpecifiersPerObject.end();
54  ++it)
55  {
56  if (it->first.find("_sub") != std::string::npos)
57  {
58  for (unsigned int i = 0; i < it->second.size(); ++i)
59  {
60  it->second[i]->observedId = "";
61  }
62  }
63  }
64 
65  this->setISM(ism);
66  LogHelper::logMessage("Tree is generated\n", LOG_INFO, LOG_COLOR_TREE);
68  }
69 
70 
71  void Tree::build(std::string pattern, unsigned clusterId, const TrackPtr reference,
72  std::vector<ClusterPtr>& clustersLeft, const std::vector<ClusterPtr>& allClusters,
73  IsmPtr& ism, bool naive) {
74 
75  this->height = 0;
76  this->weight = 1;
77  this->reference = TrackPtr(new Track(*reference));
78 
79  ClusterPtr cluster;
80  std::vector<ClusterPtr>::iterator clusterIt;
81  for (clusterIt = clustersLeft.begin(); clusterIt != clustersLeft.end(); ++clusterIt)
82  {
83  if (reference->type == (*clusterIt)->getReference()->type &&
84  reference->observedId == (*clusterIt)->getReference()->observedId)
85  {
86  cluster = *clusterIt;
87  clustersLeft.erase(clusterIt);
88  break;
89  }
90  }
91  if (cluster != 0)
92  {
93  std::stringstream subPatternNameStream;
94  if (pattern.find("_sub") != std::string::npos)
95  {
96  subPatternNameStream<<pattern<<clusterId;
97  pattern = subPatternNameStream.str();
98  this->getReference()->type = pattern;
99  this->getReference()->observedId = "";
100  this->setWeight(0);
101  LogHelper::logMessage("Renamed to " + this->getReference()->type, LOG_DEBUG, LOG_COLOR_TREE);
102 
103  subPatternNameStream<<"_sub";
104  pattern = subPatternNameStream.str();
105  }
106  else
107  {
108  this->getReference()->type = pattern;
109  this->getReference()->observedId = "";
110  this->setWeight(0);
111  LogHelper::logMessage("Renamed to " + this->getReference()->type, LOG_DEBUG, LOG_COLOR_TREE);
112  subPatternNameStream<<pattern<<"_sub";
113  pattern = subPatternNameStream.str();
114  }
115  for (TrackPtr& child : cluster->getChildren()->tracks)
116  {
117  bool ignore = false;
118  LogHelper::logMessage("naive is: " + std::to_string(naive), LOG_DEBUG, LOG_COLOR_TREE);
119  if (naive == false)
120  {
121  for (const ClusterPtr& clusterChecker : allClusters)
122  {
123  if (clusterChecker == cluster)
124  {
125  //Clusters are ordered by level they'd have in a tree
126  break;
127  }
128  for (TrackPtr& childChecker : clusterChecker->getChildren()->tracks)
129  {
130  if (childChecker->type == child->type && childChecker->observedId == child->observedId)
131  {
132  ignore = true;
133  }
134  }
135  }
136  }
137  TreePtr subTree;
138  if (ignore == false)
139  {
140  LogHelper::logMessage("Building subtree for " + child->type, LOG_DEBUG, LOG_COLOR_TREE);
141  subTree = TreePtr(new Tree(pattern, clusterId, child, clustersLeft, allClusters, ism, naive));
142  }
143  else
144  {
145  std::vector<ClusterPtr> dummyClusters;
146  LogHelper::logMessage("Would build subtree for " + child->type
147  + " but must not. Appending as leaf instead", LOG_DEBUG, LOG_COLOR_TREE);
148  subTree = TreePtr(new Tree(pattern, clusterId, child, dummyClusters, allClusters, ism, naive));
149  }
150  std::vector<VoteSpecifierPtr> votes =
151  cluster->getVotersByVotersTypeAndObservedId(child->type, child->observedId);
152 
153  this->addChild(subTree);
154  if (subTree->getHeight() + 1 > this->getHeight())
155  {
156  this->setHeight(subTree->getHeight() + 1);
157  }
158  for (VoteSpecifierPtr& vote : votes)
159  {
160  vote->patternName = this->getReference()->type;
161  vote->observedId = child->observedId;
162  vote->objectType = subTree->getReference()->type;
163  ism->voteSpecifiersPerObject[subTree->getReference()->type].push_back(vote);
164  }
165  if (subTree->getWeight() > 1)
166  {
167  ++clusterId;
168  }
169  this->setWeight(this->getWeight() + subTree->getWeight());
170  }
171  PatternPtr newPattern(new Pattern(this->getReference()->type, this->getWeight()));
172  ism->patternDefinitions.insert(std::make_pair(newPattern->name, newPattern));
173  }
174  ism->objectTypes.insert(this->getReference()->type);
175  LogHelper::logMessage("BackTrack. Weight of reference is "
176  + std::to_string(this->getWeight())
177  + " and height is " + std::to_string(this->getHeight())
179  }
180 
181  std::vector<ClusterPtr> Tree::buildClusters(ISM::ObjectRelations topology) const
182  {
183 
185  LogHelper::logMessage("Starting topology clustering : \n", LOG_DEBUG, LOG_COLOR_CLUSTER);
186  std::vector<ClusterPtr> clusters;
187  std::vector<std::pair<TrackPtr, ClusterPtr> > referencesWithParent;
188  //objectOccurenceInfo.first is the amount of occurence of a track, .second is a vector ordered by occurence
189  std::pair<std::map<TrackPtr, int>, std::vector<std::pair<int, TrackPtr> > > objectOccurenceInfo = getMostCommonObjects(topology);
190  std::map<TrackPtr, int> objectOccurences = objectOccurenceInfo.first;
191  std::vector<std::pair<int, TrackPtr> > mostCommonObjects = objectOccurenceInfo.second;
192  ClusterPtr sentinel;
193  referencesWithParent.push_back(std::make_pair(mostCommonObjects.begin()->second, sentinel));
194 
195  LogHelper::logMessage("Starting at most common object : " + (*referencesWithParent.begin()).first->type, LOG_DEBUG, LOG_COLOR_CLUSTER);
196  for (size_t tracksIt = 0; tracksIt < referencesWithParent.size(); ++tracksIt)
197  {
198  for (const std::pair<TrackPtr, int>& it : objectOccurences)
199  {
200  assert(it.second >= 0); (void)it;
201  }
202  ClusterPtr currentCluster(new Cluster(std::make_pair(TrackPtr(new Track(*referencesWithParent[tracksIt].first)), referencesWithParent[tracksIt].second), topology, mostCommonObjects, objectOccurences));
203 
204  std::ostringstream s;
205  s.str("");
206  s << "Current cluster contains " << currentCluster->getChildren()->tracks.size() << " objects: "<< std::endl;
207  for (TrackPtr trackIt : currentCluster->getChildren()->tracks)
208  {
209  s << trackIt->type << " with ID " << trackIt->observedId << ", ";
210  }
211  s << std::endl << "Reference is : " << currentCluster->getReference()->type << std::endl;
213 
214  if (currentCluster->getChildren()->tracks.size() > 0)
215  {
216  clusters.push_back(currentCluster);
217  }
218 
219  for (const std::pair<TrackPtr, int>& objectIt : objectOccurences)
220  {
221  if (objectIt.second > 0)
222  {
223  std::pair<ISM::TrackPtr, ClusterPtr> subReference = getReference(mostCommonObjects, clusters, topology);
224  assert (subReference.first != 0);
225  referencesWithParent.push_back(subReference);
226  break;
227  }
228  }
229  }
230  for (const std::pair<TrackPtr, int>& it : objectOccurences)
231  {
232  assert(it.second == 0); (void)it;
233  }
234 
235  LogHelper::logMessage("All clusters have been constructed", LOG_DEBUG, LOG_COLOR_CLUSTER);
237 
238  return clusters;
239  }
240 
241  std::pair<std::map<ISM::TrackPtr, int> , std::vector<std::pair<int, ISM::TrackPtr> > >
243  {
244  std::map<ISM::TrackPtr, int> objectOccurences;
245  std::vector<std::pair<int, ISM::TrackPtr > > mostCommon;
246  for (const std::pair<unsigned int, ObjectRelationPtr> relationIt : topology)
247  {
248  TrackPtr objectA = relationIt.second->getTrackA();
249  TrackPtr objectB = relationIt.second->getTrackB();
250  if (objectOccurences[objectA])
251  {
252  ++objectOccurences[objectA];
253  }
254  else
255  {
256  objectOccurences[objectA] = 1;
257  }
258  if (objectOccurences[objectB])
259  {
260  ++objectOccurences[objectB];
261  }
262  else
263  {
264  objectOccurences[objectB] = 1;
265  }
266  }
267  //Pushing elements to vektor of pair to make it sorted
268  for (const std::pair<TrackPtr, int>& it : objectOccurences)
269  {
270  mostCommon.push_back(std::make_pair(it.second, it.first));
271  }
272 
273  //Sort mostCommon by number of occurrences of the object and by the object identifier (object type + object observedId).
274  struct compare {
275  bool operator()(const std::pair<int, ISM::TrackPtr > &firstElem, const std::pair<int, ISM::TrackPtr > &secondElem) {
276  if (firstElem.first == secondElem.first)
277  {
278  std::string objectIdentifierFirstElem = firstElem.second->type + firstElem.second->observedId;
279  std::string objectIdentifierSecondElem = secondElem.second->type + secondElem.second->observedId;
280  return objectIdentifierFirstElem.compare(objectIdentifierSecondElem) < 0;
281 
282  }
283  return firstElem.first > secondElem.first;
284  }
285  };
286 
287  std::sort(mostCommon.begin(), mostCommon.end(), compare());
288  std::pair<std::map<TrackPtr, int>, std::vector<std::pair<int, ISM::TrackPtr > > > ret = std::make_pair(objectOccurences, mostCommon);
289  return ret;
290  }
291 
292  std::pair<TrackPtr, ClusterPtr> Tree::getReference(std::vector<std::pair<int, TrackPtr> >& objectTracks,
293  const std::vector<ClusterPtr>& currentClusters, const ObjectRelations& topology) const
294  {
295  std::vector<TrackPtr> orderedObjectsInRelations;
296  for (std::pair<int, TrackPtr>& tracksIt : objectTracks)
297  {
298  for (const std::pair<unsigned int, ObjectRelationPtr>& relationIt : topology)
299  {
300  if (relationIt.second->containsObject(tracksIt.second->type, tracksIt.second->observedId))
301  {
302  orderedObjectsInRelations.push_back(tracksIt.second);
303  }
304  }
305  }
306 
307  ClusterPtr recommendedParent;
308  TrackPtr reference = *orderedObjectsInRelations.begin();
309  for (TrackPtr& tracksIt : orderedObjectsInRelations)
310  {
311  if (recommendedParent != 0)
312  {
313  break;
314  }
315  for (const ClusterPtr& clusterIt : currentClusters)
316  {
317  if (recommendedParent != 0)
318  {
319  LogHelper::logMessage("Comparing with recommended parent :", LOG_DEBUG, LOG_COLOR_TREE);
320  LogHelper::logMessage(std::to_string(recommendedParent->getRecommendedLevel()) + " vs " + std::to_string(clusterIt->getRecommendedLevel()), LOG_DEBUG);
321  }
322  if (recommendedParent != 0 && recommendedParent->getRecommendedLevel() < clusterIt->getRecommendedLevel())
323  {
324  continue;
325  }
326  for (TrackPtr& childIt : clusterIt->getChildren()->tracks)
327  {
328  if ((childIt->observedId == tracksIt->observedId) && (childIt->type == tracksIt->type))
329  {
330  assert (tracksIt != 0);
331  recommendedParent = clusterIt;
332  reference = tracksIt;
333  }
334  }
335  }
336  }
337  LogHelper::logMessage("Return reference with parent", LOG_DEBUG, LOG_COLOR_CLUSTER);
338  return std::make_pair(reference, recommendedParent);
339  }
340 
341  bool Tree::compareClusters(const ClusterPtr& one, const ClusterPtr& two)
342  {
343  return one->getRecommendedLevel() < two->getRecommendedLevel();
344  }
345 
346  template <typename T> bool Tree::pairCompare(const std::pair<unsigned, T>& firstElem,
347  const std::pair<unsigned, T>& secondElem)
348  {
349  return firstElem.first > secondElem.first;
350  }
351 
352  void Tree::addChild(const boost::shared_ptr<Tree>& child)
353  {
354  this->children.push_back(child);
355  }
356 
357  void Tree::setHeight(unsigned height)
358  {
359  this->height = height;
360  }
361 
362  unsigned Tree::getHeight()
363  {
364  return this->height;
365  }
366 
367  void Tree::setWeight(unsigned weight)
368  {
369  this->weight = weight;
370  }
371 
372  unsigned Tree::getWeight()
373  {
374  return this->weight;
375  }
376 
377  void Tree::addVotes(const std::string& voterType, const std::vector<VoteSpecifierPtr>& votes)
378  {
379  std::vector<VoteSpecifierPtr> copy = votes;
380  this->votesByVotersType.insert(std::make_pair(voterType, votes));
381  }
382 
383  std::vector<VoteSpecifierPtr> Tree::getVotesByType(const std::string& type)
384  {
385  return this->votesByVotersType.at(type);
386  }
387 
389  {
390  return this->reference;
391  }
392 
394  {
395  return this->ism;
396  }
397 
399  {
400  this->ism = ism;
401  }
402 }
TrackPtr getReference()
Definition: Tree.cpp:388
void setISM(IsmPtr ism)
Definition: Tree.cpp:398
std::vector< boost::shared_ptr< Tree > > children
Definition: Tree.hpp:69
unsigned getHeight()
Definition: Tree.cpp:362
void build(std::string pattern, unsigned clusterId, const TrackPtr reference, std::vector< ClusterPtr > &clustersLeft, const std::vector< ClusterPtr > &allClusters, IsmPtr &ism, bool naive)
Definition: Tree.cpp:71
void addVotes(const std::string &voterType, const std::vector< VoteSpecifierPtr > &votes)
Definition: Tree.cpp:377
void addChild(const boost::shared_ptr< Tree > &child)
Definition: Tree.cpp:352
static bool pairCompare(const std::pair< unsigned, T > &firstElem, const std::pair< unsigned, T > &secondElem)
Definition: Tree.cpp:346
Tree(TrackPtr reference)
Definition: Tree.hpp:35
static void logLine(LogLevel logLevel=LOG_INFO)
Definition: LogHelper.cpp:101
std::vector< VoteSpecifierPtr > getVotesByType(const std::string &type)
Definition: Tree.cpp:383
IsmPtr getISM()
Definition: Tree.cpp:393
boost::shared_ptr< Cluster > ClusterPtr
Definition: Cluster.hpp:53
unsigned height
Definition: Tree.hpp:70
unsigned getWeight()
Definition: Tree.cpp:372
const char * LOG_COLOR_CLUSTER
Definition: Tree.hpp:66
static bool compareClusters(const ClusterPtr &one, const ClusterPtr &two)
Definition: Tree.cpp:341
static void logMessage(const std::string &message, LogLevel logLevel=LOG_INFO, const char *logColor=LOG_COLOR_DEFAULT)
Definition: LogHelper.cpp:96
std::map< unsigned int, ISM::ObjectRelationPtr, std::less< unsigned > > ObjectRelations
unsigned weight
Definition: Tree.hpp:71
boost::shared_ptr< ImplicitShapeModel > IsmPtr
boost::shared_ptr< Pattern > PatternPtr
Definition: Pattern.hpp:36
TrackPtr reference
Definition: Tree.hpp:68
boost::shared_ptr< VoteSpecifier > VoteSpecifierPtr
boost::shared_ptr< Tree > TreePtr
Definition: typedef.hpp:46
IsmPtr ism
Definition: Tree.hpp:73
const char * LOG_COLOR_TREE
Definition: Tree.hpp:65
void setHeight(unsigned height)
Definition: Tree.cpp:357
std::map< std::string, std::vector< VoteSpecifierPtr > > votesByVotersType
Definition: Tree.hpp:72
void setWeight(unsigned weight)
Definition: Tree.cpp:367
boost::shared_ptr< Track > TrackPtr
Definition: Track.hpp:55
std::pair< std::map< ISM::TrackPtr, int >, std::vector< std::pair< int, ISM::TrackPtr > > > getMostCommonObjects(const ISM::ObjectRelations &topology) const
Definition: Tree.cpp:242
this namespace contains all generally usable classes.
std::vector< ClusterPtr > buildClusters(ISM::ObjectRelations) const
Definition: Tree.cpp:181


asr_lib_ism
Author(s): Hanselmann Fabian, Heller Florian, Heizmann Heinrich, Kübler Marcel, Mehlhaus Jonas, Meißner Pascal, Qattan Mohamad, Reckling Reno, Stroh Daniel
autogenerated on Wed Jan 8 2020 04:02:41