12 namespace depth_quality
18 _update_readonly_options_timer(
std::
chrono::seconds(6)), _roi_percent(0.4
f),
27 _min_dist(300.
f), _max_dist(2000.
f), _max_angle(10.
f),
28 _metrics_model(_viewer_model)
44 bool valid_config =
false;
45 std::vector<rs2::config> cfgs;
49 bool usb3_device =
true;
54 bool usb3_device =
true;
58 usb3_device = !(std::string::npos != usb_type.find(
"2."));
64 int requested_fps = usb3_device ? 30 : 15;
71 cfgs.emplace_back(cfg_default);
78 cfgs.emplace_back(cfg_alt);
81 for (
auto&
cfg : cfgs)
83 if ((valid_config =
cfg.can_resolve(
_pipe)))
87 valid_config = active_profile;
110 if (!advanced_mode.is_enabled())
113 advanced_mode.toggle_advanced_mode(
true);
114 valid_config =
false;
152 if (second_line !=
"")
181 u8"\n \uf1b2 Please point the camera to a flat Wall / Surface!",
207 constexpr
const char* orientation_instruction =
" Recommended angle: < 3 degrees";
208 constexpr
const char* distance_instruction =
" Recommended distance: 0.3m-2m from the target";
213 u8"\n \uf061 Rotate the camera slightly Right",
214 orientation_instruction);
221 u8"\n \uf060 Rotate the camera slightly Left",
222 orientation_instruction);
229 u8"\n \uf062 Rotate the camera slightly Up",
230 orientation_instruction);
237 u8"\n \uf063 Rotate the camera slightly Down",
238 orientation_instruction);
245 u8"\n \uf0b2 Move the camera further Away",
246 distance_instruction);
254 u8"\n \uf066 Move the camera Closer to the wall",
255 distance_instruction);
265 static const float fade_factor = 0.6f;
277 bool any_guide = distance_guide || orientation_guide;
287 const auto window_y = viewer_rect.
y + viewer_rect.
h / 2;
288 const auto window_h = viewer_rect.
h / 2 - 5;
309 static float prev_x = 0.f;
310 static float prev_y = 0.f;
312 prev_x = (prev_x +
x) / 2.
f;
313 prev_y = (prev_y +
y) / 2.
f;
324 { pos1.x + 41, pos1.y + 40 }, 41,
327 for (
int i = 2;
i < 7;
i += 1)
330 float alpha = (1.f + float(sin(
t))) / 2.
f;
336 { pos1.x + 41 - 2 *
i * prev_x, pos1.y + 40 - 2 *
i * prev_y }, 40.f -
i*
i,
343 { pos1.x + 41 + 70 * prev_x, pos1.y + 40 + 70 * prev_y }, 10.f,
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;
370 { pos1.x + 1, pos1.y },
371 { pos1.x + 81, max_y - 5 },
374 for (
int i = 0;
i < parts;
i++)
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);
386 ImColor(
blend(
c, distance_guide ? 1.
f : fade_factor * fade_factor)));
397 for (
int j = -2;
j < 2;
j++)
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));
410 for (
int j = 1;
j < 5;
j++)
413 auto alpha = (1 + float(sin(
t))) / 2.
f;
425 for (
int j = 1;
j < 5;
j++)
428 auto alpha = (1.f + float(sin(
t))) / 2.
f;
466 bool distance_guide =
false;
467 bool orientation_guide =
false;
468 bool found =
draw_instructions(win, viewer_rect, distance_guide, orientation_guide);
492 std::vector<std::function<void()>> draw_later;
494 auto json_loaded =
false;
499 [&](std::function<
void()>
func)
501 auto profile =_pipe.get_active_profile();
505 auto streams = profile.get_streams();
508 for (auto&& s : streams)
510 cfg.enable_stream(s.stream_type(), s.stream_index(), s.format(), s.fps());
525 for (
auto&& lambda : draw_later)
535 catch (
const std::exception& e)
571 cfg.
enable_stream(primary.stream_type(), primary.stream_index(),
572 primary.width(), primary.height(), primary.format(), primary.fps());
574 primary.width(), primary.height(), secondary.
format(), primary.fps());
606 std::this_thread::sleep_for(std::chrono::milliseconds(100));
628 static std::vector<std::string> items{
"80%",
"60%",
"40%",
"20%" };
632 bool allow_changing_roi =
true;
641 allow_changing_roi =
false;
642 _error_message =
"ROI cannot be changed while IR Reflectivity is enabled";
648 if (allow_changing_roi)
672 bool current_ir_reflectivity_opt
676 ¤t_ir_reflectivity_opt))
681 current_ir_reflectivity_opt);
684 =
"Please set 'VGA' resolution, 'Max Range' preset and " 685 "20% ROI before enabling IR Reflectivity";
692 ds.get_option_description(
698 catch (
const std::exception&
e)
709 ImGui::SetTooltip(
"Estimated distance to an average within the ROI of the target (wall) in mm");
713 static float prev_metric_distance = 0;
722 prev_metric_distance = curr_metric_distance;
766 static float prev_metric_angle = 0;
775 prev_metric_angle = curr_metric_angle;
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");
853 catch(
const std::exception & e )
865 "Unknown error occurred" );
888 s->streaming =
false;
916 auto baseline_mm = -1.f;
927 auto extrin = (*left_sensor).get_extrinsics_to(*right_sensor);
928 baseline_mm = fabs(extrin.translation[0]) * 1000;
949 sub->show_algo_roi =
true;
952 sub->streaming =
true;
956 sub->_options_invalidated =
true;
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;
1005 for (
int i = 0;
i < curr_window;
i++)
1007 auto val = fabs(best - _vals[(SIZE + _idx -
i) % SIZE]);
1008 min_val +=
val / curr_window;
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++;
1023 _depth_scale_units(0.
f),
1024 _stereo_baseline_mm(0.
f),
1025 _ground_truth_mm(0),
1028 _roi_percentage(0.4
f),
1030 _recorder(viewer_model)
1038 std::this_thread::sleep_for(std::chrono::milliseconds(10));
1042 std::vector<single_metric_data>
sample;
1043 for (
auto&&
f : frames)
1046 auto stream_type =
profile.stream_type();
1054 bool plane_fit_set{};
1057 std::lock_guard<std::mutex>
lock(
_m);
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)) };
1071 std::tie(gt_mm, plane_fit_set) =
get_inputs();
1076 std::lock_guard<std::mutex>
lock(
_m);
1086 std::this_thread::sleep_for(std::chrono::milliseconds(80));
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 });
1114 if (_pipe.get_active_profile())
1115 dev = _pipe.get_active_profile().get_device();
1124 std::stringstream ss;
1125 ss <<
"Device Info:" 1130 <<
"\n\nStreaming profile:\nStream,Format,Resolution,FPS\n";
1132 for (
auto&
stream : _pipe.get_active_profile().get_streams())
1135 ss <<
vs.stream_name() <<
"," 1137 <<
vs.width() <<
"x" <<
vs.height() <<
"," <<
vs.fps() <<
"\n";
1145 std::lock_guard<std::mutex>
lock(
_m);
1147 if (!_persistent_visibility.eval())
return;
1149 std::stringstream ss;
1150 auto val = _vals[(SIZE + _idx - 1) % SIZE];
1152 ss << _label << std::setprecision(2) << std::fixed << std::setw(3) <<
val <<
" " << _units;
1157 if (
range == GREEN_RANGE)
1159 else if (
range == YELLOW_RANGE)
1161 else if (
range == RED_RANGE)
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)));
1174 _trending_up.add_value(has_trend(
true));
1175 _trending_down.add_value(has_trend(
false));
1177 if (_trending_up.eval())
1193 else if (_trending_down.eval())
1225 ImVec2 desc_size = { 270, 50 };
1226 auto lines =
std::count(_description.begin(), _description.end(),
'\n') + 1;
1227 desc_size.
y = lines * 20.f;
1232 ImGui::PlotLines(_id.c_str(), (
float*)&_vals,
int(SIZE), int(_idx), ss.str().c_str(), _min, _max, { 270, 50 });
1244 for (
auto&& plot :
_plots)
1254 csv.open(_filename_base +
"_depth_metrics.csv");
1257 csv << _metrics->_camera_info;
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;
1264 csv <<
"\nSample Id,Frame #,Timestamp (ms),";
1265 auto records_data = _metric_data;
1267 records_data.push_back({
"Plane Fit RMS Error mm" ,
"" });
1268 for (
auto&&
metric : records_data)
1276 for (
auto&&
it: _samples)
1278 csv <<
i++ <<
","<<
it.frame_number <<
"," << std::fixed << std::setprecision(4) <<
it.timestamp <<
",";
1279 for (
auto&&
metric : records_data)
1282 if (samp !=
it.samples.end()) csv << samp->val;
1294 auto filename_base = _filename_base;
1296 auto loc = filename_base.find_last_of(
".");
1297 if (loc != std::string::npos)
1298 filename_base.erase(loc, std::string::npos);
1300 std::stringstream fn;
1303 for (
auto&&
frame : frames)
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());
1327 auto filename = filename_base +
"_" + stream_desc +
"_" + fn.str() +
".raw";
1334 filename = filename_base +
"_" + stream_desc +
"_" + fn.str() +
"_metadata.csv";
1344 if (_viewer_model.selected_tex_source_uid >= 0)
1346 for (
auto&&
frame : frames)
1350 ply_texture =
frame;
1351 _pc.map_to(ply_texture);
1358 auto fname = filename_base +
"_" + fn.str() +
"_3d_mesh.ply";
1359 std::unique_ptr<rs2::filter> exporter;
static const textual_icon lock
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val)
int selected_tex_source_uid
static const ImVec4 white
const char * rs2_format_to_string(rs2_format format)
IMGUI_API float GetCursorPosX()
IMGUI_API void AddRectFilled(const ImVec2 &a, const ImVec2 &b, ImU32 col, float rounding=0.0f, int rounding_corners=0x0F)
static const auto imgui_flags
rs2_sensor_mode resolution_from_width_height(int width, int height)
IMGUI_API ImVec2 GetCursorPos()
rs2::frame handle_ready_frames(const rect &viewer_rect, ux_window &window, int devices, std::string &error_message)
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)
GLuint const GLchar * name
IMGUI_API void AddCircle(const ImVec2 ¢re, float radius, ImU32 col, int num_segments=12, float thickness=1.0f)
ImVec4 from_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a, bool consistent_color)
GLsizei GLenum const void GLuint GLsizei GLfloat * metrics
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)
IMGUI_API void SetCursorPos(const ImVec2 &local_pos)
static const ImVec4 light_grey
void update_roi_attributes(const region_of_interest &roi, float roi_percent)
std::array< float3, 4 > get_plane()
static const ImVec4 light_blue
void begin_process_frame(rs2::frame f)
void disable_ground_truth()
std::enable_if< std::is_base_of< rs2::frame, T >::value, bool >::type poll_for_frame(T *output) const
stream_profile get_profile() const
device_list query_devices() const
std::map< int, stream_model > streams
std::unordered_set< int > _hidden_options
region_of_interest get_roi()
IMGUI_API void SetNextWindowPos(const ImVec2 &pos, ImGuiSetCond cond=0)
void stop_record(device_model *dev)
void draw_notification(ux_window &win, const rect &viewer_rect, int w, const std::string &msg, const std::string &second_line)
snapshot_metrics get_last_metrics()
void add_on_load_message(const std::string &msg)
IMGUI_API bool TreeNodeEx(const char *label, ImGuiTreeNodeFlags flags=0)
GLdouble GLdouble GLdouble w
GLsizei const GLchar *const * string
std::atomic< bool > synchronization_enable
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLfloat distance
IMGUI_API void AddLine(const ImVec2 &a, const ImVec2 &b, ImU32 col, float thickness=1.0f)
void record_frames(const frameset &frame)
void update_3d_camera(ux_window &win, const rect &viewer_rect, bool force=false)
std::thread _worker_thread
IMGUI_API bool TreeNode(const char *label)
IMGUI_API ImVec2 GetContentRegionMax()
bool is_valid(const plane_3d &p)
std::shared_ptr< notifications_model > not_model
bool _support_ir_reflectivity
rs2_intrinsics _depth_intrinsic
ImFont * get_font() const
static const textual_icon usb_type
def info(name, value, persistent=False)
void set_plane_fit(bool found)
IMGUI_API void SameLine(float pos_x=0.0f, float spacing_w=-1.0f)
std::string error_to_string(const error &e)
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()
IMGUI_API bool Begin(const char *name, bool *p_open=NULL, ImGuiWindowFlags flags=0)
metrics_recorder _recorder
IMGUI_API void PopStyleVar(int count=1)
IMGUI_API void Dummy(const ImVec2 &size)
static const ImVec4 regular_blue
double get_elapsed_ms() const
GLint GLsizei GLsizei height
void serialize_to_csv() const
IMGUI_API void SetNextWindowSize(const ImVec2 &size, ImGuiSetCond cond=0)
static const ImVec4 sensor_bg
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)
void disable_stream(rs2_stream stream, int index=-1)
static const ImVec4 sensor_header_light_blue
IMGUI_API void PushItemWidth(float item_width)
IMGUI_API void Text(const char *fmt,...) IM_PRINTFARGS(1)
static const ImVec4 device_info_color
IMGUI_API bool Button(const char *label, const ImVec2 &size=ImVec2(0, 0))
void update_stream_attributes(const rs2_intrinsics &intrinsic, float scale_units, float baseline)
static const ImVec4 button_color
void begin_stream(std::shared_ptr< subdevice_model > d, rs2::stream_profile p)
std::array< float3, 4 > roi_rect
IMGUI_API void AddCircleFilled(const ImVec2 ¢re, float radius, ImU32 col, int num_segments=12)
bool supports(rs2_camera_info info) const
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)
bool can_resolve(std::shared_ptr< rs2_pipeline > p) const
bool has_trend(bool positive)
float _stereo_baseline_mm
device get_device() const
IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4 &col)
IMGUI_API void PushFont(ImFont *font)
post_processing_filters ppf
rs2_format format() const
IMGUI_API ImVec2 GetCursorScreenPos()
ImVec4 blend(const ImVec4 &c, float a)
bool val_in_range(const T &val, const std::initializer_list< T > &list)
pipeline_profile resolve(std::shared_ptr< rs2_pipeline > p) const
std::vector< stream_profile > get_streams() const
IMGUI_API void PopItemWidth()
const char * rs2_stream_to_string(rs2_stream stream)
void set_ground_truth(int gt)
bool support_non_syncronized_mode
void render(ux_window &win)
bool allow_3d_source_change
IMGUI_API bool Checkbox(const char *label, bool *v)
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
std::vector< std::unique_ptr< device_model > > device_models_list
void set_devices_changed_callback(T callback)
IMGUI_API void SetCursorScreenPos(const ImVec2 &pos)
void add_sample(rs2::frameset &frames, std::vector< single_metric_data > sample)
static const ImVec4 redish
IMGUI_API void SetContentRegionWidth(float y)
snapshot_metrics _latest_metrics
std::map< int, rs2::frame_queue > frames_queue
int selected_depth_source_uid
std::array< float, 3 > color
static const ImVec4 yellow
ImFont * get_large_font() const
pipeline_profile get_active_profile() const
void show_top_bar(ux_window &window, const rect &viewer_rect, const device_models_list &devices)
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)
IMGUI_API void SetCursorPosY(float y)
void render(ux_window &win)
unsigned long long get_frame_number() const
rs2_stream stream_type() const
void set_option(rs2_option option, float value) const
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))
static const ImVec4 dark_sensor_bg
IMGUI_API float GetCursorPosY()
IMGUI_API bool IsItemHovered()
void update_device_data(const std::string &camera_info)
IMGUI_API bool InputInt(const char *label, int *v, int step=1, int step_fast=100, ImGuiInputTextFlags extra_flags=0)
IMGUI_API void PopStyleColor(int count=1)
std::vector< std::shared_ptr< metric_plot > > _plots
std::string to_string(T value)