main.cpp 36 KB

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