depth-quality-model.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2019 Intel Corporation. All Rights Reserved.
3 #include <iomanip>
4 #include "depth-quality-model.h"
6 #include "model-views.h"
7 #include "viewer.h"
8 #include "os.h"
9 
10 namespace rs2
11 {
12  namespace depth_quality
13  {
15  : _ctx(ctx),
16  _pipe(ctx),
17  _viewer_model(ctx),
18  _update_readonly_options_timer(std::chrono::seconds(6)), _roi_percent(0.4f),
19  _roi_located(std::chrono::seconds(4)),
20  _too_close(std::chrono::seconds(4)),
21  _too_far(std::chrono::seconds(4)),
22  _skew_right(std::chrono::seconds(1)),
23  _skew_left(std::chrono::seconds(1)),
24  _skew_up(std::chrono::seconds(1)),
25  _skew_down(std::chrono::seconds(1)),
26  _angle_alert(std::chrono::seconds(4)),
27  _min_dist(300.f), _max_dist(2000.f), _max_angle(10.f),
28  _metrics_model(_viewer_model)
29  {
35  _viewer_model.support_non_syncronized_mode = false; //pipeline outputs only syncronized frameset
37  // Hide options from the DQT application
40  }
41 
43  {
44  bool valid_config = false;
45  std::vector<rs2::config> cfgs;
46  rs2::pipeline_profile active_profile;
47 
48  // Adjust settings according to USB type
49  bool usb3_device = true;
50  auto devices = _ctx.query_devices();
51  if (devices.size())
52  {
53  auto dev = devices[0];
54  bool usb3_device = true;
56  {
58  usb3_device = !(std::string::npos != usb_type.find("2."));
59  }
60  }
61  else
62  return valid_config;
63 
64  int requested_fps = usb3_device ? 30 : 15;
65 
66  {
67  rs2::config cfg_default;
68  // Preferred configuration Depth + Synthetic Color
69  cfg_default.enable_stream(RS2_STREAM_DEPTH, -1, 0, 0, RS2_FORMAT_Z16, requested_fps);
70  cfg_default.enable_stream(RS2_STREAM_INFRARED, -1, 0, 0, RS2_FORMAT_RGB8, requested_fps);
71  cfgs.emplace_back(cfg_default);
72  }
73  // Use Infrared luminocity as a secondary video in case synthetic chroma is not supported
74  {
75  rs2::config cfg_alt;
76  cfg_alt.enable_stream(RS2_STREAM_DEPTH, -1, 0, 0, RS2_FORMAT_Z16, requested_fps);
77  cfg_alt.enable_stream(RS2_STREAM_INFRARED, -1, 0, 0, RS2_FORMAT_Y8, requested_fps);
78  cfgs.emplace_back(cfg_alt);
79  }
80 
81  for (auto& cfg : cfgs)
82  {
83  if ((valid_config = cfg.can_resolve(_pipe)))
84  {
85  try {
86  active_profile = _pipe.start(cfg);
87  valid_config = active_profile;
88  break;
89  }
90  catch (...)
91  {
92  _pipe.stop();
93  valid_config = false;
94  if (!_device_in_use)
95  {
96  window.add_on_load_message("Device is not functional or busy!");
97  _device_in_use = true;
98  }
99  }
100  }
101  }
102 
103  if (valid_config)
104  {
105  // Toggle advanced mode
107  if (dev.is<rs400::advanced_mode>())
108  {
109  auto advanced_mode = dev.as<rs400::advanced_mode>();
110  if (!advanced_mode.is_enabled())
111  {
112  window.add_on_load_message("Toggling device into Advanced Mode...");
113  advanced_mode.toggle_advanced_mode(true);
114  valid_config = false;
115  }
116  }
117 
119  }
120 
122  {
123  auto dev = get_active_device();
124  if (dev && info.was_removed(dev))
125  {
126  std::unique_lock<std::mutex> lock(_mutex);
127  reset(window);
128  }
129  });
130 
131  return valid_config;
132  }
133 
134  void draw_notification(ux_window& win, const rect& viewer_rect, int w,
135  const std::string& msg, const std::string& second_line)
136  {
141 
147  ImGui::SetNextWindowPos({ viewer_rect.w / 2 + viewer_rect.x - w / 2, viewer_rect.h / 2 + viewer_rect.y - 38.f });
148 
149  ImGui::SetNextWindowSize({ float(w), 76.f });
150  ImGui::Begin(msg.c_str(), nullptr, flags);
151 
152  if (second_line != "")
153  {
154  auto pos = ImGui::GetCursorPos();
155  ImGui::SetCursorPosY(pos.y - 10);
156  }
158  ImGui::Text("%s", msg.c_str());
159  ImGui::PopFont();
160 
161  ImGui::PushFont(win.get_font());
162  ImGui::Text("%s", second_line.c_str());
163  ImGui::PopFont();
164 
165  ImGui::End();
168  }
169 
170  bool tool_model::draw_instructions(ux_window& win, const rect& viewer_rect, bool& distance, bool& orientation)
171  {
172  if (_viewer_model.paused)
173  return false;
174 
175  auto plane_fit_found = is_valid(_metrics_model.get_plane());
176  _metrics_model.set_plane_fit(plane_fit_found);
177  _roi_located.add_value(plane_fit_found);
178  if (!_roi_located.eval())
179  {
180  draw_notification(win, viewer_rect, 450,
181  u8"\n \uf1b2 Please point the camera to a flat Wall / Surface!",
182  "");
183  return false;
184  }
185 
187  if (_angle_alert.eval())
188  {
189  orientation = true;
190  }
191 
194 
197 
200 
203 
206 
207  constexpr const char* orientation_instruction = " Recommended angle: < 3 degrees"; // " Use the orientation gimbal to align the camera";
208  constexpr const char* distance_instruction = " Recommended distance: 0.3m-2m from the target"; // " Use the distance locator to position the camera";
209 
210  if (_skew_right.eval())
211  {
212  draw_notification(win, viewer_rect, 400,
213  u8"\n \uf061 Rotate the camera slightly Right",
214  orientation_instruction);
215  return false;
216  }
217 
218  if (_skew_left.eval())
219  {
220  draw_notification(win, viewer_rect, 400,
221  u8"\n \uf060 Rotate the camera slightly Left",
222  orientation_instruction);
223  return false;
224  }
225 
226  if (_skew_up.eval())
227  {
228  draw_notification(win, viewer_rect, 400,
229  u8"\n \uf062 Rotate the camera slightly Up",
230  orientation_instruction);
231  return false;
232  }
233 
234  if (_skew_down.eval())
235  {
236  draw_notification(win, viewer_rect, 400,
237  u8"\n \uf063 Rotate the camera slightly Down",
238  orientation_instruction);
239  return false;
240  }
241 
242  if (_too_close.eval())
243  {
244  draw_notification(win, viewer_rect, 400,
245  u8"\n \uf0b2 Move the camera further Away",
246  distance_instruction);
247  distance = true;
248  return true; // Show metrics even when too close/far
249  }
250 
251  if (_too_far.eval())
252  {
253  draw_notification(win, viewer_rect, 400,
254  u8"\n \uf066 Move the camera Closer to the wall",
255  distance_instruction);
256  distance = true;
257  return true;
258  }
259 
260  return true;
261  }
262 
263  void tool_model::draw_guides(ux_window& win, const rect& viewer_rect, bool distance_guide, bool orientation_guide)
264  {
265  static const float fade_factor = 0.6f;
266  static utilities::time::stopwatch animation_clock;
267 
273 
277  bool any_guide = distance_guide || orientation_guide;
278  if (any_guide)
279  {
281  }
282  else
283  {
285  }
286 
287  const auto window_y = viewer_rect.y + viewer_rect.h / 2;
288  const auto window_h = viewer_rect.h / 2 - 5;
289  ImGui::SetNextWindowPos({ viewer_rect.w + viewer_rect.x - 95.f, window_y });
290  ImGui::SetNextWindowSize({ 90.f, window_h });
291  ImGui::Begin("Guides", nullptr, flags);
292 
294  blend(light_grey, any_guide ? 1.f : fade_factor));
295 
296  //ImGui::PushFont(win.get_large_font());
297  //ImGui::Text(u8"\uf1e5 ");
298  //ImGui::PopFont();
299 
302  blend(light_grey, orientation_guide ? 1.f : fade_factor));
303 
304  ImGui::Text("Orientation:");
308 
309  static float prev_x = 0.f;
310  static float prev_y = 0.f;
311 
312  prev_x = (prev_x + x) / 2.f;
313  prev_y = (prev_y + y) / 2.f;
314 
315  ImGui::Text("%.1f degree", angle);
316 
317  auto pos = ImGui::GetCursorPos();
318 
319  ImGui::SetCursorPos({ pos.x, pos.y + 5 });
321  auto pos1 = ImGui::GetCursorScreenPos();
322 
324  { pos1.x + 41, pos1.y + 40 }, 41,
325  ImColor(blend(light_grey, orientation_guide ? 1.f : fade_factor)), 64);
326 
327  for (int i = 2; i < 7; i += 1)
328  {
329  auto t = (animation_clock.get_elapsed_ms() / 500) * M_PI - i * (M_PI / 5);
330  float alpha = (1.f + float(sin(t))) / 2.f;
331 
332  auto c = blend(grey, (1.f - float(i)/7.f)*fade_factor);
333  if (orientation_guide) c = blend(light_blue, alpha);
334 
336  { pos1.x + 41 - 2 * i * prev_x, pos1.y + 40 - 2 * i * prev_y }, 40.f - i*i,
337  ImColor(c), 64);
338  }
339 
340  if (angle < 50)
341  {
343  { pos1.x + 41 + 70 * prev_x, pos1.y + 40 + 70 * prev_y }, 10.f,
344  ImColor(blend(grey, orientation_guide ? 1.f : fade_factor)), 64);
345  }
346 
347  ImGui::SetCursorPos({ pos.x, pos.y + 90 });
348 
351  blend(light_grey, distance_guide ? 1.f : fade_factor));
352 
353  if (window_h > 100)
354  {
355  ImGui::Text("Distance:");
356 
357  auto wall_dist = _metrics_model.get_last_metrics().distance;
358  ImGui::Text("%.2f mm", wall_dist);
359 
360  if (window_h > 220)
361  {
362  pos = ImGui::GetCursorPos();
363  pos1 = ImGui::GetCursorScreenPos();
364  auto min_y = pos1.y + 10;
365  auto max_y = window_h + window_y;
366  int bar_spacing = 15;
367  int parts = int(max_y - min_y) / bar_spacing;
368 
370  { pos1.x + 1, pos1.y },
371  { pos1.x + 81, max_y - 5 },
372  ImColor(blend(light_grey, distance_guide ? 1.f : fade_factor * fade_factor)));
373 
374  for (int i = 0; i < parts; i++)
375  {
376  auto y = min_y + bar_spacing * i + 5;
377  auto t = 1.f - float(i) / (parts - 1);
378  auto tnext = 1.f - float(i + 1) / (parts - 1);
379  float d = t * 1.5f * _max_dist;
380  float dnext = tnext * 1.5f * _max_dist;
381 
382  auto c = light_grey;
383 
384  ImGui::GetWindowDrawList()->AddLine({ pos1.x + 45, y },
385  { pos1.x + 80, y },
386  ImColor(blend(c, distance_guide ? 1.f : fade_factor * fade_factor)));
387  if (d >= _min_dist && d <= _max_dist)
388  c = green;
389  ImGui::SetCursorPos({ pos.x + 7, pos.y + bar_spacing * i + 5 });
390  ImGui::PushStyleColor(ImGuiCol_Text, blend(c, distance_guide ? 1.f : fade_factor));
391  ImGui::Text("%.0f", d);
393 
394  _depth_scale_events[i].add_value(d > wall_dist && dnext <= wall_dist);
395  if (_depth_scale_events[i].eval())
396  {
397  for (int j = -2; j < 2; j++)
398  {
399  auto yc = yellow;
400  auto factor = (1 - abs(j) / 3.f);
401  yc = blend(yc, factor*factor);
402  if (!distance_guide) yc = blend(yc, fade_factor);
404  { pos1.x + 45, y + (bar_spacing * j) + 1 },
405  { pos1.x + 80, y + (bar_spacing * (j + 1)) }, ImColor(yc));
406  }
407 
408  if (wall_dist < _min_dist)
409  {
410  for (int j = 1; j < 5; j++)
411  {
412  auto t = (animation_clock.get_elapsed_ms() / 500) * M_PI - j * (M_PI / 5);
413  auto alpha = (1 + float(sin(t))) / 2.f;
414 
415  ImGui::SetCursorPos({ pos.x + 57, pos.y + bar_spacing * (i - j) + 14 });
417  blend(blend(light_grey, alpha), distance_guide ? 1.f : fade_factor));
418  ImGui::Text(u8"\uf106");
420  }
421  }
422 
423  if (wall_dist > _max_dist)
424  {
425  for (int j = 1; j < 5; j++)
426  {
427  auto t = (animation_clock.get_elapsed_ms() / 500) * M_PI - j * (M_PI / 5);
428  auto alpha = (1.f + float(sin(t))) / 2.f;
429 
430  ImGui::SetCursorPos({ pos.x + 57, pos.y + bar_spacing * (i + j) + 14 });
432  blend(blend(light_grey, alpha), distance_guide ? 1.f : fade_factor));
433  ImGui::Text(u8"\uf107");
435  }
436  }
437  }
438  }
439  }
440  }
441 
443 
444  ImGui::End();
447  }
448 
450  {
451  rect viewer_rect = { _viewer_model.panel_width,
452  _viewer_model.panel_y, win.width() -
454  win.height() - _viewer_model.panel_y };
455 
456  if (_first_frame)
457  {
458  _viewer_model.update_3d_camera(win, viewer_rect, true);
459  _first_frame = false;
460  }
461 
462  device_models_list list;
463  _viewer_model.show_top_bar(win, viewer_rect, list);
465 
466  bool distance_guide = false;
467  bool orientation_guide = false;
468  bool found = draw_instructions(win, viewer_rect, distance_guide, orientation_guide);
469 
471  ImGui::SetNextWindowPos({ 0, 0 });
473  ImGui::Begin("Add Device Panel", nullptr, viewer_ui_traits::imgui_flags);
474  ImGui::End();
476 
477  // Set window position and size
482 
483  // *********************
484  // Creating window menus
485  // *********************
488 
489  if (_device_model.get())
490  {
491  device_model* device_to_remove = nullptr;
492  std::vector<std::function<void()>> draw_later;
493  auto windows_width = ImGui::GetContentRegionMax().x;
494  auto json_loaded = false;
496  win,
497  _error_message, device_to_remove, _viewer_model, windows_width,
498  draw_later, true,
499  [&](std::function<void()>func)
500  {
501  auto profile =_pipe.get_active_profile();
502  _pipe.stop();
503  func();
504 
505  auto streams = profile.get_streams();
506  config cfg;
507 
508  for (auto&& s : streams)
509  {
510  cfg.enable_stream(s.stream_type(), s.stream_index(), s.format(), s.fps());
511  }
512  _pipe.start(cfg);
513 
514  json_loaded = true;
515  },
516  false);
517 
518  if (json_loaded)
519  {
521  }
522  ImGui::SetContentRegionWidth(windows_width);
524 
525  for (auto&& lambda : draw_later)
526  {
527  try
528  {
529  lambda();
530  }
531  catch (const error& e)
532  {
534  }
535  catch (const std::exception& e)
536  {
537  _error_message = e.what();
538  }
539  }
540  // Restore the cursor position after invoking lambdas
542 
543  if (_depth_sensor_model.get())
544  {
546  ImGui::PushStyleColor(ImGuiCol_Text, from_rgba(0xc3, 0xd5, 0xe5, 0xff));
547  ImGui::PushFont(win.get_font());
548 
552 
554  {
557 
558  if (_depth_sensor_model->draw_stream_selection(_error_message))
559  {
560  if (_depth_sensor_model->is_selected_combination_supported())
561  {
562  // Preserve streams and ui selections
563  auto primary = _depth_sensor_model->get_selected_profiles().front().as<video_stream_profile>();
564  auto secondary = _pipe.get_active_profile().get_streams().back().as<video_stream_profile>();
565  _depth_sensor_model->store_ui_selection();
566 
567  _pipe.stop();
568 
570  // We have a single resolution control that obides both streams
571  cfg.enable_stream(primary.stream_type(), primary.stream_index(),
572  primary.width(), primary.height(), primary.format(), primary.fps());
573  cfg.enable_stream(secondary.stream_type(), secondary.stream_index(),
574  primary.width(), primary.height(), secondary.format(), primary.fps());
575 
576  // The secondary stream may use its previous resolution when appropriate
577  if (!cfg.can_resolve(_pipe))
578  {
579  cfg.disable_stream(secondary.stream_type());
580  cfg.enable_stream(secondary.stream_type(), secondary.stream_index(),
581  secondary.width(), secondary.height(), secondary.format(), primary.fps());
582  }
583 
584  // Wait till a valid device is registered and responsive
585  bool success = false;
586  do
587  {
588  try // Retries are needed to cope with HW stability issues
589  {
590 
591  auto dev = cfg.resolve(_pipe);
592  auto depth_sensor = dev.get_device().first< rs2::depth_sensor >();
594  {
595  auto depth_profile = dev.get_stream(RS2_STREAM_DEPTH);
596  auto w = depth_profile.as<video_stream_profile>().width();
599  }
600 
601  auto profile = _pipe.start(cfg);
602  success = profile;
603  }
604  catch (...)
605  {
606  std::this_thread::sleep_for(std::chrono::milliseconds(100));
607  }
608  } while (!success);
609 
611  }
612  else
613  {
614  _error_message = "Selected configuration is not supported!";
615  _depth_sensor_model->restore_ui_selection();
616  }
617  }
618 
619  auto col0 = ImGui::GetCursorPosX();
620  auto col1 = 145.f;
621 
622  ImGui::Text("Region of Interest:");
624 
627 
628  static std::vector<std::string> items{ "80%", "60%", "40%", "20%" };
629  int tmp_roi_combo_box = _roi_combo_index;
630  if (draw_combo_box("##ROI Percent", items, tmp_roi_combo_box))
631  {
632  bool allow_changing_roi = true;
633  try
634  {
636  {
637  auto && ds = _depth_sensor_model->dev.first<depth_sensor>();
638  if( ds.supports( RS2_OPTION_ENABLE_IR_REFLECTIVITY )
639  && ( ds.get_option( RS2_OPTION_ENABLE_IR_REFLECTIVITY ) == 1.0f ) )
640  {
641  allow_changing_roi = false;
642  _error_message = "ROI cannot be changed while IR Reflectivity is enabled";
643  }
644  }
645  }
646  catch (...) {}
647 
648  if (allow_changing_roi)
649  {
650  _roi_combo_index = tmp_roi_combo_box;
651  if (_roi_combo_index == 0) _roi_percent = 0.8f;
652  else if (_roi_combo_index == 1) _roi_percent = 0.6f;
653  else if (_roi_combo_index == 2) _roi_percent = 0.4f;
654  else if (_roi_combo_index == 3) _roi_percent = 0.2f;
656  }
657  }
658 
661 
662  try
663  {
665  {
666  auto && ds = _depth_sensor_model->dev.first< depth_sensor >();
668  {
669  ImGui::SetCursorPosX(col0);
671 
672  bool current_ir_reflectivity_opt
674 
675  if (ImGui::Checkbox("IR Reflectivity",
676  &current_ir_reflectivity_opt))
677  {
678  // Deny enabling IR Reflectivity on ROI != 20% [RS5-8358]
679  if (0.2f == _roi_percent)
681  current_ir_reflectivity_opt);
682  else
684  = "Please set 'VGA' resolution, 'Max Range' preset and "
685  "20% ROI before enabling IR Reflectivity";
686  }
687 
688  if (ImGui::IsItemHovered())
689  {
691  "%s",
692  ds.get_option_description(
694  }
695  }
696  }
697  }
698  catch (const std::exception& e)
699  {
700  _error_message = e.what();
701  }
702 
703  ImGui::SetCursorPosX(col0);
705 
706  ImGui::Text("Distance:");
707  if (ImGui::IsItemHovered())
708  {
709  ImGui::SetTooltip("Estimated distance to an average within the ROI of the target (wall) in mm");
710  }
712 
713  static float prev_metric_distance = 0;
714  if (_viewer_model.paused)
715  {
716  ImGui::Text("%.2f mm", prev_metric_distance);
717  }
718  else
719  {
720  auto curr_metric_distance = _metrics_model.get_last_metrics().distance;
721  ImGui::Text("%.2f mm", curr_metric_distance);
722  prev_metric_distance = curr_metric_distance;
723  }
724 
726 
728  std::string gt_str("Ground Truth");
729  if (_use_ground_truth) gt_str += ":";
730  if (ImGui::Checkbox(gt_str.c_str(), &_use_ground_truth))
731  {
734  }
735  if (ImGui::IsItemHovered())
736  {
737  ImGui::SetTooltip("True measured distance to the wall in mm");
738  }
740  if (_use_ground_truth)
741  {
743  if (ImGui::InputInt("##GT", &_ground_truth, 1))
744  {
746  }
748  ImGui::SetCursorPosX(col1 + 120); ImGui::SameLine();
749  ImGui::Text("(mm)");
750  }
751  else
752  {
754  ImGui::Dummy({ 1,1 });
755  }
757 
759 
760  ImGui::Text("Angle:");
761  if (ImGui::IsItemHovered())
762  {
763  ImGui::SetTooltip("Estimated angle to the wall in degrees");
764  }
766  static float prev_metric_angle = 0;
767  if (_viewer_model.paused)
768  {
769  ImGui::Text("%.2f deg", prev_metric_angle);
770  }
771  else
772  {
773  auto curr_metric_angle = _metrics_model.get_last_metrics().angle;
774  ImGui::Text("%.2f deg", curr_metric_angle);
775  prev_metric_angle = curr_metric_angle;
776  }
777 
779  ImGui::TreePop();
780  }
781 
784 
787 
789  {
792 
793  _metrics_model.render(win);
794 
798  {
799  if (ImGui::Button(u8"\uf0c7 Stop_record", { 140, 25 }))
800  {
802  }
803  }
804  else
805  {
806  if (ImGui::Button(u8"\uf0c7 Start_record", { 140, 25 }))
807  {
809  }
810 
811  if (ImGui::IsItemHovered())
812  {
813  ImGui::SetTooltip("Save Metrics snapshot. This will create:\nPNG image with the depth frame\nPLY 3D model with the point cloud\nJSON file with camera settings you can load later\nand a CSV with metrics recent values");
814  }
815  }
816 
818 
820  ImGui::TreePop();
821  }
822 
825  ImGui::PopFont();
827  }
828  }
829 
830  ImGui::End();
833 
834  try
835  {
836  frameset f;
837  if (_pipe.poll_for_frames(&f))
838  {
840  }
841  frame dpt = _viewer_model.handle_ready_frames(viewer_rect, win, 1, _error_message);
842  if (dpt)
844  }
845  catch( const error & e )
846  {
847  // Can occur on device disconnect
849  __FILE__,
850  __LINE__,
851  error_to_string( e ) );
852  }
853  catch( const std::exception & e )
854  {
856  __FILE__,
857  __LINE__,
858  e.what() );
859  }
860  catch( ... )
861  {
863  __FILE__,
864  __LINE__,
865  "Unknown error occurred" );
866  }
867 
868  }
869 
871  {
872  // Capture the old configuration before reconfiguring the stream
873  bool save = false;
874  subdevice_ui_selection prev_ui;
875 
877 
879  {
880  if( ! _first_frame )
881  {
882  prev_ui = _depth_sensor_model->last_valid_ui;
883  save = true;
884  }
885 
886  // Clean-up the models for new configuration
887  for (auto&& s : _device_model->subdevices)
888  s->streaming = false;
893  }
894  // Create a new device model - reset all UI the new device
895  _device_model = std::shared_ptr<rs2::device_model>(new device_model(dev, _error_message, _viewer_model, _first_frame, false));
896 
897  // Get device depth sensor model
898  for (auto&& sub : _device_model->subdevices)
899  {
900  if (sub->s->is<depth_sensor>())
901  {
902  _depth_sensor_model = sub;
903  break;
904  }
905  }
906 
907  _device_model->show_depth_only = true;
908  _device_model->show_stream_selection = false;
909 
910  _depth_sensor_model->draw_streams_selector = false;
911  _depth_sensor_model->draw_fps_selector = true;
912  _depth_sensor_model->allow_change_resolution_while_streaming = true;
913  _depth_sensor_model->allow_change_fps_while_streaming = true;
914 
915  // Retrieve stereo baseline for supported devices
916  auto baseline_mm = -1.f;
917  auto profiles = _depth_sensor_model->s->get_stream_profiles();
918  auto right_sensor = std::find_if(profiles.begin(), profiles.end(), [](rs2::stream_profile& p)
919  { return (p.stream_index() == 2) && (p.stream_type() == RS2_STREAM_INFRARED); });
920 
921  if (right_sensor != profiles.end())
922  {
923  auto left_sensor = std::find_if(profiles.begin(), profiles.end(), [](rs2::stream_profile& p)
924  { return (p.stream_index() == 1) && (p.stream_type() == RS2_STREAM_INFRARED); });
925  try
926  {
927  auto extrin = (*left_sensor).get_extrinsics_to(*right_sensor);
928  baseline_mm = fabs(extrin.translation[0]) * 1000; // baseline in mm
929  }
930  catch (...) {
931  _error_message = "Extrinsic parameters are not available";
932  }
933  }
934 
937 
938  // Restore GUI controls to the selected configuration
939  if (save)
940  {
941  _depth_sensor_model->ui = _depth_sensor_model->last_valid_ui = prev_ui;
942  }
943 
944  // Connect the device_model to the viewer_model
945  for (auto&& sub : _device_model.get()->subdevices)
946  {
947  if (!sub->s->is<depth_sensor>()) continue;
948 
949  sub->show_algo_roi = true;
950  sub->roi_percentage = _roi_percent;
952  sub->streaming = true; // The streaming activated externally to the device_model
953  sub->depth_colorizer->set_option(RS2_OPTION_HISTOGRAM_EQUALIZATION_ENABLED, 0.f);
954  sub->depth_colorizer->set_option(RS2_OPTION_MIN_DISTANCE, 0.3f);
955  sub->depth_colorizer->set_option(RS2_OPTION_MAX_DISTANCE, 2.7f);
956  sub->_options_invalidated = true;
957 
958  for (auto&& profile : profiles)
959  {
961  _viewer_model.streams[profile.unique_id()].texture->colorize = sub->depth_colorizer;
962  _viewer_model.streams[profile.unique_id()].texture->yuy2rgb = sub->yuy2rgb;
963 
964  if (profile.stream_type() == RS2_STREAM_DEPTH)
965  {
968  sub->s->as<depth_sensor>().get_depth_scale(), baseline_mm);
969 
970  _metrics_model.update_roi_attributes({ int(depth_profile.width() * (0.5f - 0.5f*_roi_percent)),
971  int(depth_profile.height() * (0.5f - 0.5f*_roi_percent)),
972  int(depth_profile.width() * (0.5f + 0.5f*_roi_percent)),
973  int(depth_profile.height() * (0.5f + 0.5f*_roi_percent)) },
974  _roi_percent);
975  }
976  }
977 
978  sub->algo_roi = _metrics_model.get_roi();
979  }
980  }
981 
982  // Reset tool state when the active camera is disconnected
984  {
985  try
986  {
987  _pipe.stop();
988  }
989  catch(...){}
990 
991  _device_in_use = false;
992  _first_frame = true;
993  win.reset();
994  }
995 
996  bool metric_plot::has_trend(bool positive)
997  {
998  const auto window_size = 110;
999  const auto curr_window = 10;
1000  auto best = ranges[GREEN_RANGE].x;
1001  if (ranges[RED_RANGE].x < ranges[GREEN_RANGE].x)
1002  best = ranges[GREEN_RANGE].y;
1003 
1004  auto min_val = 0.f;
1005  for (int i = 0; i < curr_window; i++)
1006  {
1007  auto val = fabs(best - _vals[(SIZE + _idx - i) % SIZE]);
1008  min_val += val / curr_window;
1009  }
1010 
1011  auto improved = 0;
1012  for (int i = curr_window; i <= window_size; i++)
1013  {
1014  auto val = fabs(best - _vals[(SIZE + _idx - i) % SIZE]);
1015  if (positive && min_val < val * 0.8) improved++;
1016  if (!positive && min_val * 0.8 > val) improved++;
1017  }
1018  return improved > window_size * 0.4;
1019  }
1020 
1022  _frame_queue(1),
1023  _depth_scale_units(0.f),
1024  _stereo_baseline_mm(0.f),
1025  _ground_truth_mm(0),
1026  _use_gt(false),
1027  _plane_fit(false),
1028  _roi_percentage(0.4f),
1029  _active(true),
1030  _recorder(viewer_model)
1031  {
1032  _worker_thread = std::thread([this]() {
1033  while (_active)
1034  {
1036  if (!_frame_queue.poll_for_frame(&frames))
1037  {
1038  std::this_thread::sleep_for(std::chrono::milliseconds(10));
1039  continue;
1040  }
1041 
1042  std::vector<single_metric_data> sample;
1043  for (auto&& f : frames)
1044  {
1045  auto profile = f.get_profile();
1046  auto stream_type = profile.stream_type();
1047  auto stream_format = profile.format();
1048 
1049  if ((RS2_STREAM_DEPTH == stream_type) && (RS2_FORMAT_Z16 == stream_format))
1050  {
1051  float su = 0, baseline = -1.f;
1053  int gt_mm{};
1054  bool plane_fit_set{};
1055  region_of_interest roi{};
1056  {
1057  std::lock_guard<std::mutex> lock(_m);
1058  su = _depth_scale_units;
1061  intrin = depth_profile.get_intrinsics();
1063  _roi = { int(intrin.width * (0.5f - 0.5f*this->_roi_percentage)),
1064  int(intrin.height * (0.5f - 0.5f*this->_roi_percentage)),
1065  int(intrin.width * (0.5f + 0.5f*this->_roi_percentage)),
1066  int(intrin.height * (0.5f + 0.5f*this->_roi_percentage)) };
1067 
1068  roi = _roi;
1069  }
1070 
1071  std::tie(gt_mm, plane_fit_set) = get_inputs();
1072 
1073  auto metrics = analyze_depth_image(f, su, baseline, &intrin, roi, gt_mm, plane_fit_set, sample, _recorder.is_recording(), callback);
1074 
1075  {
1076  std::lock_guard<std::mutex> lock(_m);
1078  }
1079  }
1080  }
1081  if (_recorder.is_recording())
1082  _recorder.add_sample(frames, std::move(sample));
1083 
1084  // Artificially slow down the calculation, so even on small ROIs / resolutions
1085  // the output is updated within reasonable interval (keeping it human readable)
1086  std::this_thread::sleep_for(std::chrono::milliseconds(80));
1087  }
1088  });
1089  }
1090 
1092  {
1093  _active = false;
1094  _worker_thread.join();
1095  reset();
1096  }
1097 
1098  std::shared_ptr<metric_plot> tool_model::make_metric(
1099  const std::string& name, float min, float max, const bool requires_plane_fit,
1100  const std::string& units,
1101  const std::string& description)
1102  {
1103  auto res = std::make_shared<metric_plot>(name, min, max, units, description, requires_plane_fit);
1104  _metrics_model.add_metric(res);
1105  _metrics_model._recorder.add_metric({ name,units });
1106  return res;
1107  }
1108 
1110  {
1111  rs2::device dev{};
1112  try
1113  {
1114  if (_pipe.get_active_profile())
1115  dev = _pipe.get_active_profile().get_device();
1116  }
1117  catch(...){}
1118 
1119  return dev;
1120  }
1121 
1123  {
1124  std::stringstream ss;
1125  ss << "Device Info:"
1126  << "\nType:," << _device_model->dev.get_info(RS2_CAMERA_INFO_NAME)
1127  << "\nHW Id:," << _device_model->dev.get_info(RS2_CAMERA_INFO_PRODUCT_ID)
1128  << "\nSerial Num:," << _device_model->dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER)
1129  << "\nFirmware Ver:," << _device_model->dev.get_info(RS2_CAMERA_INFO_FIRMWARE_VERSION)
1130  << "\n\nStreaming profile:\nStream,Format,Resolution,FPS\n";
1131 
1132  for (auto& stream : _pipe.get_active_profile().get_streams())
1133  {
1134  auto vs = stream.as<video_stream_profile>();
1135  ss << vs.stream_name() << ","
1136  << rs2_format_to_string(vs.format()) << ","
1137  << vs.width() << "x" << vs.height() << "," << vs.fps() << "\n";
1138  }
1139 
1140  return ss.str();
1141  }
1142 
1144  {
1145  std::lock_guard<std::mutex> lock(_m);
1146 
1147  if (!_persistent_visibility.eval()) return;
1148 
1149  std::stringstream ss;
1150  auto val = _vals[(SIZE + _idx - 1) % SIZE];
1151 
1152  ss << _label << std::setprecision(2) << std::fixed << std::setw(3) << val << " " << _units;
1153 
1155 
1156  auto range = get_range(val);
1157  if (range == GREEN_RANGE)
1159  else if (range == YELLOW_RANGE)
1161  else if (range == RED_RANGE)
1163  else
1164  ImGui::PushStyleColor(ImGuiCol_Text, from_rgba(0xc3, 0xd5, 0xe5, 0xff));
1165 
1166  ImGui::PushFont(win.get_font());
1167 
1169 
1170  const auto left_x = 295.f;
1171  const auto indicator_flicker_rate = 200;
1172  auto alpha_value = static_cast<float>(fabs(sin(_model_timer.get_elapsed_ms() / indicator_flicker_rate)));
1173 
1174  _trending_up.add_value(has_trend(true));
1175  _trending_down.add_value(has_trend(false));
1176 
1177  if (_trending_up.eval())
1178  {
1179  auto color = blend(green, alpha_value);
1181  auto col0 = ImGui::GetCursorPos();
1182  ImGui::SetCursorPosX(left_x);
1184  ImGui::Text(u8"\uf102");
1185  if (ImGui::IsItemHovered())
1186  {
1187  ImGui::SetTooltip("This metric shows positive trend");
1188  }
1189  ImGui::PopFont();
1192  }
1193  else if (_trending_down.eval())
1194  {
1195  auto color = blend(redish, alpha_value);
1197  auto col0 = ImGui::GetCursorPos();
1198  ImGui::SetCursorPosX(left_x);
1200  ImGui::Text(u8"\uf103");
1201  if (ImGui::IsItemHovered())
1202  {
1203  ImGui::SetTooltip("This metric shows negative trend");
1204  }
1205  ImGui::PopFont();
1208  }
1209  else
1210  {
1211  auto col0 = ImGui::GetCursorPos();
1212  ImGui::SetCursorPosX(left_x);
1214  ImGui::Text(" ");
1215  ImGui::PopFont();
1217  }
1218 
1219  if (ImGui::TreeNode(_label.c_str(), "%s", ss.str().c_str()))
1220  {
1224  std::string did = to_string() << _id << "-desc";
1225  ImVec2 desc_size = { 270, 50 };
1226  auto lines = std::count(_description.begin(), _description.end(), '\n') + 1;
1227  desc_size.y = lines * 20.f;
1228  ImGui::InputTextMultiline(did.c_str(), const_cast<char*>(_description.c_str()),
1229  _description.size() + 1, desc_size, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_ReadOnly);
1231 
1232  ImGui::PlotLines(_id.c_str(), (float*)&_vals, int(SIZE), int(_idx), ss.str().c_str(), _min, _max, { 270, 50 });
1233 
1234  ImGui::TreePop();
1235  }
1236 
1237  ImGui::PopFont();
1239  }
1240 
1241  // Display the latest metrics in the panel view
1243  {
1244  for (auto&& plot : _plots)
1245  {
1246  plot->render(win);
1247  }
1248  }
1249 
1251  {
1252  std::ofstream csv;
1253 
1254  csv.open(_filename_base + "_depth_metrics.csv");
1255 
1256  // Store the device info and the streaming profile details
1257  csv << _metrics->_camera_info;
1258 
1259  //Store metric environment
1260  csv << "\nEnvironment:\nPlane-Fit_distance_mm," << (_metrics->_plane_fit ? std::to_string(_metrics->_latest_metrics.distance) : "N/A") << std::endl;
1261  csv << "Ground-Truth_Distance_mm," << (_metrics->_use_gt ? std::to_string(_metrics->_ground_truth_mm ) : "N/A") << std::endl;
1262 
1263  // Generate columns header
1264  csv << "\nSample Id,Frame #,Timestamp (ms),";
1265  auto records_data = _metric_data;
1266  // Plane Fit RMS error will have dual representation both as mm and % of the range
1267  records_data.push_back({ "Plane Fit RMS Error mm" , "" });
1268  for (auto&& metric : records_data)
1269  {
1270  csv << metric.name << " " << metric.units << ",";
1271  }
1272  csv << std::endl;
1273 
1275  auto i = 0;
1276  for (auto&& it: _samples)
1277  {
1278  csv << i++ << ","<< it.frame_number << "," << std::fixed << std::setprecision(4) << it.timestamp << ",";
1279  for (auto&& metric : records_data)
1280  {
1281  auto samp = std::find_if(it.samples.begin(), it.samples.end(), [&](single_metric_data s) {return s.name == metric.name; });
1282  if (samp != it.samples.end()) csv << samp->val;
1283  csv << ",";
1284  }
1285  csv << std::endl;
1286  }
1287 
1288  csv.close();
1289  }
1290 
1292  {
1293  // Trim the file extension when provided. Note that this may amend user-provided file name in case it uses the "." character, e.g. "my.file.name"
1294  auto filename_base = _filename_base;
1295 
1296  auto loc = filename_base.find_last_of(".");
1297  if (loc != std::string::npos)
1298  filename_base.erase(loc, std::string::npos);
1299 
1300  std::stringstream fn;
1301  fn << frames.get_frame_number();
1302 
1303  for (auto&& frame : frames)
1304  {
1305 
1306  // Snapshot the color-augmented version of the frame
1307  if (auto df = frame.as<depth_frame>())
1308  {
1309  if (auto colorized_frame = _colorize.colorize(frame).as<video_frame>())
1310  {
1311 
1312  auto stream_desc = rs2_stream_to_string(colorized_frame.get_profile().stream_type());
1313  auto filename_png = filename_base + "_" + stream_desc + "_" + fn.str() + ".png";
1314  save_to_png(filename_png.data(), colorized_frame.get_width(), colorized_frame.get_height(), colorized_frame.get_bytes_per_pixel(),
1315  colorized_frame.get_data(), colorized_frame.get_width() * colorized_frame.get_bytes_per_pixel());
1316 
1317  }
1318  }
1319  auto original_frame = frame.as<video_frame>();
1320 
1321  // For Depth-originated streams also provide a copy of the raw data accompanied by sensor-specific metadata
1322  if (original_frame && val_in_range(original_frame.get_profile().stream_type(), { RS2_STREAM_DEPTH , RS2_STREAM_INFRARED }))
1323  {
1324  auto stream_desc = rs2_stream_to_string(original_frame.get_profile().stream_type());
1325 
1326  //Capture raw frame
1327  auto filename = filename_base + "_" + stream_desc + "_" + fn.str() + ".raw";
1328  if (!save_frame_raw_data(filename, original_frame))
1329  _viewer_model.not_model->add_notification(notification_data{ to_string() << "Failed to save frame raw data " << filename,
1331 
1332 
1333  // And the frame's attributes
1334  filename = filename_base + "_" + stream_desc + "_" + fn.str() + "_metadata.csv";
1335  if (!frame_metadata_to_csv(filename, original_frame))
1336  _viewer_model.not_model->add_notification(notification_data{ to_string() << "Failed to save frame metadata file " << filename,
1338 
1339  }
1340  }
1341  // Export 3d view in PLY format
1342  rs2::frame ply_texture;
1343 
1344  if (_viewer_model.selected_tex_source_uid >= 0)
1345  {
1346  for (auto&& frame : frames)
1347  {
1348  if (frame.get_profile().unique_id() == _viewer_model.selected_tex_source_uid)
1349  {
1350  ply_texture = frame;
1351  _pc.map_to(ply_texture);
1352  break;
1353  }
1354  }
1355 
1356  if (ply_texture)
1357  {
1358  auto fname = filename_base + "_" + fn.str() + "_3d_mesh.ply";
1359  std::unique_ptr<rs2::filter> exporter;
1360  exporter = std::unique_ptr<rs2::filter>(new rs2::save_to_ply(fname));
1361  export_frame(fname, std::move(exporter), *_viewer_model.not_model, frames, false);
1362  }
1363  }
1364  }
1365 
1366  }
1367  }
float y
Definition: rendering.h:499
static const textual_icon lock
Definition: model-views.h:218
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val)
Definition: imgui.cpp:4650
int selected_tex_source_uid
Definition: viewer.h:163
rs2::device get_active_device(void) const
static const ImVec4 white
Definition: model-views.h:45
const char * rs2_format_to_string(rs2_format format)
Definition: rs.cpp:1263
IMGUI_API float GetCursorPosX()
Definition: imgui.cpp:5082
IMGUI_API void AddRectFilled(const ImVec2 &a, const ImVec2 &b, ImU32 col, float rounding=0.0f, int rounding_corners=0x0F)
Definition: imgui_draw.cpp:814
static const auto imgui_flags
Definition: ux-window.h:27
rs2_sensor_mode resolution_from_width_height(int width, int height)
Definition: model-views.cpp:46
GLint y
IMGUI_API ImVec2 GetCursorPos()
Definition: imgui.cpp:5076
rs2::frame handle_ready_frames(const rect &viewer_rect, ux_window &window, int devices, std::string &error_message)
Definition: viewer.cpp:1335
snapshot_metrics analyze_depth_image(const rs2::video_frame &frame, float units, float baseline_mm, const rs2_intrinsics *intrin, rs2::region_of_interest roi, const int ground_truth_mm, bool plane_fit_present, std::vector< single_metric_data > &samples, bool record, callback_type callback)
IMGUI_API void SetTooltip(const char *fmt,...) IM_PRINTFARGS(1)
Definition: imgui.cpp:3288
GLuint const GLchar * name
IMGUI_API void AddCircle(const ImVec2 &centre, float radius, ImU32 col, int num_segments=12, float thickness=1.0f)
Definition: imgui_draw.cpp:891
ImVec4 from_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a, bool consistent_color)
GLfloat green
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
Definition: glext.h:10557
GLdouble s
bool frame_metadata_to_csv(const std::string &filename, rs2::frame frame)
IMGUI_API bool InputTextMultiline(const char *label, char *buf, size_t buf_size, const ImVec2 &size=ImVec2(0, 0), ImGuiInputTextFlags flags=0, ImGuiTextEditCallback callback=NULL, void *user_data=NULL)
Definition: imgui.cpp:8223
IMGUI_API void SetCursorPos(const ImVec2 &local_pos)
Definition: imgui.cpp:5094
GLfloat GLfloat p
Definition: glext.h:12687
static const ImVec4 light_grey
Definition: model-views.h:40
void update_roi_attributes(const region_of_interest &roi, float roi_percent)
Definition: imgui.h:88
std::array< float3, 4 > get_plane()
bool was_removed(const rs2::device &dev) const
Definition: rs_context.hpp:23
static const ImVec4 light_blue
Definition: model-views.h:38
std::enable_if< std::is_base_of< rs2::frame, T >::value, bool >::type poll_for_frame(T *output) const
stream_profile get_profile() const
Definition: rs_frame.hpp:557
device_list query_devices() const
Definition: rs_context.hpp:112
std::map< int, stream_model > streams
Definition: viewer.h:125
std::unordered_set< int > _hidden_options
Definition: viewer.h:195
IMGUI_API void SetNextWindowPos(const ImVec2 &pos, ImGuiSetCond cond=0)
Definition: imgui.cpp:4923
UINT8_TYPE u8
Definition: sqlite3.c:11450
void draw_notification(ux_window &win, const rect &viewer_rect, int w, const std::string &msg, const std::string &second_line)
rs2_intrinsics intrin
GLfloat angle
Definition: glext.h:6819
void add_on_load_message(const std::string &msg)
Definition: ux-window.cpp:433
IMGUI_API bool TreeNodeEx(const char *label, ImGuiTreeNodeFlags flags=0)
Definition: imgui.cpp:5993
Definition: cah-model.h:10
GLdouble GLdouble GLdouble w
GLsizei const GLchar *const * string
d
Definition: rmse.py:171
std::atomic< bool > synchronization_enable
Definition: viewer.h:158
GLuint GLuint stream
Definition: glext.h:1790
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1960
e
Definition: rmse.py:177
GLsizei GLsizei GLfloat distance
Definition: glext.h:10563
static const ImVec4 grey
Definition: model-views.h:48
IMGUI_API void AddLine(const ImVec2 &a, const ImVec2 &b, ImU32 col, float thickness=1.0f)
Definition: imgui_draw.cpp:796
void record_frames(const frameset &frame)
void update_3d_camera(ux_window &win, const rect &viewer_rect, bool force=false)
Definition: viewer.cpp:3066
IMGUI_API bool TreeNode(const char *label)
Definition: imgui.cpp:6070
IMGUI_API ImVec2 GetContentRegionMax()
Definition: imgui.cpp:4981
bool is_valid(const plane_3d &p)
Definition: rendering.h:243
void gc_streams()
Definition: viewer.cpp:977
std::shared_ptr< notifications_model > not_model
Definition: viewer.h:133
const float panel_y
Definition: viewer.h:64
GLdouble t
bool _support_ir_reflectivity
Definition: viewer.h:196
ImFont * get_font() const
Definition: ux-window.h:64
GLuint GLfloat * val
static const textual_icon usb_type
Definition: model-views.h:249
std::shared_ptr< subdevice_model > _depth_sensor_model
def info(name, value, persistent=False)
Definition: test.py:301
float x
Definition: rendering.h:499
IMGUI_API void SameLine(float pos_x=0.0f, float spacing_w=-1.0f)
Definition: imgui.cpp:9246
std::string error_to_string(const error &e)
Definition: rendering.h:1583
GLdouble f
bool draw_combo_box(const std::string &id, const std::vector< std::string > &device_names, int &new_index)
bool poll_for_frames(frameset *f) const
GLfloat GLfloat GLfloat alpha
IMGUI_API ImDrawList * GetWindowDrawList()
Definition: imgui.cpp:5045
IMGUI_API bool Begin(const char *name, bool *p_open=NULL, ImGuiWindowFlags flags=0)
Definition: imgui.cpp:3772
IMGUI_API void PopStyleVar(int count=1)
Definition: imgui.cpp:4675
float h
Definition: rendering.h:500
IMGUI_API void Dummy(const ImVec2 &size)
Definition: imgui.cpp:9171
const float panel_width
Definition: viewer.h:63
static const ImVec4 regular_blue
Definition: model-views.h:39
const GLubyte * c
Definition: glext.h:12690
GLdouble x
devices
Definition: test-fg.py:9
double get_elapsed_ms() const
Definition: stopwatch.h:30
GLint GLsizei GLsizei height
IMGUI_API void SetNextWindowSize(const ImVec2 &size, ImGuiSetCond cond=0)
Definition: imgui.cpp:4937
static const ImVec4 sensor_bg
Definition: model-views.h:51
GLbitfield flags
void export_frame(const std::string &fname, std::unique_ptr< rs2::filter > exporter, notifications_model &ns, frame data, bool notify)
IMGUI_API void SetCursorPosX(float x)
Definition: imgui.cpp:5101
bool allow_stream_close
Definition: viewer.h:151
void disable_stream(rs2_stream stream, int index=-1)
GLint j
static const ImVec4 sensor_header_light_blue
Definition: model-views.h:50
IMGUI_API void PushItemWidth(float item_width)
Definition: imgui.cpp:4486
IMGUI_API void Text(const char *fmt,...) IM_PRINTFARGS(1)
Definition: imgui.cpp:5223
static const ImVec4 device_info_color
Definition: model-views.h:59
IMGUI_API bool Button(const char *label, const ImVec2 &size=ImVec2(0, 0))
Definition: imgui.cpp:5573
void update_stream_attributes(const rs2_intrinsics &intrinsic, float scale_units, float baseline)
IMGUI_API void End()
Definition: imgui.cpp:4330
static const ImVec4 button_color
Definition: model-views.h:55
void begin_stream(std::shared_ptr< subdevice_model > d, rs2::stream_profile p)
Definition: viewer.cpp:3228
std::array< float3, 4 > roi_rect
Definition: viewer.h:153
IMGUI_API void AddCircleFilled(const ImVec2 &centre, float radius, ImU32 col, int num_segments=12)
Definition: imgui_draw.cpp:901
int stream_index() const
Definition: rs_frame.hpp:34
bool supports(rs2_camera_info info) const
Definition: rs_sensor.hpp:125
void enable_stream(rs2_stream stream_type, int stream_index, int width, int height, rs2_format format=RS2_FORMAT_ANY, int framerate=0)
std::shared_ptr< metric_plot > metric
int save_to_png(const char *filename, size_t pixel_width, size_t pixels_height, size_t bytes_per_pixel, const void *raster_data, size_t stride_bytes)
Definition: os.cpp:217
bool can_resolve(std::shared_ptr< rs2_pipeline > p) const
float w
Definition: rendering.h:500
GLenum func
device get_device() const
Definition: rs_pipeline.hpp:83
void add_value(bool val)
Definition: rendering.h:818
void draw_guides(ux_window &win, const rect &viewer_rect, bool distance_guide, bool orientation_guide)
IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4 &col)
Definition: imgui.cpp:4599
IMGUI_API void PushFont(ImFont *font)
Definition: imgui.cpp:4539
post_processing_filters ppf
Definition: viewer.h:130
float y
Definition: imgui.h:90
std::shared_ptr< metric_plot > make_metric(const std::string &name, float min, float max, bool plane_fit, const std::string &units, const std::string &description)
GLfloat units
std::map< int, temporal_event > _depth_scale_events
rs2_format format() const
Definition: rs_frame.hpp:44
IMGUI_API ImVec2 GetCursorScreenPos()
Definition: imgui.cpp:5121
ImVec4 blend(const ImVec4 &c, float a)
Definition: model-views.h:77
fname
Definition: rmse.py:13
bool val_in_range(const T &val, const std::initializer_list< T > &list)
Definition: rendering.h:1599
pipeline_profile resolve(std::shared_ptr< rs2_pipeline > p) const
std::shared_ptr< device_model > _device_model
std::vector< stream_profile > get_streams() const
Definition: rs_pipeline.hpp:29
IMGUI_API void PopItemWidth()
Definition: imgui.cpp:4507
IMGUI_API void TreePop()
Definition: imgui.cpp:9530
const char * rs2_stream_to_string(rs2_stream stream)
Definition: rs.cpp:1262
bool support_non_syncronized_mode
Definition: viewer.h:157
static auto it
int min(int a, int b)
Definition: lz4s.c:73
GLint GLsizei count
bool allow_3d_source_change
Definition: viewer.h:150
IMGUI_API bool Checkbox(const char *label, bool *v)
Definition: imgui.cpp:7269
float width() const
Definition: ux-window.h:41
bool save_frame_raw_data(const std::string &filename, rs2::frame frame)
typename::boost::move_detail::remove_reference< T >::type && move(T &&t) BOOST_NOEXCEPT
Video stream intrinsics.
Definition: rs_types.h:58
std::vector< std::unique_ptr< device_model > > device_models_list
Definition: model-views.h:96
void set_devices_changed_callback(T callback)
Definition: rs_context.hpp:169
float rs2_vector::* pos
IMGUI_API void SetCursorScreenPos(const ImVec2 &pos)
Definition: imgui.cpp:5127
void add_sample(rs2::frameset &frames, std::vector< single_metric_data > sample)
static const ImVec4 redish
Definition: model-views.h:52
IMGUI_API void SetContentRegionWidth(float y)
Definition: imgui.cpp:4990
std::map< int, rs2::frame_queue > frames_queue
Definition: model-views.h:933
int i
GLuint res
Definition: glext.h:8856
int selected_depth_source_uid
Definition: viewer.h:162
std::array< float, 3 > color
Definition: model-views.h:449
int unique_id() const
Definition: rs_frame.hpp:54
static const ImVec4 yellow
Definition: model-views.h:60
rs2_format format
ImFont * get_large_font() const
Definition: ux-window.h:62
pipeline_profile get_active_profile() const
void show_top_bar(ux_window &window, const rect &viewer_rect, const device_models_list &devices)
Definition: viewer.cpp:2314
pipeline_profile start()
std::tuple< int, bool > get_inputs() const
IMGUI_API void AddRect(const ImVec2 &a, const ImVec2 &b, ImU32 col, float rounding=0.0f, int rounding_corners=0x0F, float thickness=1.0f)
Definition: imgui_draw.cpp:806
IMGUI_API void SetCursorPosY(float y)
Definition: imgui.cpp:5108
unsigned long long get_frame_number() const
Definition: rs_frame.hpp:521
rs2_stream stream_type() const
Definition: rs_frame.hpp:39
void set_option(rs2_option option, float value) const
Definition: rs_options.hpp:99
metrics_model(viewer_model &viewer_model)
IMGUI_API void PlotLines(const char *label, const float *values, int values_count, int values_offset=0, const char *overlay_text=NULL, float scale_min=FLT_MAX, float scale_max=FLT_MAX, ImVec2 graph_size=ImVec2(0, 0), int stride=sizeof(float))
Definition: imgui.cpp:7211
static const ImVec4 dark_sensor_bg
Definition: model-views.h:63
IMGUI_API float GetCursorPosY()
Definition: imgui.cpp:5088
IMGUI_API bool IsItemHovered()
Definition: imgui.cpp:3200
GLint GLsizei width
IMGUI_API void PopFont()
Definition: imgui.cpp:4549
void update_device_data(const std::string &camera_info)
float x
Definition: imgui.h:90
IMGUI_API bool InputInt(const char *label, int *v, int step=1, int step_fast=100, ImGuiInputTextFlags extra_flags=0)
Definition: imgui.cpp:8296
IMGUI_API void PopStyleColor(int count=1)
Definition: imgui.cpp:4609
float height() const
Definition: ux-window.h:42
bool draw_instructions(ux_window &win, const rect &viewer_rect, bool &distance, bool &orientation)
T as() const
Definition: rs_frame.hpp:580
std::vector< std::shared_ptr< metric_plot > > _plots
std::string to_string(T value)


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:12