ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
RealSenseSensorConfig.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
9 
10 #include <Logging.h>
12 #include <json/json.h>
13 
14 #include <cstdlib>
15 #include <map>
16 #include <set>
17 #include <string>
18 #include <tuple>
19 #include <unordered_map>
20 
23 
24 namespace cloudViewer {
25 namespace t {
26 namespace io {
27 
28 // clang-format off
29 // Bidirectional string conversions for RS2 enums. Invalid values are mapped to
30 // the first entry. Reference:
31 // - https://intelrealsense.github.io/librealsense/doxygen/rs__sensor_8h.html
32 
34 STRINGIFY_ENUM(rs2_stream, {
35  {RS2_STREAM_ANY, "RS2_STREAM_ANY"},
36  {RS2_STREAM_DEPTH, "RS2_STREAM_DEPTH"},
37  {RS2_STREAM_COLOR, "RS2_STREAM_COLOR"},
38  {RS2_STREAM_INFRARED, "RS2_STREAM_INFRARED"},
39  {RS2_STREAM_FISHEYE, "RS2_STREAM_FISHEYE"},
40  {RS2_STREAM_GYRO, "RS2_STREAM_GYRO"},
41  {RS2_STREAM_ACCEL, "RS2_STREAM_ACCEL"},
42  {RS2_STREAM_GPIO, "RS2_STREAM_GPIO"},
43  {RS2_STREAM_POSE, "RS2_STREAM_POSE"},
44  {RS2_STREAM_CONFIDENCE, "RS2_STREAM_CONFIDENCE"}
45 });
46 
48 STRINGIFY_ENUM(rs2_format, {
49  {RS2_FORMAT_ANY, "RS2_FORMAT_ANY"},
50  {RS2_FORMAT_Z16, "RS2_FORMAT_Z16"},
51  {RS2_FORMAT_DISPARITY16, "RS2_FORMAT_DISPARITY16"},
52  {RS2_FORMAT_XYZ32F, "RS2_FORMAT_XYZ32F"},
53  {RS2_FORMAT_YUYV, "RS2_FORMAT_YUYV"},
54  {RS2_FORMAT_RGB8, "RS2_FORMAT_RGB8"},
55  {RS2_FORMAT_BGR8, "RS2_FORMAT_BGR8"},
56  {RS2_FORMAT_RGBA8, "RS2_FORMAT_RGBA8"},
57  {RS2_FORMAT_BGRA8, "RS2_FORMAT_BGRA8"},
58  {RS2_FORMAT_Y8, "RS2_FORMAT_Y8"},
59  {RS2_FORMAT_Y16, "RS2_FORMAT_Y16"},
60  {RS2_FORMAT_RAW10, "RS2_FORMAT_RAW10"},
61  {RS2_FORMAT_RAW16, "RS2_FORMAT_RAW16"},
62  {RS2_FORMAT_RAW8, "RS2_FORMAT_RAW8"},
63  {RS2_FORMAT_UYVY, "RS2_FORMAT_UYVY"},
64  {RS2_FORMAT_MOTION_RAW, "RS2_FORMAT_MOTION_RAW"},
65  {RS2_FORMAT_MOTION_XYZ32F, "RS2_FORMAT_MOTION_XYZ32F"},
66  {RS2_FORMAT_GPIO_RAW, "RS2_FORMAT_GPIO_RAW"},
67  {RS2_FORMAT_6DOF, "RS2_FORMAT_6DOF"},
68  {RS2_FORMAT_DISPARITY32, "RS2_FORMAT_DISPARITY32"},
69  {RS2_FORMAT_Y10BPACK, "RS2_FORMAT_Y10BPACK"},
70  {RS2_FORMAT_DISTANCE, "RS2_FORMAT_DISTANCE"},
71  {RS2_FORMAT_MJPEG, "RS2_FORMAT_MJPEG"},
72  {RS2_FORMAT_Y8I, "RS2_FORMAT_Y8I"},
73  {RS2_FORMAT_Y12I, "RS2_FORMAT_Y12I"},
74  {RS2_FORMAT_INZI, "RS2_FORMAT_INZI"},
75  {RS2_FORMAT_INVI, "RS2_FORMAT_INVI"},
76  {RS2_FORMAT_W10, "RS2_FORMAT_W10"},
77  {RS2_FORMAT_Z16H, "RS2_FORMAT_Z16H"}
78 });
79 
81 STRINGIFY_ENUM(rs2_l500_visual_preset, {
82  {RS2_L500_VISUAL_PRESET_DEFAULT, "RS2_L500_VISUAL_PRESET_DEFAULT"},
83  {RS2_L500_VISUAL_PRESET_CUSTOM, "RS2_L500_VISUAL_PRESET_CUSTOM"},
84  {RS2_L500_VISUAL_PRESET_NO_AMBIENT, "RS2_L500_VISUAL_PRESET_NO_AMBIENT"},
85  {RS2_L500_VISUAL_PRESET_LOW_AMBIENT, "RS2_L500_VISUAL_PRESET_LOW_AMBIENT"},
86  {RS2_L500_VISUAL_PRESET_MAX_RANGE, "RS2_L500_VISUAL_PRESET_MAX_RANGE"},
87  {RS2_L500_VISUAL_PRESET_SHORT_RANGE, "RS2_L500_VISUAL_PRESET_SHORT_RANGE"}
88 });
89 
91 STRINGIFY_ENUM(rs2_rs400_visual_preset, {
92  {RS2_RS400_VISUAL_PRESET_DEFAULT, "RS2_RS400_VISUAL_PRESET_DEFAULT"},
93  {RS2_RS400_VISUAL_PRESET_CUSTOM, "RS2_RS400_VISUAL_PRESET_CUSTOM"},
94  {RS2_RS400_VISUAL_PRESET_HAND, "RS2_RS400_VISUAL_PRESET_HAND"},
95  {RS2_RS400_VISUAL_PRESET_HIGH_ACCURACY, "RS2_RS400_VISUAL_PRESET_HIGH_ACCURACY"},
96  {RS2_RS400_VISUAL_PRESET_HIGH_DENSITY, "RS2_RS400_VISUAL_PRESET_HIGH_DENSITY"},
97  {RS2_RS400_VISUAL_PRESET_MEDIUM_DENSITY, "RS2_RS400_VISUAL_PRESET_MEDIUM_DENSITY"},
98  {RS2_RS400_VISUAL_PRESET_REMOVE_IR_PATTERN, "RS2_RS400_VISUAL_PRESET_REMOVE_IR_PATTERN"}
99 });
100 
101 // RS2 visual presets for SR300 devices
102 STRINGIFY_ENUM(rs2_sr300_visual_preset, {
103  {RS2_SR300_VISUAL_PRESET_DEFAULT, "RS2_SR300_VISUAL_PRESET_DEFAULT"},
104  {RS2_SR300_VISUAL_PRESET_SHORT_RANGE, "RS2_SR300_VISUAL_PRESET_SHORT_RANGE"},
105  {RS2_SR300_VISUAL_PRESET_LONG_RANGE, "RS2_SR300_VISUAL_PRESET_LONG_RANGE"},
106  {RS2_SR300_VISUAL_PRESET_BACKGROUND_SEGMENTATION, "RS2_SR300_VISUAL_PRESET_BACKGROUND_SEGMENTATION"},
107  {RS2_SR300_VISUAL_PRESET_GESTURE_RECOGNITION, "RS2_SR300_VISUAL_PRESET_GESTURE_RECOGNITION"},
108  {RS2_SR300_VISUAL_PRESET_OBJECT_SCANNING, "RS2_SR300_VISUAL_PRESET_OBJECT_SCANNING"},
109  {RS2_SR300_VISUAL_PRESET_FACE_ANALYTICS, "RS2_SR300_VISUAL_PRESET_FACE_ANALYTICS"},
110  {RS2_SR300_VISUAL_PRESET_FACE_LOGIN, "RS2_SR300_VISUAL_PRESET_FACE_LOGIN"},
111  {RS2_SR300_VISUAL_PRESET_GR_CURSOR, "RS2_SR300_VISUAL_PRESET_GR_CURSOR"},
112  {RS2_SR300_VISUAL_PRESET_MID_RANGE, "RS2_SR300_VISUAL_PRESET_MID_RANGE"},
113  {RS2_SR300_VISUAL_PRESET_IR_ONLY, "RS2_SR300_VISUAL_PRESET_IR_ONLY"}
114 });
115 // clang-format on
116 
117 std::pair<core::Dtype, uint8_t> RealSenseSensorConfig::get_dtype_channels(
118  int rs2_format_enum) {
119  static const std::unordered_map<rs2_format, core::Dtype> format_dtype = {
120  {RS2_FORMAT_Z16, core::UInt16}, {RS2_FORMAT_YUYV, core::UInt8},
121  {RS2_FORMAT_RGB8, core::UInt8}, {RS2_FORMAT_BGR8, core::UInt8},
122  {RS2_FORMAT_RGBA8, core::UInt8}, {RS2_FORMAT_BGRA8, core::UInt8},
123  {RS2_FORMAT_Y8, core::UInt8}, {RS2_FORMAT_Y16, core::UInt16}};
124  static const std::unordered_map<rs2_format, uint8_t> format_channels = {
125  {RS2_FORMAT_Z16, 1}, {RS2_FORMAT_YUYV, 2}, {RS2_FORMAT_RGB8, 3},
126  {RS2_FORMAT_BGR8, 3}, {RS2_FORMAT_RGBA8, 4}, {RS2_FORMAT_BGRA8, 4},
127  {RS2_FORMAT_Y8, 1}, {RS2_FORMAT_Y16, 1}};
128 
129  return std::make_pair(
130  format_dtype.at(static_cast<rs2_format>(rs2_format_enum)),
131  format_channels.at(static_cast<rs2_format>(rs2_format_enum)));
132 }
133 
134 static std::unordered_map<std::string, std::string> standard_config{
135  {"serial", ""},
136  {"color_format", "RS2_FORMAT_ANY"},
137  {"color_resolution", "0,0"},
138  {"depth_format", "RS2_FORMAT_ANY"},
139  {"depth_resolution", "0,0"},
140  {"fps", "0"},
141  {"visual_preset", "VISUAL_PRESET_DEFAULT"}};
142 
144 
146  const std::unordered_map<std::string, std::string> &config)
148  for (const auto &it : config) {
149  config_[it.first] = it.second;
150  }
151 }
152 
153 bool RealSenseSensorConfig::ConvertToJsonValue(Json::Value &value) const {
154  for (auto &kv : config_) {
155  value[kv.first] = config_.at(kv.first);
156  }
157  return true;
158 }
159 
160 bool RealSenseSensorConfig::ConvertFromJsonValue(const Json::Value &value) {
161  for (auto &kv : config_) {
162  config_.at(kv.first) = value[kv.first].asString();
163  }
164  return true;
165 }
166 
168  rs2::config cfg;
169  auto it = config_.find("serial");
170  if (it != config_.cend() && !it->second.empty())
171  cfg.enable_device(it->second);
172  cfg.disable_all_streams();
173 
174  auto set_config = [this](const std::string &stream_type) {
175  int width = 0, height = 0;
176  rs2_format format = RS2_FORMAT_ANY;
177  auto it = config_.find(stream_type + "_format");
178  if (it != config_.cend() && !it->second.empty())
179  enum_from_string(it->second, format);
180  it = config_.find(stream_type + "_resolution");
181  if (it != config_.cend() && !it->second.empty()) {
182  auto res = it->second.c_str();
183  char *remaining;
184  width = strtol(res, &remaining,
185  10); // [640],480 - return 0 if bad format
186  height = strtol(
187  remaining + 1, nullptr,
188  10); // 640,[480] - return 0 if bad format or no comma
189  }
190  return std::make_tuple(width, height, format);
191  };
192 
193  int width = 0, height = 0, fps = 0;
194  rs2_format format = RS2_FORMAT_ANY;
195  it = config_.find("fps");
196  if (it != config_.cend() && !it->second.empty()) fps = stoi(it->second);
197  std::tie(width, height, format) = set_config("color");
198  cfg.enable_stream(RS2_STREAM_COLOR, width, height, format, fps);
199  std::tie(width, height, format) = set_config("depth");
200  cfg.enable_stream(RS2_STREAM_DEPTH, width, height, format, fps);
201  return cfg;
202 }
203 
204 void RealSenseSensorConfig::GetPixelDtypes(const rs2::pipeline_profile &profile,
205  RGBDVideoMetadata &metadata) {
206  const auto rs_color = profile.get_stream(RS2_STREAM_COLOR)
207  .as<rs2::video_stream_profile>();
208  std::tie(metadata.color_dt_, metadata.color_channels_) =
210  static_cast<int>(rs_color.format()));
211  if (metadata.color_dt_ != core::UInt8) {
212  utility::LogError("Only 8 bit unsigned int color is supported!");
213  }
214  const auto rs_depth = profile.get_stream(RS2_STREAM_DEPTH)
215  .as<rs2::video_stream_profile>();
217  static_cast<int>(rs_depth.format()))
218  .first;
219  if (metadata.depth_dt_ != core::UInt16) {
220  utility::LogError("Only 16 bit unsigned int depth is supported!");
221  }
222 }
223 
225  const rs2::pipeline_profile &profile) {
226  if (!profile) {
227  utility::LogError("Invalid RealSense pipeline profile.");
228  }
229  Json::Value value;
230 
231  const auto rs_device = profile.get_device();
232  const auto rs_depth = profile.get_stream(RS2_STREAM_DEPTH)
233  .as<rs2::video_stream_profile>();
234  const auto rs_color = profile.get_stream(RS2_STREAM_COLOR)
235  .as<rs2::video_stream_profile>();
236 
237  rs2_intrinsics rgb_intr = rs_color.get_intrinsics();
238  camera::PinholeCameraIntrinsic pinhole_camera;
239  pinhole_camera.SetIntrinsics(rgb_intr.width, rgb_intr.height, rgb_intr.fx,
240  rgb_intr.fy, rgb_intr.ppx, rgb_intr.ppy);
241  // TODO: Add support for distortion
242  pinhole_camera.ConvertToJsonValue(value);
243 
244  value["device_name"] = rs_device.get_info(RS2_CAMERA_INFO_NAME);
245  value["serial_number"] = rs_device.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER);
246  value["depth_format"] = enum_to_string(rs_depth.format())
247  .substr(11); // remove RS2_FORMAT_ prefix
248  value["depth_scale"] =
249  1. / rs_device.first<rs2::depth_sensor>()
250  .get_depth_scale(); // convert meters -> m^(-1)
251  value["color_format"] = enum_to_string(rs_color.format())
252  .substr(11); // remove RS2_FORMAT_ prefix
253  value["fps"] = rs_color.fps();
254  if (value["fps"] != rs_depth.fps()) {
256  "Different frame rates for color ({} fps) and depth ({} fps) "
257  "streams is not supported.",
258  value["fps"], rs_depth.fps());
259  }
260  if (rs_device.is<rs2::playback>()) {
261  value["stream_length_usec"] =
262  std::chrono::duration_cast<std::chrono::microseconds>(
263  rs_device.as<rs2::playback>().get_duration())
264  .count();
265  }
266 
267  return value;
268 }
269 
270 } // namespace io
271 } // namespace t
272 } // namespace cloudViewer
filament::Texture::InternalFormat format
int width
int height
CloudViewerScene::LightingProfile profile
Contains the pinhole camera intrinsic parameters.
bool ConvertToJsonValue(Json::Value &value) const override
void SetIntrinsics(int width, int height, double fx, double fy, double cx, double cy)
Set camera intrinsic parameters.
core::Dtype depth_dt_
Pixel Dtype for depth data.
uint8_t color_channels_
Number of color channels.
core::Dtype color_dt_
Pixel Dtype for color data.
rs2::config ConvertToNativeConfig() const
Convert to RealSense config.
bool ConvertToJsonValue(Json::Value &value) const override
bool ConvertFromJsonValue(const Json::Value &value) override
RealSenseSensorConfig()
Default constructor, default configs will be used.
static void GetPixelDtypes(const rs2::pipeline_profile &profile, RGBDVideoMetadata &metadata)
static std::pair< core::Dtype, uint8_t > get_dtype_channels(int rs2_format_enum)
std::unordered_map< std::string, std::string > config_
static Json::Value GetMetadataJson(const rs2::pipeline_profile &profile)
Get metadata for a streaming RealSense camera or bag file.
#define LogError(...)
Definition: Logging.h:60
const Dtype UInt8
Definition: Dtype.cpp:48
CLOUDVIEWER_HOST_DEVICE Pair< First, Second > make_pair(const First &_first, const Second &_second)
Definition: SlabTraits.h:49
const Dtype UInt16
Definition: Dtype.cpp:49
STRINGIFY_ENUM(rs2_stream, { {RS2_STREAM_ANY, "RS2_STREAM_ANY"}, {RS2_STREAM_DEPTH, "RS2_STREAM_DEPTH"}, {RS2_STREAM_COLOR, "RS2_STREAM_COLOR"}, {RS2_STREAM_INFRARED, "RS2_STREAM_INFRARED"}, {RS2_STREAM_FISHEYE, "RS2_STREAM_FISHEYE"}, {RS2_STREAM_GYRO, "RS2_STREAM_GYRO"}, {RS2_STREAM_ACCEL, "RS2_STREAM_ACCEL"}, {RS2_STREAM_GPIO, "RS2_STREAM_GPIO"}, {RS2_STREAM_POSE, "RS2_STREAM_POSE"}, {RS2_STREAM_CONFIDENCE, "RS2_STREAM_CONFIDENCE"} })
RS2 stream types.
static std::unordered_map< std::string, std::string > standard_config
Generic file read and write utility for python interface.