main.cpp 25 KB

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