temporal-filter.cpp
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 #include "../include/librealsense2/hpp/rs_sensor.hpp"
5 #include "../include/librealsense2/hpp/rs_processing.hpp"
6 #include "source.h"
7 #include "option.h"
8 #include "environment.h"
9 #include "context.h"
10 #include "proc/synthetic-stream.h"
11 #include "proc/temporal-filter.h"
12 
13 namespace librealsense
14 {
15  const size_t PERSISTENCE_MAP_NUM = 9;
16 
17  // The persistence parameter/holes filling mode
19  const uint8_t persistence_max = PERSISTENCE_MAP_NUM-1;
20  const uint8_t persistence_default = 3; // Credible if two of the last four frames are valid at this pixel
22 
23  //alpha - the weight with default value 0.4, between 1 and 0 -- 1 means 100% weight from the current pixel
24  const float temp_alpha_min = 0.f;
25  const float temp_alpha_max = 1.f;
26  const float temp_alpha_default = 0.4f;
27  const float temp_alpha_step = 0.01f;
28 
29  //delta - the filter threshold for edge classification and preserving with default value of 20 depth increments
31  const uint8_t temp_delta_max = 100;
34 
36  depth_processing_block("Temporal Filter"),
37  _persistence_param(persistence_default),
38  _alpha_param(temp_alpha_default),
39  _one_minus_alpha(1- _alpha_param),
40  _delta_param(temp_delta_default),
41  _width(0), _height(0), _stride(0), _bpp(0),
42  _extension_type(RS2_EXTENSION_DEPTH_FRAME),
43  _current_frm_size_pixels(0)
44  {
47 
48  auto temporal_persistence_control = std::make_shared<ptr_option<uint8_t>>(
53  &_persistence_param, "Persistency mode");
54 
55  temporal_persistence_control->set_description(0, "Disabled");
56  temporal_persistence_control->set_description(1, "Valid in 8/8");
57  temporal_persistence_control->set_description(2, "Valid in 2/last 3");
58  temporal_persistence_control->set_description(3, "Valid in 2/last 4");
59  temporal_persistence_control->set_description(4, "Valid in 2/8");
60  temporal_persistence_control->set_description(5, "Valid in 1/last 2");
61  temporal_persistence_control->set_description(6, "Valid in 1/last 5");
62  temporal_persistence_control->set_description(7, "Valid in 1/8");
63  temporal_persistence_control->set_description(8, "Always on");
64 
65  temporal_persistence_control->on_set([this,temporal_persistence_control](float val)
66  {
67  if (!temporal_persistence_control->is_valid(val))
69  << "Unsupported temporal persistence param "
70  << (int)val << " is out of range.");
71 
72  on_set_persistence_control(static_cast<uint8_t>(val));
73  });
74 
75  register_option(RS2_OPTION_HOLES_FILL, temporal_persistence_control);
76 
77  auto temporal_filter_alpha = std::make_shared<ptr_option<float>>(
82  &_alpha_param, "Alpha factor of Exp. moving average, 1=no filter, 0=infinite filter");
83  temporal_filter_alpha->on_set([this](float val)
84  {
85  on_set_alpha(val);
86  });
87 
88  auto temporal_filter_delta = std::make_shared<ptr_option<uint8_t>>(
93  &_delta_param, "Edge-preserving (gradient) threshold");
94  temporal_filter_delta->on_set([this, temporal_filter_delta](float val)
95  {
96  if (!temporal_filter_delta->is_valid(val))
98  << "Unsupported temporal delta: " << val << " is out of range.");
99 
100  on_set_delta(val);
101  });
102 
103  register_option(RS2_OPTION_FILTER_SMOOTH_ALPHA, temporal_filter_alpha);
104  register_option(RS2_OPTION_FILTER_SMOOTH_DELTA, temporal_filter_delta);
105 
106  on_set_persistence_control(_persistence_param);
107  on_set_delta(_delta_param);
108  on_set_alpha(_alpha_param);
109  }
110 
112  {
114  auto tgt = prepare_target_frame(f, source);
115 
116  // Temporal filter execution
118  temp_jw_smooth<float>(const_cast<void*>(tgt.get_data()), _last_frame.data(), _history.data());
119  else
120  temp_jw_smooth<uint16_t>(const_cast<void*>(tgt.get_data()), _last_frame.data(), _history.data());
121 
122  return tgt;
123  }
124 
125 
127  {
128  std::lock_guard<std::mutex> lock(_mutex);
131  _last_frame.clear();
132  _history.clear();
133  }
134 
136  {
137  std::lock_guard<std::mutex> lock(_mutex);
138  _alpha_param = val;
140  _cur_frame_index = 0;
141  _last_frame.clear();
142  _history.clear();
143  }
144 
146  {
147  std::lock_guard<std::mutex> lock(_mutex);
148  _delta_param = static_cast<uint8_t>(val);
149  _cur_frame_index = 0;
150  _last_frame.clear();
151  _history.clear();
152  }
153 
155  {
156  if (f.get_profile().get() != _source_stream_profile.get())
157  {
160 
161  //TODO - reject any frame other than depth/disparity
163  _bpp = (_extension_type == RS2_EXTENSION_DISPARITY_FRAME) ? sizeof(float) : sizeof(uint16_t);
165  _width = vp.width();
166  _height = vp.height();
167  _stride = _width*_bpp;
169 
170  _last_frame.clear();
172 
173  _history.clear();
174  _history.resize(_current_frm_size_pixels*_bpp);
175 
176  }
177  }
178 
180  {
181  // Allocate and copy the content of the original Depth data to the target
183 
184  memmove(const_cast<void*>(tgt.get_data()), f.get_data(), _current_frm_size_pixels * _bpp);
185  return tgt;
186  }
187 
189  {
190  _persistence_map.fill(0);
191 
192  for (size_t i = 0; i < _persistence_map.size(); i++)
193  {
194  unsigned char last_7 = !!(i & 1); // old
195  unsigned char last_6 = !!(i & 2);
196  unsigned char last_5 = !!(i & 4);
197  unsigned char last_4 = !!(i & 8);
198  unsigned char last_3 = !!(i & 16);
199  unsigned char last_2 = !!(i & 32);
200  unsigned char last_1 = !!(i & 64);
201  unsigned char lastFrame = !!(i & 128); // new
202 
203  if (_persistence_param == 1)
204  {
205  int sum = lastFrame + last_1 + last_2 + last_3 + last_4 + last_5 + last_6 + last_7;
206  if (sum >= 8) // valid in eight of the last eight frames
207  _persistence_map[i] = 1;
208  }
209  else if (_persistence_param == 2) // <--- default choice in current libRS implementation
210  {
211  int sum = lastFrame + last_1 + last_2;
212  if (sum >= 2) // valid in two of the last three frames
213  _persistence_map[i] = 1;
214  }
215  else if (_persistence_param == 3) // <--- default choice recommended
216  {
217  int sum = lastFrame + last_1 + last_2 + last_3;
218  if (sum >= 2) // valid in two of the last four frames
219  _persistence_map[i] = 1;
220  }
221  else if (_persistence_param == 4)
222  {
223  int sum = lastFrame + last_1 + last_2 + last_3 + last_4 + last_5 + last_6 + last_7;
224  if (sum >= 2) // valid in two of the last eight frames
225  _persistence_map[i] = 1;
226  }
227  else if (_persistence_param == 5)
228  {
229  int sum = lastFrame + last_1;
230  if (sum >= 1) // valid in one of the last two frames
231  _persistence_map[i] = 1;
232  }
233  else if (_persistence_param == 6)
234  {
235  int sum = lastFrame + last_1 + last_2 + last_3 + last_4;
236  if (sum >= 1) // valid in one of the last five frames
237  _persistence_map[i] = 1;
238  }
239  else if (_persistence_param == 7) // <--- most filling
240  {
241  int sum = lastFrame + last_1 + last_2 + last_3 + last_4 + last_5 + last_6 + last_7;
242  if (sum >= 1) // valid in one of the last eight frames
243  _persistence_map[i] = 1;
244  }
245  else if (_persistence_param == 8) // <--- all 1's
246  {
247  _persistence_map[i] = 1;
248  }
249  else // all others, including 0, no persistance
250  {
251  }
252  }
253 
254  // Convert to credible enough
255  std::array<uint8_t, PRESISTENCY_LUT_SIZE> credible_threshold;
256  credible_threshold.fill(0);
257 
258  for (auto phase = 0; phase < 8; phase++)
259  {
260  // evaluating last phase
261  //int ephase = (phase + 7) % 8;
262  unsigned char mask = 1 << phase;
263  int i;
264 
265  for (i = 0; i < 256; i++) {
266  unsigned char pos = (unsigned char)((i << (8 - phase)) | (i >> phase));
267  if (_persistence_map[pos])
268  credible_threshold[i] |= mask;
269  }
270  }
271  // Store results
272  _persistence_map = credible_threshold;
273  }
274 }
const float temp_alpha_default
static const textual_icon lock
Definition: model-views.h:218
const uint8_t temp_delta_default
const uint8_t persistence_default
GLint GLuint mask
stream_profile get_profile() const
Definition: rs_frame.hpp:557
rs2::stream_profile _target_stream_profile
void on_set_persistence_control(uint8_t val)
const uint8_t persistence_min
const void * get_data() const
Definition: rs_frame.hpp:545
unsigned short uint16_t
Definition: stdint.h:79
std::array< uint8_t, PRESISTENCY_LUT_SIZE > _persistence_map
const uint8_t temp_delta_step
unsigned char uint8_t
Definition: stdint.h:78
void register_option(rs2_option id, std::shared_ptr< option > option)
Definition: options.h:86
const uint8_t temp_delta_max
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
GLuint GLfloat * val
const uint8_t persistence_max
GLdouble f
bool is() const
Definition: rs_frame.hpp:570
std::vector< uint8_t > _history
rs2::stream_profile _source_stream_profile
std::vector< uint8_t > _last_frame
const uint8_t temp_delta_min
const size_t PERSISTENCE_MAP_NUM
void update_configuration(const rs2::frame &f)
const float temp_alpha_max
rs2_format format() const
Definition: rs_frame.hpp:44
rs2::frame prepare_target_frame(const rs2::frame &f, const rs2::frame_source &source)
const rs2_stream_profile * get() const
Definition: rs_frame.hpp:137
const uint8_t persistence_step
GLsizei GLsizei GLchar * source
float rs2_vector::* pos
const float temp_alpha_step
int i
const float temp_alpha_min
stream_profile clone(rs2_stream type, int index, rs2_format format) const
Definition: rs_frame.hpp:63
rs2::frame process_frame(const rs2::frame_source &source, const rs2::frame &f) override
std::string to_string(T value)


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