DirectionRelationHeuristic.cpp
Go to the documentation of this file.
1 
19 
20 namespace SceneModel {
21 
22  DirectionRelationHeuristic::DirectionRelationHeuristic(const double pStaticBreakRatio, const double pTogetherRatio, const double pMaxAngleDeviation)
23  : AbstractHeuristic("DirectionRelationHeuristic")
24  , mStaticBreakRatio(pStaticBreakRatio)
25  , mTogetherRatio(pTogetherRatio)
26  , mMaxAngleDeviation(pMaxAngleDeviation)
27  {
28  }
29 
31  {
32  }
33 
35  {
36  // The closest distance between two objects.
37  double bestDistance = std::numeric_limits<double>::max();
38 
39  // Iterate over all object sets.
40  BOOST_FOREACH(boost::shared_ptr<TreeNode> first, pNodes)
41  {
42  // The currently best trajectory.
43  boost::shared_ptr<TreeNode> currentBest;
44 
45  double currentClosestDistance = std::numeric_limits<double>::max();
46  int currentBestBreaks = 1;
47  int currentBestCommonPositions = 1;
48 
49  // Iterate over all object sets in an inner loop to go over all possible combinations.
50  BOOST_FOREACH(boost::shared_ptr<TreeNode> second, pNodes)
51  {
52  // Prevent trivial comparison.
53  if (first == second) {
54  continue;
55  }
56 
57  /*
58  * What we do:
59  * Calculate a direction Vector from first to second for every Frame.
60  * Check in every frame the angle between the reference vector (first vector) and the current vector.
61  * If the misalignment is more than mMaxAngleDeviation degrees, increase staticBreaks and
62  * recalculate the reference vote.
63  * Also calculate the average distance between first and second.
64  *
65  * At the end, if the staticBreaks are below mStaticBreakRatio of the sample range,
66  * and they appear together in more than mTogetherRatio of the frames,
67  * and the second is closer to first than the current closest track,
68  * replace the current closest track with second.
69  *
70  * At the end, choose the first<->second combination with the lowest rate of static breaks.
71  *
72  * This will always create a cluster of two tracks.
73  */
74 
75  int commonPositions = 0;
76  double averageDistance = 0;
77 
78  // Go over all objects in the first object set.
79  for(unsigned int i = 0; i < first->mObjectSet->objects.size(); i++)
80  {
81  boost::shared_ptr<ISM::Object> firstObject = first->mObjectSet->objects[i];
82  boost::shared_ptr<ISM::Object> secondObject = second->mObjectSet->objects[i];
83 
84  // Both objects not empty?
85  if (!firstObject || !secondObject)
86  {
87  continue;
88  }
89 
90  // Calculate average distance.
91  averageDistance += MathHelper::getDistanceBetweenPoints(firstObject->pose->point->eigen, secondObject->pose->point->eigen);
92 
93  // +1 for common position couter.
94  commonPositions++;
95  }
96 
97  // Not enough common positions over all frames? Kick kombination!
98  if(commonPositions < (double) first->mObjectSet->objects.size() * mTogetherRatio)
99  {
100  continue;
101  }
102 
103  // Calculate the average distance.
104  averageDistance /= (double) commonPositions;
105 
106  int staticBreaks = 0;
107  bool firstRun = true;
108  Eigen::Vector3d directionVector;
109 
110  // Go over all objects in the first object set again
111  for(unsigned int i = 0; i < first->mObjectSet->objects.size(); i++)
112  {
113  boost::shared_ptr<ISM::Object> firstObject = first->mObjectSet->objects[i];
114  boost::shared_ptr<ISM::Object> secondObject = second->mObjectSet->objects[i];
115 
116  // Both objects not empty?
117  if (!firstObject || !secondObject)
118  {
119  continue;
120  }
121 
122  // This is first run? Set reference direction vector.
123  if (firstRun) {
124  directionVector = this->getDirectionVector(firstObject, secondObject);
125  firstRun = false;
126  continue;
127  }
128 
129  // Calculate deviation between reference and current direction vector.
130  Eigen::Vector3d currentDirection = this->getDirectionVector(firstObject, secondObject);
131  double deviation = MathHelper::rad2deg(acos(directionVector.dot(currentDirection)));
132 
133  // It deviation bigger than threshold, note a break in continuity.
134  if (deviation > mMaxAngleDeviation)
135  {
136  staticBreaks++;
137  directionVector = currentDirection;
138  }
139  }
140 
141  // Check, if the current association of tracks is valid.
142  if (
143  ((double) staticBreaks < ((double) commonPositions) * mStaticBreakRatio) &&
144  (!currentBest || (currentClosestDistance > averageDistance))
145  )
146  {
147  currentBest = second;
148  currentClosestDistance = averageDistance;
149  currentBestBreaks = staticBreaks;
150  currentBestCommonPositions = commonPositions;
151  }
152  }
153 
154  if(currentBest) {
155  double conf = 1 - (double) currentBestBreaks / (double) currentBestCommonPositions;
156  if(candidates.empty()
157  || (conf > this->score
158  || (conf == this->score && bestDistance > currentClosestDistance)))
159  {
160  // Delete old candidates and add the currently two best ones to the list.
161  candidates.clear();
162  candidates.push_back(first);
163  candidates.push_back(currentBest);
164 
165  // Save the score of the best cluster...
166  this->score = conf;
167 
168  // ... and the best distance.
169  bestDistance = currentClosestDistance;
170  }
171  }
172  }
173  }
174 
176  {
177  // The closest distance between two objects.
178  double bestDistance = std::numeric_limits<double>::max();
179 
180  // Iterate over all object sets.
181  BOOST_FOREACH(boost::shared_ptr<TreeNode> first, pNodes)
182  {
183  // The currently best trajectory.
184  boost::shared_ptr<TreeNode> currentBest;
185 
186  double currentClosestDistance = std::numeric_limits<double>::max();
187  int currentBestBreaks = 1;
188  int currentBestCommonPositions = 1;
189 
190  /*
191  * What we do:
192  * Calculate a direction Vector from first to second for every Frame.
193  * Check in every frame the angle between the reference vector (first vector) and the current vector.
194  * If the misalignment is more than mMaxAngleDeviation degrees, increase staticBreaks and
195  * recalculate the reference vote.
196  * Also calculate the average distance between first and second.
197  *
198  * At the end, if the staticBreaks are below mStaticBreakRatio of the sample range,
199  * and they appear together in more than mTogetherRatio of the frames,
200  * and the second is closer to first than the current closest track,
201  * replace the current closest track with second.
202  *
203  * At the end, choose the first<->second combination with the lowest rate of static breaks.
204  *
205  * This will always create a cluster of two tracks.
206  */
207 
208  int commonPositions = 0;
209  double averageDistance = 0;
210 
211  // Go over all objects in the first object set.
212  for(unsigned int i = 0; i < first->mObjectSet->objects.size(); i++)
213  {
214  boost::shared_ptr<ISM::Object> firstObject = first->mObjectSet->objects[i];
215  boost::shared_ptr<ISM::Object> secondObject = pChild->mObjectSet->objects[i];
216 
217  // Both objects not empty?
218  if (!firstObject || !secondObject)
219  continue;
220 
221  // Calculate average distance.
222  averageDistance += MathHelper::getDistanceBetweenPoints(firstObject->pose->point->eigen, secondObject->pose->point->eigen);
223 
224  // +1 for common position couter.
225  commonPositions++;
226  }
227 
228  // Not enough common positions over all frames? Kick kombination!
229  if(commonPositions < (double) first->mObjectSet->objects.size() * mTogetherRatio)
230  continue;
231 
232  // Calculate the average distance.
233  averageDistance /= (double) commonPositions;
234 
235  int staticBreaks = 0;
236  bool firstRun = true;
237  Eigen::Vector3d directionVector;
238 
239  // Go over all objects in the first object set again
240  for(unsigned int i = 0; i < first->mObjectSet->objects.size(); i++)
241  {
242  boost::shared_ptr<ISM::Object> firstObject = first->mObjectSet->objects[i];
243  boost::shared_ptr<ISM::Object> secondObject = pChild->mObjectSet->objects[i];
244 
245  // Both objects not empty?
246  if (!firstObject || !secondObject)
247  {
248  continue;
249  }
250 
251  // This is first run? Set reference direction vector.
252  if (firstRun) {
253  directionVector = this->getDirectionVector(firstObject, secondObject);
254  firstRun = false;
255  continue;
256  }
257 
258  // Calculate deviation between reference and current direction vector.
259  Eigen::Vector3d currentDirection = this->getDirectionVector(firstObject, secondObject);
260  double deviation = MathHelper::rad2deg(acos(directionVector.dot(currentDirection)));
261 
262  // It deviation bigger than threshold, note a break in continuity.
263  if (deviation > mMaxAngleDeviation)
264  {
265  staticBreaks++;
266  directionVector = currentDirection;
267  }
268  }
269 
270  // Check, if the current association of tracks is valid.
271  if (
272  ((double) staticBreaks < ((double) commonPositions) * mStaticBreakRatio) &&
273  (!currentBest || (currentClosestDistance > averageDistance))
274  )
275  {
276  currentBest = pChild;
277  currentClosestDistance = averageDistance;
278  currentBestBreaks = staticBreaks;
279  currentBestCommonPositions = commonPositions;
280  }
281 
282  if (currentBest) {
283  double conf = 1 - (double) currentBestBreaks / (double) currentBestCommonPositions;
284  if (candidates.empty()
285  || (conf > this->score
286  || (conf == this->score && bestDistance > currentClosestDistance)))
287  {
288  // Delete old candidates and add the currently two best ones to the list.
289  candidates.clear();
290  candidates.push_back(first);
291  candidates.push_back(currentBest);
292 
293  // Save the score of the best cluster...
294  this->score = conf;
295 
296  // ... and the best distance.
297  bestDistance = currentClosestDistance;
298  }
299  }
300  }
301  }
302 
304  {
305  // The new root object of this subtree.
306  // It's the object that either appears most frequent or the one that moves at least.
308 
309  // That means how often we've seen the most frequent object (in percent).
310  double bestViewRatio = 0;
311 
312  // The sum of movements of the at least moving object.
313  double bestMovement = 0;
314 
315  BOOST_FOREACH(boost::shared_ptr<TreeNode> candidate, candidates)
316  {
317 
318 
319  // Counter for the view ratio.
320  int views = 0;
321 
322  // Temporary variable for storing the movement.
323  double movement = 0;
324 
325  // The last object.
327 
328  // Iterate over all object in the track and determine the number of views and the sum of movements.
329  BOOST_FOREACH(boost::shared_ptr<ISM::Object> object, candidate->mObjectSet->objects)
330  {
331  if(object)
332  {
333  views++;
334 
335  if (lastObject) {
336  movement += MathHelper::getDistanceBetweenPoints(object->pose->point->eigen, lastObject->pose->point->eigen);
337  }
338  lastObject = object;
339  }
340  }
341 
342  // Calculate the numbers specified above.
343  double ratio = (double) views / (double) candidate->mObjectSet->objects.size();
344  if (ratio > bestViewRatio || (ratio == bestViewRatio && movement < bestMovement)) {
345  bestViewRatio = ratio;
346  bestMovement = movement;
347  root = candidate;
348  }
349  }
350 
351  // Add all other nodes as children to the root node.
352  BOOST_FOREACH(boost::shared_ptr<TreeNode> candidate, candidates)
353  if(candidate != root)
354  root->addChild(candidate);
355 
356  // Return a new cluster.
357  return root;
358  }
359 
361  {
362  return (!candidates.empty()) ? candidates[0] : boost::shared_ptr<TreeNode>();
363  }
364 
366  const boost::shared_ptr<ISM::Object> second)
367  {
368  // Calculate the spatial difference between both positions.
369  Eigen::Vector3d firstToSecond = second->pose->point->eigen - first->pose->point->eigen;
370 
371  // Get orientation of first object.
372  Eigen::Quaternion<double> firstRotation = first->pose->quat->eigen;
373 
374  // ???
375  return firstRotation.inverse()._transformVector(firstToSecond).normalized();
376  }
377 
378 }
boost::shared_ptr< TreeNode > getBestParentNode()
DirectionRelationHeuristic(const double pStaticBreakRatio, const double pTogetherRatio, const double pMaxAngleDeviation)
static double getDistanceBetweenPoints(const Eigen::Vector3d p1, const Eigen::Vector3d p2)
Definition: MathHelper.cpp:22
Eigen::Vector3d getDirectionVector(const boost::shared_ptr< ISM::Object > first, const boost::shared_ptr< ISM::Object > second)
void apply(std::vector< boost::shared_ptr< TreeNode > > pNodes)
static double rad2deg(double rad)
Definition: MathHelper.cpp:30
std::vector< boost::shared_ptr< TreeNode > > candidates


asr_relation_graph_generator
Author(s): Meißner Pascal
autogenerated on Fri Nov 15 2019 03:39:19