Intel® RealSense™ Cross Platform API  2.13.0
Intel Realsense Cross-platform API
rs_processing.hpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2017 Intel Corporation. All Rights Reserved.
3 
4 #ifndef LIBREALSENSE_RS2_PROCESSING_HPP
5 #define LIBREALSENSE_RS2_PROCESSING_HPP
6 
7 #include "rs_types.hpp"
8 #include "rs_frame.hpp"
9 #include "rs_context.hpp"
10 
11 namespace rs2
12 {
14  {
15  public:
17  const frame& original,
18  int new_bpp = 0,
19  int new_width = 0,
20  int new_height = 0,
21  int new_stride = 0,
22  rs2_extension frame_type = RS2_EXTENSION_VIDEO_FRAME) const
23  {
24  rs2_error* e = nullptr;
25  auto result = rs2_allocate_synthetic_video_frame(_source, profile.get(),
26  original.get(), new_bpp, new_width, new_height, new_stride, frame_type, &e);
27  error::handle(e);
28  return result;
29  }
30 
31  frame allocate_composite_frame(std::vector<frame> frames) const
32  {
33  rs2_error* e = nullptr;
34 
35  std::vector<rs2_frame*> refs(frames.size(), (rs2_frame*)nullptr);
36  for (size_t i = 0; i < frames.size(); i++)
37  std::swap(refs[i], frames[i].frame_ref);
38 
39  auto result = rs2_allocate_composite_frame(_source, refs.data(), (int)refs.size(), &e);
40  error::handle(e);
41  return result;
42  }
43 
44  void frame_ready(frame result) const
45  {
46  rs2_error* e = nullptr;
47  rs2_synthetic_frame_ready(_source, result.get(), &e);
48  error::handle(e);
49  result.frame_ref = nullptr;
50  }
51 
53  private:
54  template<class T>
56 
57  frame_source(rs2_source* source) : _source(source) {}
58  frame_source(const frame_source&) = delete;
59 
60  };
61 
62  template<class T>
64  {
65  T on_frame_function;
66  public:
67  explicit frame_processor_callback(T on_frame) : on_frame_function(on_frame) {}
68 
69  void on_frame(rs2_frame* f, rs2_source * source) override
70  {
71  frame_source src(source);
72  frame frm(f);
73  on_frame_function(std::move(frm), src);
74  }
75 
76  void release() override { delete this; }
77  };
78 
79  class processing_block : public options
80  {
81  public:
82  template<class S>
83  void start(S on_frame)
84  {
85  rs2_error* e = nullptr;
86  rs2_start_processing(_block.get(), new frame_callback<S>(on_frame), &e);
87  error::handle(e);
88  }
89 
90  template<class S>
91  S& operator>>(S& on_frame)
92  {
93  start(on_frame);
94  return on_frame;
95  }
96 
97  void invoke(frame f) const
98  {
99  rs2_frame* ptr = nullptr;
100  std::swap(f.frame_ref, ptr);
101 
102  rs2_error* e = nullptr;
103  rs2_process_frame(_block.get(), ptr, &e);
104  error::handle(e);
105  }
106 
107  void operator()(frame f) const
108  {
109  invoke(std::move(f));
110  }
111 
112  processing_block(std::shared_ptr<rs2_processing_block> block)
113  : options((rs2_options*)block.get()),_block(block)
114  {
115  }
116 
117  template<class S>
118  processing_block(S processing_function)
119  {
120  rs2_error* e = nullptr;
121  _block = std::shared_ptr<rs2_processing_block>(
122  rs2_create_processing_block(new frame_processor_callback<S>(processing_function),&e),
124  options::operator=(_block);
125  error::handle(e);
126  }
127 
128  operator rs2_options*() const { return (rs2_options*)_block.get(); }
129 
130  private:
131  std::shared_ptr<rs2_processing_block> _block;
132  };
133 
135  {
136  public:
142  explicit frame_queue(unsigned int capacity): _capacity(capacity)
143  {
144  rs2_error* e = nullptr;
145  _queue = std::shared_ptr<rs2_frame_queue>(
148  error::handle(e);
149  }
150 
152 
157  void enqueue(frame f) const
158  {
159  rs2_enqueue_frame(f.frame_ref, _queue.get()); // noexcept
160  f.frame_ref = nullptr; // frame has been essentially moved from
161  }
162 
167  frame wait_for_frame(unsigned int timeout_ms = 5000) const
168  {
169  rs2_error* e = nullptr;
170  auto frame_ref = rs2_wait_for_frame(_queue.get(), timeout_ms, &e);
171  error::handle(e);
172  return{ frame_ref };
173  }
174 
180  template<typename T>
181  typename std::enable_if<std::is_base_of<rs2::frame, T>::value, bool>::type poll_for_frame(T* output) const
182  {
183  rs2_error* e = nullptr;
184  rs2_frame* frame_ref = nullptr;
185  auto res = rs2_poll_for_frame(_queue.get(), &frame_ref, &e);
186  error::handle(e);
187  frame f{ frame_ref };
188  if (res) *output = f;
189  return res > 0;
190  }
191 
192  void operator()(frame f) const
193  {
194  enqueue(std::move(f));
195  }
196 
197  size_t capacity() const { return _capacity; }
198 
199  private:
200  std::shared_ptr<rs2_frame_queue> _queue;
201  size_t _capacity;
202  };
203 
204  class pointcloud : public options
205  {
206  public:
207  pointcloud() : _queue(1)
208  {
209  rs2_error* e = nullptr;
210 
211  auto pb = std::shared_ptr<rs2_processing_block>(
214  _block = std::make_shared<processing_block>(pb);
215 
216  error::handle(e);
217 
218  // Redirect options API to the processing block
219  options::operator=(pb);
220 
221  _block->start(_queue);
222  }
223 
225  {
226  _block->invoke(std::move(depth));
227  rs2::frame f;
228  if (!_queue.poll_for_frame(&f))
229  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
230  return points(f);
231  }
232 
233  void map_to(frame mapped)
234  {
235  _block->set_option(RS2_OPTION_TEXTURE_SOURCE, float(mapped.get_profile().unique_id()));
236  _block->invoke(std::move(mapped));
237  }
238  private:
239  friend class context;
240 
241  std::shared_ptr<processing_block> _block;
242  frame_queue _queue;
243  };
244 
246  {
247  public:
249  {
250  rs2_error* e = nullptr;
251  _processing_block = std::make_shared<processing_block>(
252  std::shared_ptr<rs2_processing_block>(
255 
256  error::handle(e);
257  }
258 
259  template<class S>
260  void start(S on_frame)
261  {
262  _processing_block->start(on_frame);
263  }
264 
265  void operator()(frame f) const
266  {
267  _processing_block->operator()(std::move(f));
268  }
269  private:
270  std::shared_ptr<processing_block> _processing_block;
271  };
272 
273  class syncer
274  {
275  public:
276  syncer(int queue_size = 1)
277  :_results(queue_size)
278  {
279  _sync.start(_results);
280 
281  }
282 
288  frameset wait_for_frames(unsigned int timeout_ms = 5000) const
289  {
290  return frameset(_results.wait_for_frame(timeout_ms));
291  }
292 
298  bool poll_for_frames(frameset* fs) const
299  {
300  frame result;
301  if (_results.poll_for_frame(&result))
302  {
303  *fs = frameset(result);
304  return true;
305  }
306  return false;
307  }
308 
309  void operator()(frame f) const
310  {
311  _sync(std::move(f));
312  }
313  private:
314  asynchronous_syncer _sync;
315  frame_queue _results;
316  };
317 
321  class align
322  {
323  public:
333  align(rs2_stream align_to) :_queue(1)
334  {
335  rs2_error* e = nullptr;
336  _block = std::make_shared<processing_block>(
337  std::shared_ptr<rs2_processing_block>(
338  rs2_create_align(align_to, &e),
340  error::handle(e);
341 
342  _block->start(_queue);
343  }
344 
352  {
353  (*_block)(frame);
354  rs2::frame f;
355  if (!_queue.poll_for_frame(&f))
356  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
357  return frameset(f);
358  }
359 
360  void operator()(frame f) const
361  {
362  (*_block)(std::move(f));
363  }
364  private:
365  friend class context;
366 
367  std::shared_ptr<processing_block> _block;
368  frame_queue _queue;
369  };
370 
371  class colorizer : public options
372  {
373  public:
374  colorizer() : _queue(1)
375  {
376  rs2_error* e = nullptr;
377  auto pb = std::shared_ptr<rs2_processing_block>(
380  _block = std::make_shared<processing_block>(pb);
381  error::handle(e);
382 
383  // Redirect options API to the processing block
384  options::operator=(pb);
385 
386  _block->start(_queue);
387  }
388 
390  {
391  if(depth)
392  {
393  _block->invoke(std::move(depth));
394  rs2::frame f;
395  if (!_queue.poll_for_frame(&f))
396  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
397  return video_frame(f);
398  }
399  return depth;
400  }
401 
402  video_frame operator()(frame depth) const { return colorize(depth); }
403 
404  private:
405  std::shared_ptr<processing_block> _block;
406  frame_queue _queue;
407  };
408 
412  class process_interface : public options
413  {
414  public:
415  virtual rs2::frame process(rs2::frame frame) = 0;
416  virtual void operator()(frame f) const = 0;
417  virtual ~process_interface() = default;
418  };
419 
421  {
422  public:
423  decimation_filter() :_queue(1)
424  {
425  rs2_error* e = nullptr;
426  auto pb = std::shared_ptr<rs2_processing_block>(
429  _block = std::make_shared<processing_block>(pb);
430  error::handle(e);
431 
432  // Redirect options API to the processing block
433  options::operator=(pb);
434 
435  _block->start(_queue);
436  }
437 
439  {
440  (*_block)(frame);
441  rs2::frame f;
442  if (!_queue.poll_for_frame(&f))
443  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
444  return f;
445  }
446 
447  void operator()(frame f) const override
448  {
449  (*_block)(std::move(f));
450  }
451  private:
452  friend class context;
453 
454  std::shared_ptr<processing_block> _block;
455  frame_queue _queue;
456  };
457 
459  {
460  public:
461  temporal_filter() :_queue(1)
462  {
463  rs2_error* e = nullptr;
464  auto pb = std::shared_ptr<rs2_processing_block>(
467  _block = std::make_shared<processing_block>(pb);
468  error::handle(e);
469 
470  // Redirect options API to the processing block
471  options::operator=(pb);
472 
473  _block->start(_queue);
474  }
475 
477  {
478  (*_block)(frame);
479  rs2::frame f;
480  if (!_queue.poll_for_frame(&f))
481  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
482  return f;
483  }
484 
485  void operator()(frame f) const override
486  {
487  (*_block)(std::move(f));
488  }
489  private:
490  friend class context;
491 
492  std::shared_ptr<processing_block> _block;
493  frame_queue _queue;
494  };
495 
497  {
498  public:
499  spatial_filter() :_queue(1)
500  {
501  rs2_error* e = nullptr;
502  auto pb = std::shared_ptr<rs2_processing_block>(
505  _block = std::make_shared<processing_block>(pb);
506  error::handle(e);
507 
508  // Redirect options API to the processing block
509  options::operator=(pb);
510 
511  _block->start(_queue);
512  }
513 
515  {
516  (*_block)(frame);
517  rs2::frame f;
518  if (!_queue.poll_for_frame(&f))
519  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
520  return f;
521  }
522 
523  void operator()(frame f) const override
524  {
525  (*_block)(std::move(f));
526  }
527  private:
528  friend class context;
529 
530  std::shared_ptr<processing_block> _block;
531  frame_queue _queue;
532  };
533 
535  {
536  public:
537  disparity_transform(bool transform_to_disparity=true) :_queue(1)
538  {
539  rs2_error* e = nullptr;
540  auto pb = std::shared_ptr<rs2_processing_block>(
541  rs2_create_disparity_transform_block(uint8_t(transform_to_disparity),&e),
543  _block = std::make_shared<processing_block>(pb);
544  error::handle(e);
545 
546  // Redirect options API to the processing block
547  options::operator=(pb);
548 
549  _block->start(_queue);
550  }
551 
553  {
554  (*_block)(frame);
555  rs2::frame f;
556  if (!_queue.poll_for_frame(&f))
557  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
558  return f;
559  }
560 
561  void operator()(frame f) const override
562  {
563  (*_block)(std::move(f));
564  }
565  private:
566  friend class context;
567 
568  std::shared_ptr<processing_block> _block;
569  frame_queue _queue;
570  };
571 
573  {
574  public:
575  hole_filling_filter() :_queue(1)
576  {
577  rs2_error* e = nullptr;
578  auto pb = std::shared_ptr<rs2_processing_block>(
581  _block = std::make_shared<processing_block>(pb);
582  error::handle(e);
583 
584  // Redirect options API to the processing block
585  options::operator=(pb);
586 
587  _block->start(_queue);
588  }
589 
591  {
592  (*_block)(frame);
593  rs2::frame f;
594  if (!_queue.poll_for_frame(&f))
595  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
596  return f;
597  }
598 
599  void operator()(frame f) const override
600  {
601  (*_block)(std::move(f));
602  }
603  private:
604  friend class context;
605 
606  std::shared_ptr<processing_block> _block;
607  frame_queue _queue;
608  };
609 }
610 #endif // LIBREALSENSE_RS2_PROCESSING_HPP
decimation_filter()
Definition: rs_processing.hpp:423
rs2_processing_block * rs2_create_decimation_filter_block(rs2_error **error)
Definition: rs_frame.hpp:21
Definition: rs_frame.hpp:407
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:590
Definition: rs_frame.hpp:202
Definition: rs_processing.hpp:245
frame_queue(unsigned int capacity)
Definition: rs_processing.hpp:142
rs2_frame * rs2_allocate_composite_frame(rs2_source *source, rs2_frame **frames, int count, rs2_error **error)
void operator()(frame f) const
Definition: rs_processing.hpp:360
points calculate(frame depth)
Definition: rs_processing.hpp:224
Definition: rs_processing.hpp:496
Definition: rs_processing.hpp:572
std::enable_if< std::is_base_of< rs2::frame, T >::value, bool >::type poll_for_frame(T *output) const
Definition: rs_processing.hpp:181
void rs2_start_processing(rs2_processing_block *block, rs2_frame_callback *on_frame, rs2_error **error)
Definition: rs_frame.hpp:482
int rs2_poll_for_frame(rs2_frame_queue *queue, rs2_frame **output_frame, rs2_error **error)
size_t capacity() const
Definition: rs_processing.hpp:197
void on_frame(rs2_frame *f, rs2_source *source) override
Definition: rs_processing.hpp:69
rs2_processing_block * rs2_create_hole_filling_filter_block(rs2_error **error)
rs2_processing_block * rs2_create_sync_processing_block(rs2_error **error)
void operator()(frame f) const
Definition: rs_processing.hpp:309
virtual ~process_interface()=default
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:476
rs2_processing_block * rs2_create_processing_block(rs2_frame_processor_callback *proc, rs2_error **error)
bool poll_for_frames(frameset *fs) const
Definition: rs_processing.hpp:298
Definition: rs_frame.hpp:630
void rs2_delete_frame_queue(rs2_frame_queue *queue)
void operator()(frame f) const
Definition: rs_processing.hpp:107
void map_to(frame mapped)
Definition: rs_processing.hpp:233
Definition: rs_context.hpp:11
rs2_frame_queue * rs2_create_frame_queue(int capacity, rs2_error **error)
rs2_frame * rs2_wait_for_frame(rs2_frame_queue *queue, unsigned int timeout_ms, rs2_error **error)
void rs2_process_frame(rs2_processing_block *block, rs2_frame *frame, rs2_error **error)
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:514
Definition: rs_processing.hpp:79
Definition: rs_context.hpp:78
void frame_ready(frame result) const
Definition: rs_processing.hpp:44
processing_block(std::shared_ptr< rs2_processing_block > block)
Definition: rs_processing.hpp:112
frame allocate_video_frame(const stream_profile &profile, const frame &original, int new_bpp=0, int new_width=0, int new_height=0, int new_stride=0, rs2_extension frame_type=RS2_EXTENSION_VIDEO_FRAME) const
Definition: rs_processing.hpp:16
virtual void operator()(frame f) const =0
Definition: rs_processing.hpp:412
void invoke(frame f) const
Definition: rs_processing.hpp:97
void operator()(frame f) const override
Definition: rs_processing.hpp:599
align(rs2_stream align_to)
Definition: rs_processing.hpp:333
Definition: rs_sensor.hpp:100
rs2_frame * rs2_allocate_synthetic_video_frame(rs2_source *source, const rs2_stream_profile *new_stream, rs2_frame *original, int new_bpp, int new_width, int new_height, int new_stride, rs2_extension frame_type, rs2_error **error)
rs2_processing_block * rs2_create_align(rs2_stream align_to, rs2_error **error)
frame_queue()
Definition: rs_processing.hpp:151
Definition: rs_processing.hpp:13
rs2_processing_block * rs2_create_pointcloud(rs2_error **error)
hole_filling_filter()
Definition: rs_processing.hpp:575
void rs2_enqueue_frame(rs2_frame *frame, void *queue)
virtual rs2::frame process(rs2::frame frame)=0
Definition: rs_types.hpp:32
processing_block(S processing_function)
Definition: rs_processing.hpp:118
Definition: rs_processing.hpp:458
video_frame colorize(frame depth) const
Definition: rs_processing.hpp:389
void rs2_synthetic_frame_ready(rs2_source *source, rs2_frame *frame, rs2_error **error)
spatial_filter()
Definition: rs_processing.hpp:499
S & operator>>(S &on_frame)
Definition: rs_processing.hpp:91
pointcloud()
Definition: rs_processing.hpp:207
Definition: rs_sensor.hpp:114
void operator()(frame f) const override
Definition: rs_processing.hpp:485
void rs2_delete_processing_block(rs2_processing_block *block)
void operator()(frame f) const override
Definition: rs_processing.hpp:561
Definition: rs_processing.hpp:204
rs2_processing_block * rs2_create_temporal_filter_block(rs2_error **error)
void enqueue(frame f) const
Definition: rs_processing.hpp:157
void start(S on_frame)
Definition: rs_processing.hpp:83
struct rs2_options rs2_options
Definition: rs_types.h:171
void start(S on_frame)
Definition: rs_processing.hpp:260
void operator()(frame f) const
Definition: rs_processing.hpp:265
void operator()(frame f) const
Definition: rs_processing.hpp:192
syncer(int queue_size=1)
Definition: rs_processing.hpp:276
void operator()(frame f) const override
Definition: rs_processing.hpp:447
static void handle(rs2_error *e)
Definition: rs_types.hpp:121
struct rs2_source rs2_source
Definition: rs_types.h:163
rs2_processing_block * rs2_create_disparity_transform_block(unsigned char transform_to_disparity, rs2_error **error)
rs2_processing_block * rs2_create_colorizer(rs2_error **error)
rs2_stream
Streams are different types of data provided by RealSense devices.
Definition: rs_sensor.h:38
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:552
const rs2_stream_profile * get() const
Definition: rs_frame.hpp:79
Definition: rs_processing.hpp:371
frame wait_for_frame(unsigned int timeout_ms=5000) const
Definition: rs_processing.hpp:167
Definition: rs_types.h:104
void release() override
Definition: rs_processing.hpp:76
Definition: rs_processing.hpp:321
rs2_extension
Specifies advanced interfaces (capabilities) objects may implement.
Definition: rs_types.h:94
asynchronous_syncer()
Definition: rs_processing.hpp:248
rs2_processing_block * rs2_create_spatial_filter_block(rs2_error **error)
frame_processor_callback(T on_frame)
Definition: rs_processing.hpp:67
rs2_source * _source
Definition: rs_processing.hpp:52
options & operator=(const options &other)
Definition: rs_sensor.hpp:209
Definition: rs_processing.hpp:273
video_frame operator()(frame depth) const
Definition: rs_processing.hpp:402
Definition: rs_processing.hpp:134
Definition: rs_processing.hpp:63
frameset wait_for_frames(unsigned int timeout_ms=5000) const
Definition: rs_processing.hpp:288
Definition: rs_processing.hpp:420
temporal_filter()
Definition: rs_processing.hpp:461
struct rs2_error rs2_error
Definition: rs_types.h:149
Definition: rs_option.h:59
void operator()(frame f) const override
Definition: rs_processing.hpp:523
frameset process(frameset frame)
Definition: rs_processing.hpp:351
rs2_frame * get() const
Definition: rs_frame.hpp:367
colorizer()
Definition: rs_processing.hpp:374
struct rs2_frame rs2_frame
Definition: rs_types.h:151
Definition: rs_processing.hpp:534
stream_profile get_profile() const
Definition: rs_frame.hpp:345
frame allocate_composite_frame(std::vector< frame > frames) const
Definition: rs_processing.hpp:31
disparity_transform(bool transform_to_disparity=true)
Definition: rs_processing.hpp:537
int unique_id() const
Definition: rs_frame.hpp:32
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:438