TwoStage.cpp 8.8 KB

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