main.cpp 27 KB

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