main.cpp 33 KB

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