colorizer.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 
8 #include "context.h"
9 #include "environment.h"
10 #include "option.h"
11 #include "colorizer.h"
12 #include "disparity-transform.h"
13 
14 namespace librealsense
15 {
16  static color_map hue{ {
17  { 255, 0, 0 },
18  { 255, 255, 0 },
19  { 0, 255, 0 },
20  { 0, 255, 255 },
21  { 0, 0, 255 },
22  { 255, 0, 255 },
23  { 255, 0, 0 },
24  } };
25 
26  static color_map jet{ {
27  { 0, 0, 255 },
28  { 0, 255, 255 },
29  { 255, 255, 0 },
30  { 255, 0, 0 },
31  { 50, 0, 0 },
32  } };
33 
34  static color_map classic{ {
35  { 30, 77, 203 },
36  { 25, 60, 192 },
37  { 45, 117, 220 },
38  { 204, 108, 191 },
39  { 196, 57, 178 },
40  { 198, 33, 24 },
41  } };
42 
43  static color_map grayscale{ {
44  { 255, 255, 255 },
45  { 0, 0, 0 },
46  } };
47 
49  { 0, 0, 0 },
50  { 255, 255, 255 },
51  } };
52 
53  static color_map biomes{ {
54  { 0, 0, 204 },
55  { 204, 230, 255 },
56  { 255, 255, 153 },
57  { 170, 255, 128 },
58  { 0, 153, 0 },
59  { 230, 242, 255 },
60  } };
61 
62  static color_map cold{ {
63  { 230, 247, 255 },
64  { 0, 92, 230 },
65  { 0, 179, 179 },
66  { 0, 51, 153 },
67  { 0, 5, 15 }
68  } };
69 
70  static color_map warm{ {
71  { 255, 255, 230 },
72  { 255, 204, 0 },
73  { 255, 136, 77 },
74  { 255, 51, 0 },
75  { 128, 0, 0 },
76  { 10, 0, 0 }
77  } };
78 
79  static color_map quantized{ {
80  { 255, 255, 255 },
81  { 0, 0, 0 },
82  }, 6 };
83 
84  static color_map pattern{ {
85  { 255, 255, 255 },
86  { 0, 0, 0 },
87  { 255, 255, 255 },
88  { 0, 0, 0 },
89  { 255, 255, 255 },
90  { 0, 0, 0 },
91  { 255, 255, 255 },
92  { 0, 0, 0 },
93  { 255, 255, 255 },
94  { 0, 0, 0 },
95  { 255, 255, 255 },
96  { 0, 0, 0 },
97  { 255, 255, 255 },
98  { 0, 0, 0 },
99  { 255, 255, 255 },
100  { 0, 0, 0 },
101  { 255, 255, 255 },
102  { 0, 0, 0 },
103  { 255, 255, 255 },
104  { 0, 0, 0 },
105  { 255, 255, 255 },
106  { 0, 0, 0 },
107  { 255, 255, 255 },
108  { 0, 0, 0 },
109  { 255, 255, 255 },
110  { 0, 0, 0 },
111  { 255, 255, 255 },
112  { 0, 0, 0 },
113  { 255, 255, 255 },
114  { 0, 0, 0 },
115  { 255, 255, 255 },
116  { 0, 0, 0 },
117  { 255, 255, 255 },
118  { 0, 0, 0 },
119  { 255, 255, 255 },
120  { 0, 0, 0 },
121  { 255, 255, 255 },
122  { 0, 0, 0 },
123  { 255, 255, 255 },
124  { 0, 0, 0 },
125  { 255, 255, 255 },
126  { 0, 0, 0 },
127  { 255, 255, 255 },
128  { 0, 0, 0 },
129  { 255, 255, 255 },
130  { 0, 0, 0 },
131  { 255, 255, 255 },
132  { 0, 0, 0 },
133  { 255, 255, 255 },
134  { 0, 0, 0 },
135  } };
136 
138  : colorizer("Depth Visualization")
139  {}
140 
143  _min(0.f), _max(6.f), _equalize(true),
145  {
146  _histogram = std::vector<int>(MAX_DEPTH, 0);
147  _hist_data = _histogram.data();
150 
152 
153  auto min_opt = std::make_shared<ptr_option<float>>(0.f, 16.f, 0.1f, 0.f, &_min, "Min range in meters");
154 
155  auto max_opt = std::make_shared<ptr_option<float>>(0.f, 16.f, 0.1f, 6.f, &_max, "Max range in meters");
156 
158  std::make_shared<max_distance_option>(
159  max_opt,
160  min_opt));
161 
163  std::make_shared<min_distance_option>(
164  min_opt,
165  max_opt));
166 
167  auto color_map = std::make_shared<ptr_option<int>>(0, (int)_maps.size() - 1, 1, 0, &_map_index, "Color map");
168  color_map->set_description(0.f, "Jet");
169  color_map->set_description(1.f, "Classic");
170  color_map->set_description(2.f, "White to Black");
171  color_map->set_description(3.f, "Black to White");
172  color_map->set_description(4.f, "Bio");
173  color_map->set_description(5.f, "Cold");
174  color_map->set_description(6.f, "Warm");
175  color_map->set_description(7.f, "Quantized");
176  color_map->set_description(8.f, "Pattern");
177  color_map->set_description(9.f, "Hue");
179 
180  auto preset_opt = std::make_shared<ptr_option<int>>(0, 3, 1, 0, &_preset, "Preset depth colorization");
181  preset_opt->set_description(0.f, "Dynamic");
182  preset_opt->set_description(1.f, "Fixed");
183  preset_opt->set_description(2.f, "Near");
184  preset_opt->set_description(3.f, "Far");
185 
186  preset_opt->on_set([this](float val)
187  {
188  if (fabs(val - 0.f) < 1e-6)
189  {
190  // Dynamic
191  _equalize = true;
192  _map_index = 0;
193  }
194  if (fabs(val - 1.f) < 1e-6)
195  {
196  // Fixed
197  _equalize = false;
198  _map_index = 0;
199  _min = 0.f;
200  _max = 6.f;
201  }
202  if (fabs(val - 2.f) < 1e-6)
203  {
204  // Near
205  _equalize = false;
206  _map_index = 1;
207  _min = 0.3f;
208  _max = 1.5f;
209  }
210  if (fabs(val - 3.f) < 1e-6)
211  {
212  // Far
213  _equalize = false;
214  _map_index = 0;
215  _min = 1.f;
216  _max = 16.f;
217  }
218  });
220 
221  auto hist_opt = std::make_shared<ptr_option<bool>>(false, true, true, true, &_equalize, "Perform histogram equalization");
223  }
224 
226  {
227  if (!frame || frame.is<rs2::frameset>())
228  return false;
229 
230  if (frame.get_profile().stream_type() != RS2_STREAM_DEPTH)
231  return false;
232 
233  return true;
234  }
235 
237  {
238  if (f.get_profile().get() != _source_stream_profile.get())
239  {
242 
243  auto snr = ( (frame_interface *)f.get() )->get_sensor().get();
244  auto depth_sensor = As< librealsense::depth_sensor >( snr );
245  if( depth_sensor )
247  else
248  {
249  // For playback sensors
250  auto extendable = As< librealsense::extendable_interface >( snr );
251  if( extendable
253  (void **)( &depth_sensor ) ) )
254  {
256  }
257  else
258  {
259  LOG_ERROR( "Failed to query depth units from sensor" );
260  throw std::runtime_error( "failed to query depth units from sensor" );
261  }
262  }
264  _d2d_convert_factor = info.d2d_convert_factor;
265  }
266 
268  {
269  auto depth_format = depth.get_profile().format();
270  const auto w = depth.get_width(), h = depth.get_height();
271  auto rgb_data = reinterpret_cast<uint8_t*>(const_cast<void *>(rgb.get_data()));
272  auto coloring_function = [&, this](float data) {
273  auto hist_data = _hist_data[(int)data];
274  auto pixels = (float)_hist_data[MAX_DEPTH - 1];
275  return (hist_data / pixels);
276  };
277 
279  {
280  auto depth_data = reinterpret_cast<const float*>(depth.get_data());
281  update_histogram(_hist_data, depth_data, w, h);
282  make_rgb_data<float>(depth_data, rgb_data, w, h, coloring_function);
283  }
284  else if (depth_format == RS2_FORMAT_Z16)
285  {
286  auto depth_data = reinterpret_cast<const uint16_t*>(depth.get_data());
287  update_histogram(_hist_data, depth_data, w, h);
288  make_rgb_data<uint16_t>(depth_data, rgb_data, w, h, coloring_function);
289  }
290  };
291 
293  {
294  auto depth_format = depth.get_profile().format();
295  const auto w = depth.get_width(), h = depth.get_height();
296  auto rgb_data = reinterpret_cast<uint8_t*>(const_cast<void *>(rgb.get_data()));
297 
299  {
300  auto depth_data = reinterpret_cast<const float*>(depth.get_data());
301  // convert from depth min max to disparity min max
302  // note: max min value is inverted in disparity domain
303  auto __min = _min;
304  if (__min < 1e-6f) { __min = 1e-6f; } // Min value set to prevent zero division. only when _min is zero.
305  auto max = (_d2d_convert_factor / (__min)) * _depth_units + .5f;
306  auto min = (_d2d_convert_factor / (_max)) * _depth_units + .5f;
307  auto coloring_function = [&, this](float data) {
308  return (data - min) / (max - min);
309  };
310  make_rgb_data<float>(depth_data, rgb_data, w, h, coloring_function);
311  }
312  else if (depth_format == RS2_FORMAT_Z16)
313  {
314  auto depth_data = reinterpret_cast<const uint16_t*>(depth.get_data());
315  auto min = _min;
316  auto max = _max;
317  auto coloring_function = [&, this](float data) {
318  if (min >= max) return 0.f;
319  return (data * _depth_units - min) / (max - min);
320  };
321  make_rgb_data<uint16_t>(depth_data, rgb_data, w, h, coloring_function);
322  }
323  };
324 
325  rs2::frame ret;
326 
327  auto vf = f.as<rs2::video_frame>();
328  ret = source.allocate_video_frame(_target_stream_profile, f, 3, vf.get_width(), vf.get_height(), vf.get_width() * 3, RS2_EXTENSION_VIDEO_FRAME);
329 
330  if (_equalize)
331  make_equalized_histogram(f, ret);
332  else
333  make_value_cropped_frame(f, ret);
334 
335  return ret;
336  }
337 }
static color_map hue
Definition: colorizer.cpp:16
static color_map cold
Definition: colorizer.cpp:62
rs2::stream_profile _source_stream_profile
Definition: colorizer.h:167
rs2_frame * get() const
Definition: rs_frame.hpp:590
GLuint const GLchar * name
static const int MAX_DEPTH
Definition: colorizer.h:117
static color_map pattern
Definition: colorizer.cpp:84
bool should_process(const rs2::frame &frame) override
Definition: colorizer.cpp:225
static color_map quantized
Definition: colorizer.cpp:79
stream_profile get_profile() const
Definition: rs_frame.hpp:557
static color_map grayscale
Definition: colorizer.cpp:43
static color_map inv_grayscale
Definition: colorizer.cpp:48
GLint GLint GLsizei GLsizei GLsizei depth
const void * get_data() const
Definition: rs_frame.hpp:545
unsigned short uint16_t
Definition: stdint.h:79
static color_map classic
Definition: colorizer.cpp:34
rs2::frame process_frame(const rs2::frame_source &source, const rs2::frame &f) override
Definition: colorizer.cpp:236
GLdouble GLdouble GLdouble w
static color_map warm
Definition: colorizer.cpp:70
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:1960
unsigned char uint8_t
Definition: stdint.h:78
e
Definition: rmse.py:177
void register_option(rs2_option id, std::shared_ptr< option > option)
Definition: options.h:86
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
static info update_info_from_frame(const rs2::frame &f)
def info(name, value, persistent=False)
Definition: test.py:301
virtual float get_depth_scale() const =0
GLdouble f
bool is() const
Definition: rs_frame.hpp:570
void make_equalized_histogram(depth_pixel *dst, const rs2::video_frame &depth, const color_map &cm)
std::vector< int > _histogram
Definition: colorizer.h:162
std::vector< color_map * > _maps
Definition: colorizer.h:159
rs2::stream_profile _target_stream_profile
Definition: colorizer.h:166
#define LOG_ERROR(...)
Definition: src/types.h:242
int stream_index() const
Definition: rs_frame.hpp:34
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
rs2_format format() const
Definition: rs_frame.hpp:44
int get_height() const
Definition: rs_frame.hpp:671
int min(int a, int b)
Definition: lz4s.c:73
const rs2_stream_profile * get() const
Definition: rs_frame.hpp:137
GLsizei GLsizei GLchar * source
static color_map jet
Definition: colorizer.cpp:26
static color_map biomes
Definition: colorizer.cpp:53
static void update_histogram(int *hist, const T *depth_data, int w, int h)
Definition: colorizer.h:104
GLushort pattern
GLboolean * data
rs2_stream stream_type() const
Definition: rs_frame.hpp:39
void make_value_cropped_frame(depth_pixel *dst, const rs2::video_frame &depth, const color_map &cm, float depth_min, float depth_max, float depth_units)
stream_profile clone(rs2_stream type, int index, rs2_format format) const
Definition: rs_frame.hpp:63
int get_width() const
Definition: rs_frame.hpp:659
Definition: parser.hpp:150
T as() const
Definition: rs_frame.hpp:580


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