main.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. //
  2. // Created by wrede on 19.04.16.
  3. //
  4. #include "../core/DetectionSequence.h"
  5. #include "../util/FileIO.h"
  6. #include "../util/Parser.h"
  7. #include "../algo/NStage.h"
  8. #include "../algo/KShortestPaths.h"
  9. #include "../util/Visualizer.h"
  10. #include "../util/Logger.h"
  11. #include "../core/ObjectDataAngular.h"
  12. #include "../algo/Berclaz.h"
  13. #include "../algo/KShortestPaths2.h"
  14. #include "../algo/KShortestPaths3.h"
  15. #include "../algo/KShortestPaths4.h"
  16. #include <boost/program_options.hpp>
  17. #include <boost/graph/named_function_params.hpp>
  18. #include <boost/graph/bellman_ford_shortest_paths.hpp>
  19. struct
  20. {
  21. size_t max_frame_skip;
  22. std::string max_tracklet_count;
  23. std::string penalty_value;
  24. } n_stage_params;
  25. void RunNStage(core::DetectionSequence& sequence,
  26. std::vector<core::TrackletPtr>& tracks)
  27. {
  28. util::Logger::LogInfo("Running n-stage");
  29. std::vector<double> penalty_values;
  30. std::vector<size_t> max_tracklet_counts;
  31. // Parse strings to vectors
  32. size_t d_index;
  33. std::string str, part;
  34. str = n_stage_params.max_tracklet_count;
  35. do
  36. {
  37. d_index = str.find(",");
  38. part = str.substr(0, d_index);
  39. if (part.size() > 0)
  40. {
  41. max_tracklet_counts.push_back((unsigned long&&) atoi(part.c_str()));
  42. }
  43. str = str.substr(d_index + 1);
  44. }
  45. while (d_index != std::string::npos);
  46. str = n_stage_params.penalty_value;
  47. do
  48. {
  49. d_index = str.find(",");
  50. part = str.substr(0, d_index);
  51. if (part.size() > 0)
  52. {
  53. penalty_values.push_back(std::atof(part.c_str()));
  54. }
  55. str = str.substr(d_index + 1);
  56. }
  57. while (d_index != std::string::npos);
  58. // Init n stage
  59. algo::NStage n_stage(n_stage_params.max_frame_skip,
  60. penalty_values, max_tracklet_counts);
  61. n_stage.Run(sequence, tracks);
  62. // Interpolate tracks
  63. for (auto track : tracks)
  64. {
  65. track->InterpolateMissingFrames();
  66. }
  67. util::Logger::LogInfo("Finished");
  68. }
  69. struct
  70. {
  71. int h_res;
  72. int v_res;
  73. int vicinity_size;
  74. size_t batch_size;
  75. size_t max_track_count;
  76. } berclaz_params;
  77. void RunBerclaz(core::DetectionSequence& sequence,
  78. std::vector<core::TrackletPtr>& tracks)
  79. {
  80. util::Logger::LogInfo("Running berclaz");
  81. // Init berclaz
  82. algo::Berclaz berclaz(berclaz_params.h_res,
  83. berclaz_params.v_res,
  84. berclaz_params.vicinity_size);
  85. berclaz.Run(sequence, berclaz_params.batch_size,
  86. berclaz_params.max_track_count, tracks);
  87. util::Logger::LogInfo("Interpolate tracks");
  88. // Interpolate tracks
  89. for (auto track : tracks)
  90. {
  91. track->InterpolateMissingFrames();
  92. }
  93. util::Logger::LogInfo("Finished");
  94. }
  95. void Run(int argc, char** argv)
  96. {
  97. // Algorithm independent values
  98. std::string input_file, output_file, images_folder, algorithm, config_path, header, input_format;
  99. bool info, debug, display;
  100. char input_delimiter, output_delimiter;
  101. double temporal_weight, spatial_weight, angular_weight, image_width, image_height;
  102. boost::program_options::options_description opts("Allowed options");
  103. opts.add_options()
  104. ("help",
  105. "produce help message")
  106. ("info",
  107. boost::program_options::value<bool>(&info)
  108. ->default_value(false),
  109. "if the program should show progress information")
  110. ("debug",
  111. boost::program_options::value<bool>(&debug)
  112. ->default_value(false),
  113. "if the program should show debug messages")
  114. ("display",
  115. boost::program_options::value<bool>(&display)
  116. ->default_value(false),
  117. "if a window with the images and the detected tracks should be opened")
  118. ("config",
  119. boost::program_options::value<std::string>(&config_path),
  120. "the path to the config file, if no path is given the command line arguments are read")
  121. ("input-file",
  122. boost::program_options::value<std::string>(&input_file),
  123. "set detections file path")
  124. ("output-file",
  125. boost::program_options::value<std::string>(&output_file),
  126. "set the output file path")
  127. ("output-delimiter",
  128. boost::program_options::value<char>(&output_delimiter)
  129. ->default_value(';'),
  130. "the delimiter used to separate values in the specified output file")
  131. ("images-folder",
  132. boost::program_options::value<std::string>(&images_folder),
  133. "set images folder path")
  134. ("input-header",
  135. boost::program_options::value<std::string>(&header),
  136. "sets the input header, this value is optional if the input file has a header labeling the values,"
  137. "the delimiter used for the header needs to be the same as for the rest of the file")
  138. ("input-format",
  139. boost::program_options::value<std::string>(&input_format)
  140. ->default_value("ObjectData"),
  141. "the format the input should be parsed into, valid formats are: "
  142. "2D, Box, Angular")
  143. ("input-delimiter",
  144. boost::program_options::value<char>(&input_delimiter)
  145. ->default_value(';'),
  146. "the delimiter used to separate values in the specified input file")
  147. ("image-width",
  148. boost::program_options::value<double>(&image_width)
  149. ->default_value(1),
  150. "the width of the image")
  151. ("image-height",
  152. boost::program_options::value<double>(&image_height)
  153. ->default_value(1),
  154. "the height of the image")
  155. ("algorithm",
  156. boost::program_options::value<std::string>(&algorithm),
  157. "set the algorithm to use, current viable options: n-stage berclaz")
  158. ("max-frame-skip",
  159. boost::program_options::value<size_t>(&n_stage_params.max_frame_skip)
  160. ->default_value(1),
  161. "(n stage) set the maximum number of frames a track can skip between two detections,"
  162. " if set to less or equal than zero all frames are linked")
  163. ("max-tracklet-count",
  164. boost::program_options::value<std::string>(&n_stage_params.max_tracklet_count)
  165. ->default_value("-1,1"),
  166. "(n stage) set the maximum number of tracklets to be extracted")
  167. ("penalty-value",
  168. boost::program_options::value<std::string>(&n_stage_params.penalty_value)
  169. ->default_value("0,0"),
  170. "(n stage) set the penalty value for edges from and to source and sink")
  171. ("temporal-weight",
  172. boost::program_options::value<double>(&temporal_weight)
  173. ->default_value(1.0),
  174. "(n stage) temporal weight for difference calculations between two detections")
  175. ("spatial-weight",
  176. boost::program_options::value<double>(&spatial_weight)
  177. ->default_value(1.0),
  178. "(n stage) spatial weight for difference calculations between two detections")
  179. ("angular-weight",
  180. boost::program_options::value<double>(&angular_weight)
  181. ->default_value(1.0),
  182. "(n stage) angular weight for difference calculations between two detections")
  183. ("horizontal-resolution",
  184. boost::program_options::value<int>(&berclaz_params.h_res)
  185. ->default_value(10),
  186. "(berclaz) the number of horizontal grid cells")
  187. ("vertical-resolution",
  188. boost::program_options::value<int>(&berclaz_params.v_res)
  189. ->default_value(10),
  190. "(berclaz) the number of vertical grid cells")
  191. ("vicinity-size",
  192. boost::program_options::value<int>(&berclaz_params.vicinity_size)
  193. ->default_value(1),
  194. "(berclaz) the vicinity size, the number of cells a detection can travel between two frames")
  195. ("max-track-count",
  196. boost::program_options::value<size_t>(&berclaz_params.max_track_count)
  197. ->default_value(1),
  198. "(berclaz) the maximal number of tracks to extract")
  199. ("batch-size",
  200. boost::program_options::value<size_t>(&berclaz_params.batch_size)
  201. ->default_value(100),
  202. "(berclaz) the size of one processing batch");
  203. boost::program_options::variables_map opt_var_map;
  204. #pragma clang diagnostic push
  205. #pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
  206. boost::program_options::store(
  207. boost::program_options::parse_command_line(argc, argv, opts),
  208. opt_var_map);
  209. #pragma clang diagnostic pop
  210. boost::program_options::notify(opt_var_map);
  211. // Display help
  212. if (opt_var_map.count("help") != 0)
  213. {
  214. std::cout << opts << std::endl;
  215. exit(0);
  216. }
  217. // Read config
  218. if (opt_var_map.count("config") != 0)
  219. {
  220. std::ifstream config_file(config_path, std::ifstream::in);
  221. if (config_file.is_open())
  222. {
  223. boost::program_options::store(
  224. boost::program_options::parse_config_file(config_file,
  225. opts),
  226. opt_var_map);
  227. config_file.close();
  228. boost::program_options::notify(opt_var_map);
  229. }
  230. else
  231. {
  232. util::Logger::LogError("Unable to open config file!");
  233. exit(0);
  234. }
  235. }
  236. else if (opt_var_map.count("input-file") == 0 ||
  237. opt_var_map.count("input-format") == 0 ||
  238. opt_var_map.count("output-file") == 0)
  239. {
  240. std::cout << opts << std::endl;
  241. exit(0);
  242. }
  243. // Enable info logging
  244. if (info != 0)
  245. {
  246. util::Logger::SetInfo(true);
  247. util::Logger::LogInfo("Enabled");
  248. }
  249. // Enable debug logging
  250. if (debug != 0)
  251. {
  252. util::Logger::SetDebug(true);
  253. util::Logger::LogDebug("Enabled");
  254. }
  255. // Reading the input file
  256. util::Logger::LogInfo("Reading input");
  257. util::ValueMapVector values;
  258. try
  259. {
  260. if (header.size() > 0)
  261. {
  262. util::FileIO::ReadCSV(values, header, input_file, input_delimiter);
  263. }
  264. else
  265. {
  266. util::FileIO::ReadCSV(values, input_file, input_delimiter);
  267. }
  268. }
  269. catch (std::exception& e)
  270. {
  271. util::Logger::LogError("Failed to read input file!");
  272. util::Logger::LogError(e.what());
  273. exit(0);
  274. }
  275. // Parsing the read input
  276. core::DetectionSequence sequence;
  277. if (input_format == "2D")
  278. {
  279. util::Parser::ParseObjectData2D(values,
  280. sequence,
  281. image_width,
  282. image_height,
  283. temporal_weight,
  284. spatial_weight);
  285. }
  286. else if (input_format == "Box")
  287. {
  288. util::Parser::ParseObjectDataBox(values,
  289. sequence,
  290. image_width,
  291. image_height,
  292. temporal_weight,
  293. spatial_weight);
  294. }
  295. else if (input_format == "Angular")
  296. {
  297. util::Parser::ParseObjectDataAngular(values,
  298. sequence,
  299. image_width,
  300. image_height,
  301. temporal_weight,
  302. spatial_weight,
  303. angular_weight);
  304. }
  305. else
  306. {
  307. // No valid input-format specified
  308. std::cout << opts << std::endl;
  309. exit(0);
  310. }
  311. // Running the specified algorithm
  312. std::vector<core::TrackletPtr> tracks;
  313. time_t begin_time, end_time;
  314. util::Logger::LogInfo("Start time measurement");
  315. begin_time = time(0);
  316. if (algorithm == "n-stage")
  317. {
  318. RunNStage(sequence, tracks);
  319. }
  320. else if (algorithm == "berclaz")
  321. {
  322. RunBerclaz(sequence, tracks);
  323. }
  324. else
  325. {
  326. // No valid algorithm specified
  327. std::cout << opts << std::endl;
  328. exit(0);
  329. }
  330. end_time = time(0);
  331. util::Logger::LogInfo("Time measurement stopped");
  332. util::Logger::LogInfo("Time passed: "
  333. + std::to_string(difftime(end_time, begin_time) / 60.0)
  334. + " minutes");
  335. // Write the output file
  336. util::FileIO::WriteTracks(tracks, output_file, output_delimiter);
  337. // Display the tracking data
  338. if (display)
  339. {
  340. util::Visualizer vis;
  341. if (algorithm == "berclaz")
  342. vis.Display(tracks, images_folder, "Visualizer",
  343. 0, 24, berclaz_params.h_res, berclaz_params.v_res);
  344. else
  345. vis.Display(tracks, images_folder);
  346. }
  347. }
  348. void CreateTestGraph(DirectedGraph& graph, Vertex& source, Vertex& sink)
  349. {
  350. // Create test graph (suurballe wikipedia example)
  351. // std::vector<Vertex> vertices;
  352. // for (size_t i = 0; i < 6; ++i)
  353. // {
  354. // vertices.push_back(
  355. // boost::add_vertex(
  356. // core::ObjectDataPtr(new core::ObjectData(i)),graph));
  357. // }
  358. //
  359. // // AB
  360. // boost::add_edge(vertices[0], vertices[1], 1.0, graph);
  361. // boost::add_edge(vertices[1], vertices[0], 1.0, graph);
  362. //
  363. // // AC
  364. // boost::add_edge(vertices[0], vertices[2], 2.0, graph);
  365. // boost::add_edge(vertices[2], vertices[0], 2.0, graph);
  366. //
  367. // // BD
  368. // boost::add_edge(vertices[1], vertices[3], 1.0, graph);
  369. // boost::add_edge(vertices[3], vertices[1], 1.0, graph);
  370. //
  371. // // BE
  372. // boost::add_edge(vertices[1], vertices[4], 2.0, graph);
  373. // boost::add_edge(vertices[4], vertices[1], 2.0, graph);
  374. //
  375. // // CD
  376. // boost::add_edge(vertices[2], vertices[3], 2.0, graph);
  377. // boost::add_edge(vertices[3], vertices[2], 2.0, graph);
  378. //
  379. // // DF
  380. // boost::add_edge(vertices[3], vertices[5], 1.0, graph);
  381. // boost::add_edge(vertices[5], vertices[3], 1.0, graph);
  382. //
  383. // // EF
  384. // boost::add_edge(vertices[4], vertices[5], 2.0, graph);
  385. // boost::add_edge(vertices[5], vertices[4], 2.0, graph);
  386. //
  387. // source = vertices[0];
  388. // sink = vertices[5];
  389. // Create test graph
  390. std::vector<Vertex> vertices;
  391. for (size_t i = 0; i < 11; ++i)
  392. {
  393. vertices.push_back(
  394. boost::add_vertex(
  395. core::ObjectDataPtr(new core::ObjectData(i)),graph));
  396. }
  397. // boost::add_edge(vertices[0], vertices[1], 0.0, graph);
  398. // boost::add_edge(vertices[0], vertices[8], 0.0, graph);
  399. // boost::add_edge(vertices[0], vertices[4], 0.0, graph);
  400. // boost::add_edge(vertices[1], vertices[2], -1.0, graph);
  401. // boost::add_edge(vertices[1], vertices[5], -1.0, graph);
  402. // boost::add_edge(vertices[2], vertices[3], -1.0, graph);
  403. // boost::add_edge(vertices[2], vertices[6], -1.0, graph);
  404. // boost::add_edge(vertices[2], vertices[10], -1.0, graph);
  405. // boost::add_edge(vertices[3], vertices[7], 4.0, graph);
  406. // boost::add_edge(vertices[4], vertices[2], 1.0, graph);
  407. // boost::add_edge(vertices[4], vertices[5], 1.0, graph);
  408. // boost::add_edge(vertices[4], vertices[9], 1.0, graph);
  409. // boost::add_edge(vertices[5], vertices[6], 2.0, graph);
  410. // boost::add_edge(vertices[5], vertices[3], 2.0, graph);
  411. // boost::add_edge(vertices[6], vertices[7], 4.0, graph);
  412. // boost::add_edge(vertices[8], vertices[2], -3.0, graph);
  413. // boost::add_edge(vertices[8], vertices[9], -3.0, graph);
  414. // boost::add_edge(vertices[9], vertices[3], 3.0, graph);
  415. // boost::add_edge(vertices[9], vertices[10], 3.0, graph);
  416. // boost::add_edge(vertices[10], vertices[7], 4.0, graph);
  417. source = vertices[0];
  418. sink = vertices[10];
  419. for (int i = 1; i < vertices.size() - 1; ++i)
  420. {
  421. boost::add_edge(source, vertices[i], 0.0, graph);
  422. }
  423. boost::add_edge(vertices[1], vertices[4], -1.0, graph);
  424. boost::add_edge(vertices[1], vertices[5], -1.0, graph);
  425. boost::add_edge(vertices[1], vertices[10], 0.0, graph);
  426. boost::add_edge(vertices[4], vertices[7], -1.0, graph);
  427. boost::add_edge(vertices[4], vertices[8], -1.0, graph);
  428. boost::add_edge(vertices[4], vertices[10], 0.0, graph);
  429. boost::add_edge(vertices[7], vertices[10], -1.0, graph);
  430. boost::add_edge(vertices[2], vertices[4], -2.0, graph);
  431. boost::add_edge(vertices[2], vertices[5], -2.0, graph);
  432. boost::add_edge(vertices[2], vertices[6], -2.0, graph);
  433. boost::add_edge(vertices[2], vertices[10], 0.0, graph);
  434. boost::add_edge(vertices[5], vertices[7], -2.0, graph);
  435. boost::add_edge(vertices[5], vertices[8], -2.0, graph);
  436. boost::add_edge(vertices[5], vertices[9], -2.0, graph);
  437. boost::add_edge(vertices[5], vertices[10], 0.0, graph);
  438. boost::add_edge(vertices[8], vertices[10], -2.0, graph);
  439. boost::add_edge(vertices[3], vertices[5], -3.0, graph);
  440. boost::add_edge(vertices[3], vertices[6], -3.0, graph);
  441. boost::add_edge(vertices[3], vertices[10], 0.0, graph);
  442. boost::add_edge(vertices[6], vertices[8], -3.0, graph);
  443. boost::add_edge(vertices[6], vertices[9], -3.0, graph);
  444. boost::add_edge(vertices[6], vertices[10], 0.0, graph);
  445. boost::add_edge(vertices[9], vertices[10], -3.0, graph);
  446. // Connect all with source and sink
  447. // boost::add_edge(vertices[1], sink, 0, graph);
  448. // boost::add_edge(source, vertices[2], 0, graph);
  449. // boost::add_edge(vertices[2], sink, 0, graph);
  450. // boost::add_edge(source, vertices[3], 0, graph);
  451. // boost::add_edge(vertices[4], sink, 0, graph);
  452. // boost::add_edge(source, vertices[5], 0, graph);
  453. // boost::add_edge(vertices[5], sink, 0, graph);
  454. // boost::add_edge(source, vertices[6], 0, graph);
  455. // boost::add_edge(vertices[8], sink, 0, graph);
  456. // boost::add_edge(source, vertices[9], 0, graph);
  457. // boost::add_edge(vertices[9], sink, 0, graph);
  458. // boost::add_edge(source, vertices[10], 0, graph);
  459. // boost::add_edge(vertices[1], vertices[7], 0.0, graph);
  460. // boost::add_edge(vertices[8], vertices[7], 0.0, graph);
  461. }
  462. void TestKSP(DirectedGraph graph, Vertex source, Vertex sink, size_t n_paths)
  463. {
  464. util::FileIO::WriteCSVMatlab(graph, "/home/wrede/Dokumente/graph_ksp.csv");
  465. algo::KShortestPaths2 ksp;
  466. MultiPredecessorMap paths = ksp.Run(graph, source, sink, n_paths);
  467. util::FileIO::WriteCSVMatlab(paths, source, sink, "/home/wrede/Dokumente/paths_ksp.csv");
  468. }
  469. void TestKBellmanFord(DirectedGraph graph, Vertex source, Vertex sink, size_t n_paths)
  470. {
  471. util::FileIO::WriteCSVMatlab(graph, "/home/wrede/Dokumente/graph_kbf.csv");
  472. MultiPredecessorMap paths;
  473. for (size_t i = 0; i < n_paths; ++i)
  474. {
  475. // Prepare variables for path finding
  476. size_t graph_size = boost::num_vertices(graph);
  477. std::vector<Vertex> pred_list(graph_size);
  478. std::vector<double> dist_list(graph_size);
  479. VertexIndexMap graph_indices = boost::get(boost::vertex_index, graph);
  480. EdgeWeightMap weight_map = boost::get(boost::edge_weight, graph);
  481. PredecessorMap pred_map(&pred_list[0], graph_indices);
  482. DistanceMap dist_map(&dist_list[0], graph_indices);
  483. // Find the shortest path
  484. boost::bellman_ford_shortest_paths(graph, graph_size,
  485. boost::root_vertex(source)
  486. .weight_map(weight_map)
  487. .predecessor_map(pred_map)
  488. .distance_map(dist_map));
  489. // Add path
  490. for (Vertex u = sink, v = pred_map[u]; u != v; u = v, v = pred_map[v])
  491. {
  492. paths[u].insert(v);
  493. if (u != sink && u != source)
  494. boost::clear_out_edges(u, graph);
  495. }
  496. }
  497. util::FileIO::WriteCSVMatlab(paths, source, sink, "/home/wrede/Dokumente/paths_kbf.csv");
  498. }
  499. void TestGrid()
  500. {
  501. int lower_index = 0;
  502. int upper_index = 5;
  503. double lower_bound = 0.0;
  504. double upper_bound = 50.0;
  505. util::Grid grid(upper_index, upper_index, upper_index,
  506. upper_bound, upper_bound, upper_bound);
  507. std::uniform_int_distribution<int> unii(lower_index, upper_index - 1);
  508. std::uniform_real_distribution<double> unif(lower_bound, upper_bound);
  509. std::default_random_engine re;
  510. // Fill with empty values
  511. std::cout << "fill with empty values\n";
  512. for (int z = lower_index; z < upper_index; ++z)
  513. {
  514. for (int y = lower_index; y < upper_index; ++y)
  515. {
  516. for (int x = lower_index; y < upper_index; ++y)
  517. {
  518. grid.SetValue(nullptr, x, y, z);
  519. }
  520. }
  521. }
  522. // Randomly add data
  523. std::cout << "randomly add data\n";
  524. for (int i = 0; i < 10; ++i)
  525. {
  526. int xi = unii(re);
  527. int yi = unii(re);
  528. int zi = unii(re);
  529. core::ObjectDataPtr value(new core::ObjectData((size_t)i));
  530. grid.SetValue(value, xi, yi, zi);
  531. std::cout << xi << "," << yi << "," << zi << " = " << *value << std::endl;
  532. }
  533. // Randomly get data
  534. std::cout << "randomly get data\n";
  535. for (int i = 0; i < 10; ++i)
  536. {
  537. double x = unif(re);
  538. double y = unif(re);
  539. double z = unif(re);
  540. std::cout << x << "," << y << "," << z << " = ";
  541. core::ObjectDataPtr value = grid.GetValue(x, y, z);
  542. if (value)
  543. {
  544. std::cout << *value << std::endl;
  545. }
  546. else
  547. {
  548. std::cout << "nullptr" << std::endl;
  549. }
  550. }
  551. }
  552. void CreateBerclazGraph(DirectedGraph& graph, Vertex& source, Vertex& sink)
  553. {
  554. util::Logger::SetDebug(true);
  555. util::Logger::SetInfo(true);
  556. util::Logger::LogInfo("Test berclaz graph");
  557. // Init grid with data
  558. util::Grid grid(3, 3, 3, 9.0, 9.0, 9.0);
  559. for (int z = 0; z < grid.GetDepthCount(); ++z)
  560. {
  561. for (int y = 0; y < grid.GetHeightCount(); ++y)
  562. {
  563. for (int x = 0; x < grid.GetWidthCount(); ++x)
  564. {
  565. core::ObjectDataPtr value(new core::ObjectData(10));
  566. grid.SetValue(value, x, y, z);
  567. }
  568. }
  569. }
  570. // Add path source->0,0,0->0,0,1->0,0,2->sink
  571. core::ObjectDataPtr value0(new core::ObjectData(1));
  572. value0->SetDetectionScore(1.0);
  573. grid.SetValue(value0, 0, 0, 0);
  574. core::ObjectDataPtr value1(new core::ObjectData(2));
  575. value1->SetDetectionScore(1.0);
  576. grid.SetValue(value1, 0, 0, 1);
  577. core::ObjectDataPtr value2(new core::ObjectData(3));
  578. value2->SetDetectionScore(1.0);
  579. grid.SetValue(value2, 0, 0, 2);
  580. // Add path source->0,1,0->0,1,1->0,1,2->sink
  581. core::ObjectDataPtr value3(new core::ObjectData(4));
  582. value3->SetDetectionScore(0.6);
  583. grid.SetValue(value3, 0, 1, 0);
  584. core::ObjectDataPtr value4(new core::ObjectData(5));
  585. value4->SetDetectionScore(0.6);
  586. grid.SetValue(value4, 0, 1, 1);
  587. core::ObjectDataPtr value5(new core::ObjectData(6));
  588. value5->SetDetectionScore(0.6);
  589. grid.SetValue(value5, 0, 1, 2);
  590. // Add path source->0,2,0->0,2,1->0,2,2->sink
  591. core::ObjectDataPtr value6(new core::ObjectData(7));
  592. value6->SetDetectionScore(0.55);
  593. grid.SetValue(value6, 0, 2, 0);
  594. core::ObjectDataPtr value7(new core::ObjectData(8));
  595. value7->SetDetectionScore(0.55);
  596. grid.SetValue(value7, 0, 2, 1);
  597. core::ObjectDataPtr value8(new core::ObjectData(9));
  598. value8->SetDetectionScore(0.55);
  599. grid.SetValue(value8, 0, 2, 2);
  600. util::Logger::LogDebug("add vertices");
  601. // Add grid vertices
  602. graph.clear();
  603. for (int z = 0; z < grid.GetDepthCount(); ++z)
  604. {
  605. for (int y = 0; y < grid.GetHeightCount(); ++y)
  606. {
  607. for (int x = 0; x < grid.GetWidthCount(); ++x)
  608. {
  609. boost::add_vertex(grid.GetValue(x, y, z), graph);
  610. }
  611. }
  612. }
  613. util::Logger::LogDebug("vertex count " + std::to_string(boost::num_vertices(graph)));
  614. util::Logger::LogDebug("edge count " + std::to_string(boost::num_edges(graph)));
  615. // Add source and sink vertex
  616. source = boost::add_vertex(core::ObjectDataPtr(new core::ObjectData()), graph);
  617. sink = boost::add_vertex(core::ObjectDataPtr(new core::ObjectData()), graph);
  618. util::Logger::LogDebug("add edges");
  619. // Iterate all vertices but source and sink
  620. VertexIndexMap vertices = boost::get(boost::vertex_index, graph);
  621. VertexValueMap values = boost::get(boost::vertex_name, graph);
  622. int vicinity_size = 1;
  623. int layer_size = grid.GetWidthCount() * grid.GetHeightCount();
  624. for (int z = 0; z < grid.GetDepthCount(); ++z)
  625. {
  626. for (int y = 0; y < grid.GetHeightCount(); ++y)
  627. {
  628. for (int x = 0; x < grid.GetWidthCount(); ++x)
  629. {
  630. // First vertex index
  631. int vi = x + y * grid.GetHeightCount() + z * layer_size;
  632. // Get the score, clamp it, prevent division by zero and
  633. // logarithm of zero
  634. double score = values[vi]->GetDetectionScore();
  635. if (score > 0.999999)
  636. {
  637. score = 0.999999;
  638. }
  639. else if (score < 0.000001)
  640. {
  641. score = 0.000001;
  642. }
  643. // Calculate the edge weight
  644. double weight = -std::log(score / (1 - score));
  645. // Connect with the next frame only if there is a next frame
  646. if (z < grid.GetDepthCount() - 1)
  647. {
  648. // Iterate all nearby cells in the next frame
  649. for (int ny = std::max(0, y - vicinity_size);
  650. ny <
  651. std::min(grid.GetHeightCount(), y + vicinity_size + 1);
  652. ++ny)
  653. {
  654. for (int nx = std::max(0, x - vicinity_size);
  655. nx < std::min(grid.GetWidthCount(),
  656. x + vicinity_size + 1);
  657. ++nx)
  658. {
  659. // Second vertex index
  660. int vj = nx + ny * grid.GetHeightCount() +
  661. (z + 1) * layer_size;
  662. // Connect to nearby cells
  663. boost::add_edge(vertices[vi], vertices[vj],
  664. weight, graph);
  665. }
  666. }
  667. boost::add_edge(vertices[vi], sink, 0.0, graph);
  668. }
  669. else
  670. {
  671. boost::add_edge(vertices[vi], sink, weight, graph);
  672. }
  673. // Connect with source and sink
  674. boost::add_edge(source, vertices[vi], 0.0, graph);
  675. }
  676. }
  677. }
  678. util::Logger::LogDebug("vertex count " + std::to_string(boost::num_vertices(graph)));
  679. util::Logger::LogDebug("edge count " + std::to_string(boost::num_edges(graph)));
  680. }
  681. void CreatePresentationGraph(DirectedGraph& graph, Vertex& source, Vertex& sink)
  682. {
  683. std::vector<Vertex> vertices;
  684. for (size_t i = 0; i < 10; ++i)
  685. {
  686. vertices.push_back(boost::add_vertex(core::ObjectDataPtr(new core::ObjectData(i)), graph));
  687. }
  688. source = vertices[0];
  689. sink = vertices[9];
  690. boost::add_edge(vertices[0], vertices[1], 0.0, graph);
  691. boost::add_edge(vertices[0], vertices[2], 0.0, graph);
  692. boost::add_edge(vertices[1], vertices[3], 12.0, graph);
  693. boost::add_edge(vertices[1], vertices[4], 15.0, graph);
  694. boost::add_edge(vertices[2], vertices[3], 15.0, graph);
  695. boost::add_edge(vertices[2], vertices[4], 10.0, graph);
  696. boost::add_edge(vertices[3], vertices[5], 15.0, graph);
  697. boost::add_edge(vertices[3], vertices[6], 12.0, graph);
  698. boost::add_edge(vertices[4], vertices[5], 12.0, graph);
  699. boost::add_edge(vertices[4], vertices[6], 11.0, graph);
  700. boost::add_edge(vertices[5], vertices[7], 12.0, graph);
  701. boost::add_edge(vertices[5], vertices[8], 12.0, graph);
  702. boost::add_edge(vertices[6], vertices[7], 11.0, graph);
  703. boost::add_edge(vertices[6], vertices[8], 10.0, graph);
  704. boost::add_edge(vertices[7], vertices[9], 0.0, graph);
  705. boost::add_edge(vertices[8], vertices[9], 0.0, graph);
  706. // boost::add_edge(vertices[0], vertices[1], 0.0, graph);
  707. // boost::add_edge(vertices[0], vertices[2], 0.0, graph);
  708. // boost::add_edge(vertices[1], vertices[3], 12.0, graph);
  709. // boost::add_edge(vertices[1], vertices[4], 15.0, graph);
  710. // boost::add_edge(vertices[2], vertices[3], 15.0, graph);
  711. // boost::add_edge(vertices[2], vertices[4], 10.0, graph);
  712. // boost::add_edge(vertices[3], vertices[5], 12.0, graph);
  713. // boost::add_edge(vertices[3], vertices[6], 12.0, graph);
  714. // boost::add_edge(vertices[4], vertices[5], 11.0, graph);
  715. // boost::add_edge(vertices[4], vertices[6], 10.0, graph);
  716. // boost::add_edge(vertices[5], vertices[7], 15.0, graph);
  717. // boost::add_edge(vertices[5], vertices[8], 12.0, graph);
  718. // boost::add_edge(vertices[6], vertices[7], 12.0, graph);
  719. // boost::add_edge(vertices[6], vertices[8], 11.0, graph);
  720. // boost::add_edge(vertices[7], vertices[9], 0.0, graph);
  721. // boost::add_edge(vertices[8], vertices[9], 0.0, graph);
  722. }
  723. void TestSuurballe()
  724. {
  725. // Create the graph
  726. Vertex source, sink;
  727. DirectedGraph graph;
  728. std::vector<Vertex> vertices;
  729. // First example graph
  730. // for (int i = 0; i < 7; ++i)
  731. // {
  732. // vertices.push_back(boost::add_vertex(graph));
  733. // }
  734. // source = vertices[0];
  735. // sink = vertices[6];
  736. // boost::add_edge(vertices[0], vertices[1], 5.0, graph);
  737. // boost::add_edge(vertices[0], vertices[4], 2.0, graph);
  738. // boost::add_edge(vertices[1], vertices[2], 1.0, graph);
  739. // boost::add_edge(vertices[1], vertices[4], 1.0, graph);
  740. // boost::add_edge(vertices[2], vertices[6], 1.0, graph);
  741. // boost::add_edge(vertices[3], vertices[2], 1.0, graph);
  742. // boost::add_edge(vertices[4], vertices[3], 2.0, graph);
  743. // boost::add_edge(vertices[4], vertices[5], 1.0, graph);
  744. // boost::add_edge(vertices[5], vertices[2], 1.0, graph);
  745. // boost::add_edge(vertices[5], vertices[6], 1.0, graph);
  746. // Second example graph
  747. for (int i = 0; i < 8; ++i)
  748. {
  749. vertices.push_back(boost::add_vertex(graph));
  750. }
  751. source = vertices[0];
  752. sink = vertices[7];
  753. boost::add_edge(vertices[0], vertices[1], 1.0, graph);
  754. boost::add_edge(vertices[0], vertices[4], 8.0, graph);
  755. boost::add_edge(vertices[0], vertices[5], 1.0, graph);
  756. boost::add_edge(vertices[1], vertices[2], 1.0, graph);
  757. boost::add_edge(vertices[1], vertices[7], 8.0, graph);
  758. boost::add_edge(vertices[2], vertices[3], 1.0, graph);
  759. boost::add_edge(vertices[3], vertices[4], 1.0, graph);
  760. boost::add_edge(vertices[3], vertices[6], 2.0, graph);
  761. boost::add_edge(vertices[4], vertices[7], 1.0, graph);
  762. boost::add_edge(vertices[5], vertices[2], 2.0, graph);
  763. boost::add_edge(vertices[5], vertices[6], 6.0, graph);
  764. boost::add_edge(vertices[6], vertices[7], 1.0, graph);
  765. algo::KShortestPaths4 suurballe(graph, source, sink, 3);
  766. suurballe.Run();
  767. size_t i = 0;
  768. for (std::vector<Vertex> path : suurballe.GetPaths())
  769. {
  770. i++;
  771. std::cout << "P" << i << "{";
  772. for (Vertex v : path)
  773. {
  774. std::cout << v;
  775. }
  776. std::cout << "}\n";
  777. }
  778. std::cout << "Total paths length: " << suurballe.GetTotalPathsLength() << std::endl;
  779. }
  780. int main(int argc, char** argv)
  781. {
  782. //TODO load with frame offset
  783. // Run(argc, argv);
  784. // TestTracklet();
  785. // DirectedGraph graph;
  786. // Vertex source, sink;
  787. // CreatePresentationGraph(graph, source, sink);
  788. //
  789. // util::FileIO::WriteCSVMatlab(graph, "/home/wrede/Dokumente/graph.csv");
  790. //
  791. // TestKBellmanFord(graph, source, sink, 2);
  792. // TestKSP(graph, source, sink, 3);
  793. // TestGrid();
  794. TestSuurballe();
  795. return 0;
  796. }