TwoStage.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. //
  2. // Created by wrede on 25.04.16.
  3. //
  4. #include "TwoStage.h"
  5. namespace algo
  6. {
  7. TwoStage::TwoStage(size_t max_frame_skip, double penalty_value,
  8. size_t max_tracklet_count)
  9. {
  10. max_frame_skip_ = max_frame_skip;
  11. penalty_value_ = penalty_value;
  12. max_tracklet_count_ = max_tracklet_count;
  13. }
  14. DirectedGraph TwoStage::CreateObjectGraph(core::DetectionSequence detections)
  15. {
  16. DirectedGraph graph;
  17. std::vector<std::vector<Vertex>> layers;
  18. // Add source as the vertex with the lowest index
  19. Vertex source = boost::add_vertex(core::ObjectData(), graph);
  20. // Add vertices from detection sequence to directed graph
  21. // Save the vertices which are in one frame/layer for later use to
  22. // link easily between vertices in adjacent frames/layers
  23. for (size_t i = 0; i < detections.GetFrameCount(); ++i)
  24. {
  25. std::vector<Vertex> layer;
  26. for (size_t j = 0; j < detections.GetObjectCount(i); ++j)
  27. {
  28. Vertex v =
  29. boost::add_vertex(detections.GetObject(i, j), graph);
  30. layer.push_back(v);
  31. }
  32. layers.push_back(layer);
  33. }
  34. // Add sink as the vertex with the highest index
  35. Vertex sink = boost::add_vertex(core::ObjectData(), graph);
  36. // Vertex objects
  37. VertexValueMap values = boost::get(boost::vertex_name, graph);
  38. // Create edges
  39. for (size_t i = 0; i < layers.size(); ++i)
  40. {
  41. // For each edge in this frame/layer
  42. for (size_t j = 0; j < layers[i].size(); ++j)
  43. {
  44. Vertex u = layers[i][j];
  45. // For each next frame/layer until maxFrameSkip or end
  46. for (size_t k = 1;
  47. k < max_frame_skip_ && i + k < layers.size();
  48. ++k)
  49. {
  50. // To every edge in the next frame/layer
  51. for (size_t l = 0; l < layers[i + k].size(); ++l)
  52. {
  53. Vertex v = layers[i + k][l];
  54. boost::add_edge(u, v,
  55. values[u].CompareTo(&values[v]),
  56. graph);
  57. }
  58. }
  59. // From source to vertex and from vertex to sink
  60. boost::add_edge(source, u,
  61. (i + 1) * penalty_value_,
  62. graph);
  63. boost::add_edge(u, sink,
  64. (layers.size() - i) * penalty_value_,
  65. graph);
  66. }
  67. }
  68. obj_graph_ = graph;
  69. frame_count_ = layers.size();
  70. return graph;
  71. }
  72. DirectedGraph TwoStage::CreateTrackletGraph()
  73. {
  74. return CreateTrackletGraph(obj_graph_, frame_count_);
  75. }
  76. DirectedGraph TwoStage::CreateTrackletGraph(DirectedGraph obj_graph,
  77. size_t frame_count)
  78. {
  79. DirectedGraph tlt_graph;
  80. // Add source to tracklet graph
  81. Vertex tlt_src = boost::add_vertex(core::ObjectData(), tlt_graph);
  82. // Prepare parameter for dijkstra
  83. size_t obj_graph_size = boost::num_vertices(obj_graph);
  84. std::vector<Vertex> obj_pred_list(obj_graph_size);
  85. std::vector<double> obj_dist_list(obj_graph_size);
  86. VertexIndexMap obj_indices = boost::get(boost::vertex_index, obj_graph);
  87. VertexValueMap obj_values = boost::get(boost::vertex_name, obj_graph);
  88. PredecessorMap obj_pred_map(&obj_pred_list[0], obj_indices);
  89. DistanceMap obj_dist_map(&obj_dist_list[0], obj_indices);
  90. // Source and sink of the object graph
  91. Vertex obj_src = obj_indices[0];
  92. Vertex obj_snk = obj_indices[obj_graph_size - 1];
  93. // Iteratively run dijkstra to extract tracklets
  94. for (size_t i = 0; i < max_tracklet_count_; ++i)
  95. {
  96. boost::dijkstra_shortest_paths(obj_graph, obj_src,
  97. boost::predecessor_map(obj_pred_map)
  98. .distance_map(obj_dist_map));
  99. // Create the tracklet
  100. core::Tracklet tracklet;
  101. Vertex v = obj_snk;
  102. for (Vertex u = obj_pred_map[obj_snk];
  103. u != v;
  104. v = u, u = obj_pred_map[v])
  105. {
  106. tracklet.AddPathObjectFirst(obj_values[u]);
  107. // Leave source and sink untouched
  108. if (!obj_values[u].IsVirtual())
  109. {
  110. // Remove the path by setting all used edges to a weight of
  111. // infinity
  112. std::pair<DirectedGraph::out_edge_iterator,
  113. DirectedGraph::out_edge_iterator>
  114. edge_iter = boost::out_edges(u, obj_graph);
  115. for (DirectedGraph::out_edge_iterator iter = edge_iter.first;
  116. iter != edge_iter.second;
  117. ++iter)
  118. {
  119. boost::get(boost::edge_weight, obj_graph, *iter)
  120. = std::numeric_limits<double>::infinity();
  121. }
  122. }
  123. }
  124. // Add tracklet into tracklet graph
  125. boost::add_vertex(tracklet, tlt_graph);
  126. }
  127. // Add sink to tracklet graph
  128. Vertex tlt_snk = boost::add_vertex(core::ObjectData(), tlt_graph);
  129. // Create edges
  130. size_t tlt_graph_size = boost::num_vertices(tlt_graph);
  131. VertexIndexMap tlt_indices = boost::get(boost::vertex_index, tlt_graph);
  132. VertexValueMap tlt_values = boost::get(boost::vertex_name, tlt_graph);
  133. // For every tracklet but source and sink
  134. for (size_t i = 1; i < tlt_graph_size - 1; ++i)
  135. {
  136. Vertex u = tlt_indices[i];
  137. size_t u_first_frame =
  138. ((core::Tracklet)tlt_values[u]).GetFirstFrameIndex();
  139. size_t u_last_frame =
  140. ((core::Tracklet)tlt_values[u]).GetLastFrameIndex();
  141. // Create edges between tracklets
  142. for (size_t j = 1; j < tlt_graph_size - 1; ++j)
  143. {
  144. if (i != j)
  145. {
  146. Vertex v = tlt_indices[j];
  147. size_t v_first_frame =
  148. ((core::Tracklet)tlt_values[v]).GetFirstFrameIndex();
  149. if (u_last_frame < v_first_frame)
  150. {
  151. boost::add_edge(u, v,
  152. tlt_values[u].CompareTo(&tlt_values[v]),
  153. tlt_graph);
  154. }
  155. }
  156. }
  157. // From source
  158. boost::add_edge(tlt_src, u,
  159. (u_first_frame + 1) * penalty_value_,
  160. tlt_graph);
  161. // To sink
  162. boost::add_edge(u, tlt_snk,
  163. (frame_count - u_last_frame) * penalty_value_,
  164. tlt_graph);
  165. }
  166. tlt_graph_ = tlt_graph;
  167. return tlt_graph;
  168. }
  169. std::vector<core::Tracklet> TwoStage::ExtractTracks()
  170. {
  171. return ExtractTracks(tlt_graph_);
  172. }
  173. std::vector<core::Tracklet> TwoStage::ExtractTracks(DirectedGraph tlt_graph)
  174. {
  175. std::vector<core::Tracklet> tracks;
  176. //TODO implement
  177. //TODO convert tracklets graph into list of tracklets/tracks
  178. return tracks;
  179. }
  180. }