main.cpp 36 KB

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