Intel® RealSense™ Cross Platform API
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 {
18  {
19  public:
33  const frame& original,
34  int new_bpp = 0,
35  int new_width = 0,
36  int new_height = 0,
37  int new_stride = 0,
38  rs2_extension frame_type = RS2_EXTENSION_VIDEO_FRAME) const
39  {
40  rs2_error* e = nullptr;
41  auto result = rs2_allocate_synthetic_video_frame(_source, profile.get(),
42  original.get(), new_bpp, new_width, new_height, new_stride, frame_type, &e);
43  error::handle(e);
44  return result;
45  }
52  frame allocate_composite_frame(std::vector<frame> frames) const
53  {
54  rs2_error* e = nullptr;
55 
56  std::vector<rs2_frame*> refs(frames.size(), (rs2_frame*)nullptr);
57  for (size_t i = 0; i < frames.size(); i++)
58  std::swap(refs[i], frames[i].frame_ref);
59 
60  auto result = rs2_allocate_composite_frame(_source, refs.data(), (int)refs.size(), &e);
61  error::handle(e);
62  return result;
63  }
69  void frame_ready(frame result) const
70  {
71  rs2_error* e = nullptr;
72  rs2_synthetic_frame_ready(_source, result.get(), &e);
73  error::handle(e);
74  result.frame_ref = nullptr;
75  }
76 
78  private:
79  template<class T>
81 
82  frame_source(rs2_source* source) : _source(source) {}
83  frame_source(const frame_source&) = delete;
84 
85  };
86 
87  template<class T>
89  {
90  T on_frame_function;
91  public:
92  explicit frame_processor_callback(T on_frame) : on_frame_function(on_frame) {}
93 
94  void on_frame(rs2_frame* f, rs2_source * source) override
95  {
96  frame_source src(source);
97  frame frm(f);
98  on_frame_function(std::move(frm), src);
99  }
100 
101  void release() override { delete this; }
102  };
103 
107  class processing_block : public options
108  {
109  public:
115  template<class S>
116  void start(S on_frame)
117  {
118  rs2_error* e = nullptr;
119  rs2_start_processing(_block.get(), new frame_callback<S>(on_frame), &e);
120  error::handle(e);
121  }
128  template<class S>
129  S& operator>>(S& on_frame)
130  {
131  start(on_frame);
132  return on_frame;
133  }
139  void invoke(frame f) const
140  {
141  rs2_frame* ptr = nullptr;
142  std::swap(f.frame_ref, ptr);
143 
144  rs2_error* e = nullptr;
145  rs2_process_frame(_block.get(), ptr, &e);
146  error::handle(e);
147  }
151  void operator()(frame f) const
152  {
153  invoke(std::move(f));
154  }
160  processing_block(std::shared_ptr<rs2_processing_block> block)
161  : options((rs2_options*)block.get()),_block(block)
162  {
163  }
164 
170  template<class S>
171  processing_block(S processing_function)
172  {
173  rs2_error* e = nullptr;
174  _block = std::shared_ptr<rs2_processing_block>(
175  rs2_create_processing_block(new frame_processor_callback<S>(processing_function),&e),
177  options::operator=(_block);
178  error::handle(e);
179  }
180 
181  operator rs2_options*() const { return (rs2_options*)_block.get(); }
182 
183  private:
184  std::shared_ptr<rs2_processing_block> _block;
185  };
186 
188  {
189  public:
195  explicit frame_queue(unsigned int capacity): _capacity(capacity)
196  {
197  rs2_error* e = nullptr;
198  _queue = std::shared_ptr<rs2_frame_queue>(
201  error::handle(e);
202  }
203 
205 
210  void enqueue(frame f) const
211  {
212  rs2_enqueue_frame(f.frame_ref, _queue.get()); // noexcept
213  f.frame_ref = nullptr; // frame has been essentially moved from
214  }
215 
220  frame wait_for_frame(unsigned int timeout_ms = 5000) const
221  {
222  rs2_error* e = nullptr;
223  auto frame_ref = rs2_wait_for_frame(_queue.get(), timeout_ms, &e);
224  error::handle(e);
225  return{ frame_ref };
226  }
227 
233  template<typename T>
234  typename std::enable_if<std::is_base_of<rs2::frame, T>::value, bool>::type poll_for_frame(T* output) const
235  {
236  rs2_error* e = nullptr;
237  rs2_frame* frame_ref = nullptr;
238  auto res = rs2_poll_for_frame(_queue.get(), &frame_ref, &e);
239  error::handle(e);
240  frame f{ frame_ref };
241  if (res) *output = f;
242  return res > 0;
243  }
244 
245  template<typename T>
246  typename std::enable_if<std::is_base_of<rs2::frame, T>::value, bool>::type try_wait_for_frame(T* output, unsigned int timeout_ms = 5000) const
247  {
248  rs2_error* e = nullptr;
249  rs2_frame* frame_ref = nullptr;
250  auto res = rs2_try_wait_for_frame(_queue.get(), timeout_ms, &frame_ref, &e);
251  error::handle(e);
252  frame f{ frame_ref };
253  if (res) *output = f;
254  return res > 0;
255  }
259  void operator()(frame f) const
260  {
261  enqueue(std::move(f));
262  }
267  size_t capacity() const { return _capacity; }
268 
269  private:
270  std::shared_ptr<rs2_frame_queue> _queue;
271  size_t _capacity;
272  };
273 
277  class pointcloud : public options
278  {
279  public:
283  pointcloud() : _queue(1)
284  {
285  rs2_error* e = nullptr;
286 
287  auto pb = std::shared_ptr<rs2_processing_block>(
290  _block = std::make_shared<processing_block>(pb);
291 
292  error::handle(e);
293 
294  // Redirect options API to the processing block
295  options::operator=(pb);
296 
297  _block->start(_queue);
298  }
306  {
307  _block->invoke(std::move(depth));
308  rs2::frame f;
309  if (!_queue.poll_for_frame(&f))
310  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
311  return points(f);
312  }
318  void map_to(frame mapped)
319  {
320  _block->set_option(RS2_OPTION_TEXTURE_SOURCE, float(mapped.get_profile().unique_id()));
321  _block->invoke(std::move(mapped));
322  }
323  private:
324  friend class context;
325 
326  std::shared_ptr<processing_block> _block;
327  frame_queue _queue;
328  };
329 
331  {
332  public:
337  {
338  rs2_error* e = nullptr;
339  _processing_block = std::make_shared<processing_block>(
340  std::shared_ptr<rs2_processing_block>(
343 
344  error::handle(e);
345  }
346 
351  template<class S>
352  void start(S on_frame)
353  {
354  _processing_block->start(on_frame);
355  }
360  void operator()(frame f) const
361  {
362  _processing_block->operator()(std::move(f));
363  }
364  private:
365  std::shared_ptr<processing_block> _processing_block;
366  };
367 
368  class syncer
369  {
370  public:
374  syncer(int queue_size = 1)
375  :_results(queue_size)
376  {
377  _sync.start(_results);
378 
379  }
380 
386  frameset wait_for_frames(unsigned int timeout_ms = 5000) const
387  {
388  return frameset(_results.wait_for_frame(timeout_ms));
389  }
390 
396  bool poll_for_frames(frameset* fs) const
397  {
398  frame result;
399  if (_results.poll_for_frame(&result))
400  {
401  *fs = frameset(result);
402  return true;
403  }
404  return false;
405  }
406 
413  bool try_wait_for_frames(frameset* fs, unsigned int timeout_ms = 5000) const
414  {
415  frame result;
416  if (_results.try_wait_for_frame(&result, timeout_ms))
417  {
418  *fs = frameset(result);
419  return true;
420  }
421  return false;
422  }
423 
424  void operator()(frame f) const
425  {
426  _sync(std::move(f));
427  }
428  private:
429  asynchronous_syncer _sync;
430  frame_queue _results;
431  };
432 
436  class align
437  {
438  public:
448  align(rs2_stream align_to) :_queue(1)
449  {
450  rs2_error* e = nullptr;
451  _block = std::make_shared<processing_block>(
452  std::shared_ptr<rs2_processing_block>(
453  rs2_create_align(align_to, &e),
455  error::handle(e);
456 
457  _block->start(_queue);
458  }
459 
467  {
468  (*_block)(frame);
469  rs2::frame f;
470  if (!_queue.poll_for_frame(&f))
471  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
472  return frameset(f);
473  }
480  void operator()(frame f) const
481  {
482  (*_block)(std::move(f));
483  }
484  private:
485  friend class context;
486 
487  std::shared_ptr<processing_block> _block;
488  frame_queue _queue;
489  };
490 
491  class colorizer : public options
492  {
493  public:
498  colorizer() : _queue(1)
499  {
500  rs2_error* e = nullptr;
501  auto pb = std::shared_ptr<rs2_processing_block>(
504  _block = std::make_shared<processing_block>(pb);
505  error::handle(e);
506 
507  // Redirect options API to the processing block
508  options::operator=(pb);
509 
510  _block->start(_queue);
511  }
518  {
519  if(depth)
520  {
521  _block->invoke(std::move(depth));
522  rs2::frame f;
523  if (!_queue.poll_for_frame(&f))
524  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
525  return video_frame(f);
526  }
527  return depth;
528  }
534  video_frame operator()(frame depth) const { return colorize(depth); }
535 
536  private:
537  std::shared_ptr<processing_block> _block;
538  frame_queue _queue;
539  };
540 
544  class process_interface : public options
545  {
546  public:
547  virtual rs2::frame process(rs2::frame frame) = 0;
548  virtual void operator()(frame f) const = 0;
549  virtual ~process_interface() = default;
550  };
551 
553  {
554  public:
559  decimation_filter() :_queue(1)
560  {
561  rs2_error* e = nullptr;
562  auto pb = std::shared_ptr<rs2_processing_block>(
565  _block = std::make_shared<processing_block>(pb);
566  error::handle(e);
567 
568  // Redirect options API to the processing block
569  options::operator=(pb);
570 
571  _block->start(_queue);
572  }
579  {
580  (*_block)(frame);
581  rs2::frame f;
582  if (!_queue.poll_for_frame(&f))
583  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
584  return f;
585  }
590  void operator()(frame f) const override
591  {
592  (*_block)(std::move(f));
593  }
594  private:
595  friend class context;
596 
597  std::shared_ptr<processing_block> _block;
598  frame_queue _queue;
599  };
600 
602  {
603  public:
610  temporal_filter() :_queue(1)
611  {
612  rs2_error* e = nullptr;
613  auto pb = std::shared_ptr<rs2_processing_block>(
616  _block = std::make_shared<processing_block>(pb);
617  error::handle(e);
618 
619  // Redirect options API to the processing block
620  options::operator=(pb);
621 
622  _block->start(_queue);
623  }
630  {
631  (*_block)(frame);
632  rs2::frame f;
633  if (!_queue.poll_for_frame(&f))
634  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
635  return f;
636  }
641  void operator()(frame f) const override
642  {
643  (*_block)(std::move(f));
644  }
645  private:
646  friend class context;
647 
648  std::shared_ptr<processing_block> _block;
649  frame_queue _queue;
650  };
651 
653  {
654  public:
662  spatial_filter() :_queue(1)
663  {
664  rs2_error* e = nullptr;
665  auto pb = std::shared_ptr<rs2_processing_block>(
668  _block = std::make_shared<processing_block>(pb);
669  error::handle(e);
670 
671  // Redirect options API to the processing block
672  options::operator=(pb);
673 
674  _block->start(_queue);
675  }
676 
683  {
684  (*_block)(frame);
685  rs2::frame f;
686  if (!_queue.poll_for_frame(&f))
687  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
688  return f;
689  }
690 
695  void operator()(frame f) const override
696  {
697  (*_block)(std::move(f));
698  }
699  private:
700  friend class context;
701 
702  std::shared_ptr<processing_block> _block;
703  frame_queue _queue;
704  };
705 
707  {
708  public:
713  disparity_transform(bool transform_to_disparity=true) :_queue(1)
714  {
715  rs2_error* e = nullptr;
716  auto pb = std::shared_ptr<rs2_processing_block>(
717  rs2_create_disparity_transform_block(uint8_t(transform_to_disparity),&e),
719  _block = std::make_shared<processing_block>(pb);
720  error::handle(e);
721 
722  // Redirect options API to the processing block
723  options::operator=(pb);
724 
725  _block->start(_queue);
726  }
727 
734  {
735  (*_block)(frame);
736  rs2::frame f;
737  if (!_queue.poll_for_frame(&f))
738  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
739  return f;
740  }
741 
746  void operator()(frame f) const override
747  {
748  (*_block)(std::move(f));
749  }
750  private:
751  friend class context;
752 
753  std::shared_ptr<processing_block> _block;
754  frame_queue _queue;
755  };
756 
758  {
759  public:
764  hole_filling_filter() :_queue(1)
765  {
766  rs2_error* e = nullptr;
767  auto pb = std::shared_ptr<rs2_processing_block>(
770  _block = std::make_shared<processing_block>(pb);
771  error::handle(e);
772 
773  // Redirect options API to the processing block
774  options::operator=(pb);
775 
776  _block->start(_queue);
777  }
784  {
785  (*_block)(frame);
786  rs2::frame f;
787  if (!_queue.poll_for_frame(&f))
788  throw std::runtime_error("Error occured during execution of the processing block! See the log for more info");
789  return f;
790  }
795  void operator()(frame f) const override
796  {
797  (*_block)(std::move(f));
798  }
799  private:
800  friend class context;
801 
802  std::shared_ptr<processing_block> _block;
803  frame_queue _queue;
804  };
805 }
806 #endif // LIBREALSENSE_RS2_PROCESSING_HPP
decimation_filter()
Definition: rs_processing.hpp:559
rs2_processing_block * rs2_create_decimation_filter_block(rs2_error **error)
Definition: rs_frame.hpp:21
Definition: rs_frame.hpp:535
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:783
Definition: rs_frame.hpp:286
Definition: rs_processing.hpp:330
frame_queue(unsigned int capacity)
Definition: rs_processing.hpp:195
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:480
points calculate(frame depth)
Definition: rs_processing.hpp:305
Definition: rs_processing.hpp:652
Definition: rs_processing.hpp:757
std::enable_if< std::is_base_of< rs2::frame, T >::value, bool >::type poll_for_frame(T *output) const
Definition: rs_processing.hpp:234
void rs2_start_processing(rs2_processing_block *block, rs2_frame_callback *on_frame, rs2_error **error)
Definition: rs_frame.hpp:618
int rs2_poll_for_frame(rs2_frame_queue *queue, rs2_frame **output_frame, rs2_error **error)
size_t capacity() const
Definition: rs_processing.hpp:267
void on_frame(rs2_frame *f, rs2_source *source) override
Definition: rs_processing.hpp:94
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:424
virtual ~process_interface()=default
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:629
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:396
Definition: rs_frame.hpp:815
void rs2_delete_frame_queue(rs2_frame_queue *queue)
void operator()(frame f) const
Definition: rs_processing.hpp:151
void map_to(frame mapped)
Definition: rs_processing.hpp:318
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:682
Definition: rs_processing.hpp:107
Definition: rs_context.hpp:104
void frame_ready(frame result) const
Definition: rs_processing.hpp:69
processing_block(std::shared_ptr< rs2_processing_block > block)
Definition: rs_processing.hpp:160
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:32
virtual void operator()(frame f) const =0
Definition: rs_processing.hpp:544
void invoke(frame f) const
Definition: rs_processing.hpp:139
void operator()(frame f) const override
Definition: rs_processing.hpp:795
align(rs2_stream align_to)
Definition: rs_processing.hpp:448
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:204
Definition: rs_processing.hpp:17
rs2_processing_block * rs2_create_pointcloud(rs2_error **error)
hole_filling_filter()
Definition: rs_processing.hpp:764
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:171
Definition: rs_processing.hpp:601
video_frame colorize(frame depth) const
Definition: rs_processing.hpp:517
void rs2_synthetic_frame_ready(rs2_source *source, rs2_frame *frame, rs2_error **error)
spatial_filter()
Definition: rs_processing.hpp:662
S & operator>>(S &on_frame)
Definition: rs_processing.hpp:129
pointcloud()
Definition: rs_processing.hpp:283
Definition: rs_sensor.hpp:114
void operator()(frame f) const override
Definition: rs_processing.hpp:641
void rs2_delete_processing_block(rs2_processing_block *block)
void operator()(frame f) const override
Definition: rs_processing.hpp:746
Definition: rs_processing.hpp:277
rs2_processing_block * rs2_create_temporal_filter_block(rs2_error **error)
void enqueue(frame f) const
Definition: rs_processing.hpp:210
void start(S on_frame)
Definition: rs_processing.hpp:116
struct rs2_options rs2_options
Definition: rs_types.h:171
void start(S on_frame)
Definition: rs_processing.hpp:352
void operator()(frame f) const
Definition: rs_processing.hpp:360
void operator()(frame f) const
Definition: rs_processing.hpp:259
syncer(int queue_size=1)
Definition: rs_processing.hpp:374
void operator()(frame f) const override
Definition: rs_processing.hpp:590
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
bool try_wait_for_frames(frameset *fs, unsigned int timeout_ms=5000) const
Definition: rs_processing.hpp:413
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:733
const rs2_stream_profile * get() const
Definition: rs_frame.hpp:136
Definition: rs_processing.hpp:491
frame wait_for_frame(unsigned int timeout_ms=5000) const
Definition: rs_processing.hpp:220
Definition: rs_types.h:104
void release() override
Definition: rs_processing.hpp:101
Definition: rs_processing.hpp:436
rs2_extension
Specifies advanced interfaces (capabilities) objects may implement.
Definition: rs_types.h:94
asynchronous_syncer()
Definition: rs_processing.hpp:336
rs2_processing_block * rs2_create_spatial_filter_block(rs2_error **error)
frame_processor_callback(T on_frame)
Definition: rs_processing.hpp:92
rs2_source * _source
Definition: rs_processing.hpp:77
options & operator=(const options &other)
Definition: rs_sensor.hpp:209
Definition: rs_processing.hpp:368
video_frame operator()(frame depth) const
Definition: rs_processing.hpp:534
Definition: rs_processing.hpp:187
Definition: rs_processing.hpp:88
frameset wait_for_frames(unsigned int timeout_ms=5000) const
Definition: rs_processing.hpp:386
int rs2_try_wait_for_frame(rs2_frame_queue *queue, unsigned int timeout_ms, rs2_frame **output_frame, rs2_error **error)
Definition: rs_processing.hpp:552
temporal_filter()
Definition: rs_processing.hpp:610
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:695
frameset process(frameset frame)
Definition: rs_processing.hpp:466
rs2_frame * get() const
Definition: rs_frame.hpp:495
std::enable_if< std::is_base_of< rs2::frame, T >::value, bool >::type try_wait_for_frame(T *output, unsigned int timeout_ms=5000) const
Definition: rs_processing.hpp:246
colorizer()
Definition: rs_processing.hpp:498
struct rs2_frame rs2_frame
Definition: rs_types.h:151
Definition: rs_processing.hpp:706
stream_profile get_profile() const
Definition: rs_frame.hpp:462
frame allocate_composite_frame(std::vector< frame > frames) const
Definition: rs_processing.hpp:52
disparity_transform(bool transform_to_disparity=true)
Definition: rs_processing.hpp:713
int unique_id() const
Definition: rs_frame.hpp:53
rs2::frame process(rs2::frame frame) override
Definition: rs_processing.hpp:578