rs-convert.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2018 Intel Corporation. All Rights Reserved.
3 
4 #include <iostream>
5 
6 #include "librealsense2/rs.hpp"
7 
8 #include "tclap/CmdLine.h"
9 
15 
16 #include <mutex>
17 
18 #define SECONDS_TO_NANOSECONDS 1000000000
19 
20 using namespace std;
21 using namespace TCLAP;
22 
23 
24 int main(int argc, char** argv) try
25 {
26 #ifdef BUILD_EASYLOGGINGPP
28 #endif
29 
30  // Parse command line arguments
31  CmdLine cmd("librealsense rs-convert tool", ' ');
32  ValueArg<string> inputFilename("i", "input", "ROS-bag filename", true, "", "ros-bag-file");
33  ValueArg<string> outputFilenamePng("p", "output-png", "output PNG file(s) path", false, "", "png-path");
34  ValueArg<string> outputFilenameCsv("v", "output-csv", "output CSV (depth matrix) file(s) path", false, "", "csv-path");
35  ValueArg<string> outputFilenameRaw("r", "output-raw", "output RAW file(s) path", false, "", "raw-path");
36  ValueArg<string> outputFilenamePly("l", "output-ply", "output PLY file(s) path", false, "", "ply-path");
37  ValueArg<string> outputFilenameBin("b", "output-bin", "output BIN (depth matrix) file(s) path", false, "", "bin-path");
38  SwitchArg switchDepth("d", "depth", "convert depth frames (default - all supported)", false);
39  SwitchArg switchColor("c", "color", "convert color frames (default - all supported)", false);
40  ValueArg <string> frameNumberStart("f", "first-framenumber", "ignore frames whose frame number is less than this value", false, "", "first-framenumber");
41  ValueArg <string> frameNumberEnd("t", "last-framenumber", "ignore frames whose frame number is greater than this value", false, "", "last-framenumber");
42  ValueArg <string> startTime("s", "start-time", "ignore frames whose timestamp is less than this value (the first frame is at time 0)", false, "", "start-time");
43  ValueArg <string> endTime("e", "end-time", "ignore frames whose timestamp is greater than this value (the first frame is at time 0)", false, "", "end-time");
44 
45 
46  cmd.add(inputFilename);
47  cmd.add(frameNumberEnd);
48  cmd.add(frameNumberStart);
49  cmd.add(endTime);
50  cmd.add(startTime);
51  cmd.add(outputFilenamePng);
52  cmd.add(outputFilenameCsv);
53  cmd.add(outputFilenameRaw);
54  cmd.add(outputFilenamePly);
55  cmd.add(outputFilenameBin);
56  cmd.add(switchDepth);
57  cmd.add(switchColor);
58  cmd.parse(argc, argv);
59 
60  vector<shared_ptr<rs2::tools::converter::converter_base>> converters;
61  shared_ptr<rs2::tools::converter::converter_ply> plyconverter;
62 
63  rs2_stream streamType = switchDepth.isSet() ? rs2_stream::RS2_STREAM_DEPTH
64  : switchColor.isSet() ? rs2_stream::RS2_STREAM_COLOR
66 
67  if (outputFilenameCsv.isSet())
68  {
69  converters.push_back(
70  make_shared<rs2::tools::converter::converter_csv>(
71  outputFilenameCsv.getValue()
72  , streamType));
73  }
74 
75  if (outputFilenamePng.isSet())
76  {
77  converters.push_back(
78  make_shared<rs2::tools::converter::converter_png>(
79  outputFilenamePng.getValue()
80  , streamType));
81  }
82 
83  if (outputFilenameRaw.isSet())
84  {
85  converters.push_back(
86  make_shared<rs2::tools::converter::converter_raw>(
87  outputFilenameRaw.getValue()
88  , streamType));
89  }
90 
91  if (outputFilenameBin.isSet())
92  {
93  converters.push_back(
94  make_shared<rs2::tools::converter::converter_bin>(
95  outputFilenameBin.getValue()));
96  }
97 
98  if (converters.empty() && !outputFilenamePly.isSet())
99  {
100  throw runtime_error("output not defined");
101  }
102 
103  unsigned long long first_frame = 0;
104  unsigned long long last_frame = 0;
105  uint64_t start_time = 0;
106  uint64_t end_time = 0;
107 
108  if (frameNumberStart.isSet())
109  {
110  first_frame = stoi(frameNumberStart.getValue());
111  }
112  if (frameNumberEnd.isSet())
113  {
114  last_frame = stoi(frameNumberEnd.getValue());
115  }
116  if (startTime.isSet())
117  {
118  start_time = (uint64_t) (SECONDS_TO_NANOSECONDS * (std::strtod( startTime.getValue().c_str(), nullptr )));
119  }
120  if (endTime.isSet())
121  {
122  end_time = (uint64_t) (SECONDS_TO_NANOSECONDS * (std::strtod( endTime.getValue().c_str(), nullptr )));
123  }
124 
125  //in order to convert frames into ply we need synced depth and color frames,
126  //therefore we use pipeline
127  if (outputFilenamePly.isSet()) {
128 
129  // Since we are running in blocking "non-real-time" mode,
130  // we don't want to prevent process termination if some of the frames
131  // did not find a match and hence were not serviced
132  auto pipe = std::shared_ptr<rs2::pipeline>(
133  new rs2::pipeline(), [](rs2::pipeline*) {});
134 
135  plyconverter = make_shared<rs2::tools::converter::converter_ply>(
136  outputFilenamePly.getValue());
137 
139  cfg.enable_device_from_file(inputFilename.getValue());
140  pipe->start(cfg);
141 
142  auto device = pipe->get_active_profile().get_device();
143  rs2::playback playback = device.as<rs2::playback>();
144  playback.set_real_time(false);
145 
146  auto duration = playback.get_duration();
147  int progress = 0;
148  auto frameNumber = 0ULL;
149 
150  rs2::frameset frameset;
151  uint64_t posCurr = playback.get_position();
152 
153  // try_wait_for_frames will keep repeating the last frame at the end of the file,
154  // so we need to exit the look in some other way!
155  while (pipe->try_wait_for_frames(&frameset, 1000))
156  {
157  int posP = static_cast<int>(posCurr * 100. / duration.count());
158  if (posP > progress)
159  {
160  progress = posP;
161  cout << posP << "%" << "\r" << flush;
162  }
163 
164  frameNumber = frameset[0].get_frame_number();
165 
166  bool process_frame = true;
167  if (frameNumberStart.isSet() && frameNumber < first_frame)
168  process_frame = false;
169  else if (frameNumberEnd.isSet() && frameNumber > last_frame)
170  process_frame = false;
171  else if (startTime.isSet() && posCurr < start_time)
172  process_frame = false;
173  else if (endTime.isSet() && posCurr > end_time)
174  process_frame = false;
175 
176  if( process_frame )
177  {
178  plyconverter->convert(frameset);
179  plyconverter->wait();
180  }
181 
182  auto posNext = playback.get_position();
183 
184 
185  if (posNext < posCurr)
186  break;
187 
188  posCurr = posNext;
189  }
190  }
191 
192  // for every converter other than ply,
193  // we get the frames from playback sensors
194  // and convert them one by one
195  if( ! converters.empty() )
196  {
198  auto playback = ctx.load_device(inputFilename.getValue());
199  playback.set_real_time(false);
200  std::vector<rs2::sensor> sensors = playback.query_sensors();
201  std::mutex mutex;
202 
203  auto duration = playback.get_duration();
204  int progress = 0;
205  uint64_t posCurr = playback.get_position();
206 
207  for (auto sensor : sensors)
208  {
209  if (!sensor.get_stream_profiles().size())
210  {
211  continue;
212  }
213 
214  sensor.open(sensor.get_stream_profiles());
215  sensor.start([&](rs2::frame frame)
216  {
217  std::lock_guard<std::mutex> lock(mutex);
218 
219  auto frameNumber = frame.get_frame_number();
220 
221  if (frameNumberStart.isSet() && frameNumber < first_frame)
222  return;
223  if (frameNumberEnd.isSet() && frameNumber > last_frame)
224  return;
225  if (startTime.isSet() && posCurr < start_time)
226  return;
227  if (endTime.isSet() && posCurr > end_time)
228  return;
229 
230  for_each(converters.begin(), converters.end(),
231  [&frame](shared_ptr<rs2::tools::converter::converter_base>& converter) {
232  converter->convert(frame);
233  });
234 
235  for_each(converters.begin(), converters.end(),
236  [](shared_ptr<rs2::tools::converter::converter_base>& converter) {
237  converter->wait();
238  });
239  });
240 
241  }
242 
243  //we need to clear the output of ply progress ("100%") before writing
244  //the progress of the other converters in the same line
245  cout << "\r \r";
246 
247  while (true)
248  {
249  int posP = static_cast<int>(posCurr * 100. / duration.count());
250 
251  if (posP > progress)
252  {
253  progress = posP;
254  cout << posP << "%" << "\r" << flush;
255  }
256 
257  const uint64_t posNext = playback.get_position();
258  if (posNext < posCurr)
259  break;
260 
261  posCurr = posNext;
262  }
263 
264  for (auto sensor : sensors)
265  {
266  if (!sensor.get_stream_profiles().size())
267  {
268  continue;
269  }
270  sensor.stop();
271  sensor.close();
272  }
273  }
274 
275  cout << endl;
276 
277  //print statistics for ply converter.
278  if (outputFilenamePly.isSet()) {
279  cout << plyconverter->get_statistics() << endl;
280  }
281 
282  for_each(converters.begin(), converters.end(),
283  [](shared_ptr<rs2::tools::converter::converter_base>& converter) {
284  cout << converter->get_statistics() << endl;
285  });
286 
287 
288  return EXIT_SUCCESS;
289 }
290 catch (const rs2::error & e)
291 {
292  cerr << "RealSense error calling " << e.get_failed_function()
293  << "(" << e.get_failed_args() << "):\n " << e.what() << endl;
294 
295  return EXIT_FAILURE;
296 }
297 catch (const exception & e)
298 {
299  cerr << e.what() << endl;
300  return EXIT_FAILURE;
301 }
302 catch (...)
303 {
304  cerr << "some error" << endl;
305  return EXIT_FAILURE;
306 }
static const textual_icon lock
Definition: model-views.h:218
playback load_device(const std::string &file)
Definition: rs_context.hpp:184
def progress(args)
Definition: log.py:43
#define SECONDS_TO_NANOSECONDS
Definition: rs-convert.cpp:18
e
Definition: rmse.py:177
const std::string & get_failed_args() const
Definition: rs_types.hpp:117
std::ostream & cout()
bool isSet() const
Definition: Arg.h:575
unsigned __int64 uint64_t
Definition: stdint.h:90
void log_to_file(rs2_log_severity min_severity, const char *file_path=nullptr)
Definition: rs.hpp:26
uint64_t get_position() const
rs2_stream
Streams are different types of data provided by RealSense devices.
Definition: rs_sensor.h:42
T & getValue()
Definition: ValueArg.h:322
void parse(int argc, const char *const *argv)
Definition: CmdLine.h:433
int main(int argc, char **argv)
Definition: rs-convert.cpp:24
std::chrono::nanoseconds get_duration() const
void set_real_time(bool real_time) const
std::ostream & cerr()
void add(Arg &a)
Definition: CmdLine.h:413
int stoi(const std::string &value)
Definition: Arg.h:57
unsigned long long get_frame_number() const
Definition: rs_frame.hpp:521
auto device
Definition: pyrs_net.cpp:17
const std::string & get_failed_function() const
Definition: rs_types.hpp:112


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