valid-results.cpp
Go to the documentation of this file.
1 
4 #include "optimizer.h"
5 #include "cost.h"
6 #include "utils.h"
7 #include "debug.h"
8 
10 
11 
12 // Return the average pixel movement from the calibration
13 double optimizer::calc_correction_in_pixels( calib const & from_calibration, calib const & to_calibration) const
14 {
15  //% [uvMap,~,~] = OnlineCalibration.aux.projectVToRGB(frame.vertices,params.rgbPmat,params.Krgb,params.rgbDistort);
16  //% [uvMapNew,~,~] = OnlineCalibration.aux.projectVToRGB(frame.vertices,newParams.rgbPmat,newParams.Krgb,newParams.rgbDistort);
17  auto old_uvmap = get_texture_map( _z.orig_vertices, from_calibration, from_calibration.calc_p_mat());
18  auto new_uvmap = get_texture_map( _z.vertices, to_calibration, to_calibration.calc_p_mat());
19 
20  return calc_correction_in_pixels( old_uvmap, new_uvmap );
21 }
22 
23 
24 double optimizer::calc_correction_in_pixels( uvmap_t const & old_uvmap, uvmap_t const & new_uvmap ) const
25 {
26  // uvmap is Nx[x,y]
27 
28  if( old_uvmap.size() != new_uvmap.size() )
29  throw std::runtime_error( to_string()
30  << "did not expect different uvmap sizes (" << old_uvmap.size()
31  << " vs " << new_uvmap.size() << ")" );
32 
33  //% xyMovement = mean(sqrt(sum((uvMap-uvMapNew).^2,2)));
34  // note: "the mean of a vector containing NaN values is also NaN"
35  // note: .^ = element-wise power
36  // note: "if A is a matrix, then sum(A,2) is a column vector containing the sum of each row"
37  // -> so average of sqrt( dx^2 + dy^2 )
38 
39  size_t const n_pixels = old_uvmap.size();
40  if( !n_pixels )
41  throw std::runtime_error( "no pixels found in uvmap" );
42  double sum = 0;
43  for( auto i = 0; i < n_pixels; i++ )
44  {
45  double2 const & o = old_uvmap[i];
46  double2 const & n = new_uvmap[i];
47  double dx = o.x - n.x, dy = o.y - n.y;
48  double movement = sqrt( dx * dx + dy * dy );
49  sum += movement;
50  }
51  return sum / n_pixels;
52 }
53 
54 // Movement of pixels should clipped by a certain number of pixels
55 // This function actually changes the calibration if it exceeds this number of pixels!
56 void optimizer::clip_pixel_movement( size_t iteration_number )
57 {
58  double xy_movement = calc_correction_in_pixels(_final_calibration);
59 
60  // Clip any (average) movement of pixels if it's too big
61  AC_LOG( INFO, " average pixel movement= " << xy_movement );
62 
63  size_t n_max_movements = sizeof( _params.max_xy_movement_per_calibration ) / sizeof( _params.max_xy_movement_per_calibration[0] );
64  double const max_movement = _params.max_xy_movement_per_calibration[std::min( n_max_movements - 1, iteration_number )];
65 
66  if( xy_movement > max_movement )
67  {
68  AC_LOG( WARNING, "Pixel movement too big: clipping at limit for iteration (" << iteration_number << ")= " << max_movement );
69 
70  //% mulFactor = maxMovementInThisIteration/xyMovement;
71  double const mul_factor = max_movement / xy_movement;
72 
73  //% if ~strcmp( params.derivVar, 'P' )
74  // -> assuming params.derivVar == 'KrgbRT'!!
75  //% optParams = { 'xAlpha'; 'yBeta'; 'zGamma'; 'Trgb'; 'Kdepth'; 'Krgb' };
76  // -> note we don't do Kdepth at this time!
77  //% for fn = 1:numel( optParams )
78  //% diff = newParams.(optParams{ fn }) - params.(optParams{ fn });
79  //% newParams.(optParams{ fn }) = params.(optParams{ fn }) + diff * mulFactor;
80  //% end
81  calib const & old_calib = _original_calibration;
82  calib & new_calib = _final_calibration;
83  new_calib = old_calib + (new_calib - old_calib) * mul_factor;
84 
85  }
86 }
87 
88 std::vector< double > optimizer::cost_per_section_diff(calib const & old_calib, calib const & new_calib)
89 {
90  // We require here that the section_map is initialized and ready
91  if (_z.section_map.size() != _z.weights.size())
92  throw std::runtime_error("section_map has not been initialized");
93 
94  auto uvmap_old = get_texture_map(_z.orig_vertices, old_calib, old_calib.calc_p_mat());
95  auto uvmap_new = get_texture_map(_z.vertices, new_calib, new_calib.calc_p_mat());
96 
97  size_t const n_sections_x = _params.num_of_sections_for_edge_distribution_x;
98  size_t const n_sections_y = _params.num_of_sections_for_edge_distribution_y;
99  size_t const n_sections = n_sections_x * n_sections_y;
100 
101  std::vector< double > cost_per_section_diff(n_sections, 0.);
102  std::vector< size_t > N_per_section(n_sections, 0);
103 
104  //old
105  auto d_vals_old = biliniar_interp(_yuy.edges_IDT, _yuy.width, _yuy.height, uvmap_old);
106 
107  auto cost_per_vertex_old = calc_cost_per_vertex(d_vals_old, _z, _yuy,
108  [&](size_t i, double d_val, double weight, double vertex_cost) {});
109 
110  //new
111  auto d_vals_new = biliniar_interp(_yuy.edges_IDT, _yuy.width, _yuy.height, uvmap_new);
112 
113  auto cost_per_vertex_new = calc_cost_per_vertex(d_vals_new, _z, _yuy,
114  [&](size_t i, double d_val, double weight, double vertex_cost) {});
115 
116 
117  for (auto i = 0; i < cost_per_vertex_new.size(); i++)
118  {
119  if (d_vals_old[i] != std::numeric_limits<double>::max() && d_vals_new[i] != std::numeric_limits<double>::max())
120  {
122  cost_per_section_diff[section] += (cost_per_vertex_new[i] - cost_per_vertex_old[i]);
123  ++N_per_section[section];
124  }
125  }
126 
127  for (size_t x = 0; x < n_sections; ++x)
128  {
129 
130  double & cost = cost_per_section_diff[x];
131  size_t N = N_per_section[x];
132  if (N)
133  cost /= N;
134  }
135 
136  return cost_per_section_diff;
137 }
138 
139 
141  rs2_dsm_params_double & ac_data_new ) const
142 {
143  if( abs( ac_data_in.h_scale - ac_data_new.h_scale ) > _params.max_global_los_scaling_step )
144  {
145  double const new_h_scale = ac_data_in.h_scale
146  + ( ac_data_new.h_scale - ac_data_in.h_scale )
147  / abs( ac_data_new.h_scale - ac_data_in.h_scale )
149  AC_LOG( DEBUG,
150  " " << AC_D_PREC << "H scale {new}" << ac_data_new.h_scale
151  << " is not within {step}"
153  << " of {old}" << ac_data_in.h_scale << "; clipping to {final}"
154  << new_h_scale << " [CLIP-H]" );
155  ac_data_new.h_scale = new_h_scale;
156  }
157  if( abs( ac_data_in.v_scale - ac_data_new.v_scale ) > _params.max_global_los_scaling_step )
158  {
159  double const new_v_scale = ac_data_in.v_scale
160  + ( ac_data_new.v_scale - ac_data_in.v_scale )
161  / abs( ac_data_new.v_scale - ac_data_in.v_scale )
163  AC_LOG( DEBUG,
164  " " << AC_D_PREC << "V scale {new}" << ac_data_new.v_scale
165  << " is not within {step}"
167  << " of {old}" << ac_data_in.v_scale << "; clipping to {final}"
168  << new_v_scale << " [CLIP-V]" );
169  ac_data_new.v_scale = new_v_scale;
170  }
171 }
172 
174 {
175  svm_features features;
176  std::vector< double > res;
177  auto max_elem = *std::max_element(decision_params.distribution_per_section_depth.begin(), decision_params.distribution_per_section_depth.end());
178  auto min_elem = *std::min_element(decision_params.distribution_per_section_depth.begin(), decision_params.distribution_per_section_depth.end());
179  features.max_over_min_depth = max_elem / (min_elem + 1e-3);
180  res.push_back(features.max_over_min_depth);
181 
182  max_elem = *std::max_element(decision_params.distribution_per_section_rgb.begin(), decision_params.distribution_per_section_rgb.end());
183  min_elem = *std::min_element(decision_params.distribution_per_section_rgb.begin(), decision_params.distribution_per_section_rgb.end());
184  features.max_over_min_rgb = max_elem / (min_elem + 1e-3);
185  res.push_back(features.max_over_min_rgb);
186 
187  std::vector<double>::iterator it = decision_params.edge_weights_per_dir.begin();
188  max_elem = std::max(*it, *(it + 2));
189  min_elem = std::min(*it, *(it + 2));
190  features.max_over_min_perp = max_elem / (min_elem + 1e-3);
191  res.push_back(features.max_over_min_perp);
192 
193  max_elem = std::max(*(it + 1), *(it + 3));
194  min_elem = std::min(*(it + 1), *(it + 3));
195  features.max_over_min_diag = max_elem / (min_elem + 1e-3);
196  res.push_back(features.max_over_min_diag);
197 
198  features.initial_cost = decision_params.initial_cost;
199  features.final_cost = decision_params.new_cost;
200  res.push_back(features.initial_cost);
201  res.push_back(features.final_cost);
202 
203  features.xy_movement = decision_params.xy_movement;
204  if (features.xy_movement > 100) { features.xy_movement = 100; }
205  features.xy_movement_from_origin = decision_params.xy_movement_from_origin;
206  if (features.xy_movement_from_origin > 100) { features.xy_movement_from_origin = 100; }
207  res.push_back(features.xy_movement);
208  res.push_back(features.xy_movement_from_origin);
209 
210  std::vector<double>::iterator iter = decision_params.improvement_per_section.begin();
211  features.positive_improvement_sum = 0;
212  features.negative_improvement_sum = 0;
213  for (int i = 0; i < decision_params.improvement_per_section.size(); i++)
214  {
215  if (*(iter + i) > 0)
216  {
217  features.positive_improvement_sum += *(iter + i);
218  }
219  else
220  {
221  features.negative_improvement_sum += *(iter + i);
222  }
223  }
224  res.push_back(features.positive_improvement_sum);
225  res.push_back(features.negative_improvement_sum);
226 
227  return res;
228 }
230 {
231  auto uvmap = get_texture_map(_z.orig_vertices,
234 
235  _decision_params.initial_cost = calc_cost(z_data, yuy_data, uvmap); //1.560848046875000e+04;
236  //_decision_params.is_valid = 0;
239  _decision_params.improvement_per_section = _z.cost_diff_per_section; // { -4.4229550, 828.93903, 1424.0482, 2536.4409 };
240  _decision_params.min_improvement_per_section = *std::min_element(_z.cost_diff_per_section.begin(), _z.cost_diff_per_section.end());// -4.422955036163330;
241  _decision_params.max_improvement_per_section = *std::max_element(_z.cost_diff_per_section.begin(), _z.cost_diff_per_section.end()); //2.536440917968750e+03;//
242  //_decision_params.is_valid_1 = 1;
243  //_decision_params.moving_pixels = 0;
244  _decision_params.min_max_ratio_depth = z_data.min_max_ratio; // 0.762463343108504;
245  _decision_params.distribution_per_section_depth = z_data.sum_weights_per_section; //{ 980000, 780000, 1023000, 816000 };
246  _decision_params.min_max_ratio_rgb = yuy_data.min_max_ratio; // 0.618130692181835;
247  _decision_params.distribution_per_section_rgb = yuy_data.sum_weights_per_section; //{3025208, 2.899468500000000e+06, 4471484, 2.763961500000000e+06};
248  _decision_params.dir_ratio_1 = z_data.dir_ratio1;// 2.072327044025157;
249  //_decision_params.dir_ratio_2 = z_data.dir_ratio2;
250  _decision_params.edge_weights_per_dir = z_data.sum_weights_per_direction;// { 636000, 898000, 1318000, 747000 };
252  _decision_params.new_cost = calc_cost(z_data, yuy_data, new_uvmap);// 1.677282421875000e+04;
253 
254 }
255 bool svm_rbf_predictor(std::vector< double >& features, svm_model_gaussian& svm_model)
256 {
257  bool res = true;
258  std::vector< double > x_norm;
259  // Applying the model
260  for (auto i = 0; i < features.size(); i++)
261  {
262  x_norm.push_back((*(features.begin() + i) - *(svm_model.mu.begin() + i)) / (*(svm_model.sigma.begin() + i)));
263  }
264 
265  // Extracting model parameters
266  auto mu = svm_model.mu;
267  auto sigma = svm_model.sigma;
268  auto x_sv = svm_model.support_vectors;
269  auto y_sv = svm_model.support_vectors_labels;
270  auto alpha = svm_model.alpha;
271  auto bias = svm_model.bias;
272  auto gamma = 1 / (svm_model.kernel_param_scale * svm_model.kernel_param_scale);
273  int n_samples = 1;// size(featuresMat, 1);
274  //labels = zeros(nSamples, 1);
275  /* innerProduct = exp(-gamma * sum((xNorm(iSample, :) - xSV). ^ 2, 2));
276  score = sum(alpha.*ySV.*innerProduct, 1) + bias;
277  labels(iSample) = score > 0; % dealing with the theoretical possibility of score = 0*/
278  std::vector< double > inner_product;
279  double score = 0;
280 
281  for (auto i = 0; i < y_sv.size(); i++)
282  {
283  double sum_raw = 0;
284  for (auto k = 0; k < x_norm.size(); k++)
285  {
286  double res1 = *(x_norm.begin() + k) - *(x_sv[k].begin() + i);
287  sum_raw += res1 * res1;
288  }
289  double final_sum = exp(-gamma * sum_raw);
290  inner_product.push_back(final_sum);
291  score += *(alpha.begin() + i) * *(y_sv.begin() + i) * final_sum;
292  //score = sum(alpha .* ySV .* innerProduct, 1) + bias;
293  }
294  score += bias;
295 
296  if (score < 0)
297  {
298  res = false;
299  }
300  return res;
301 }
303 {
304  bool is_valid = true;
305 
308 
309  double res = 0;
310  switch (model)
311  {
312  case linear:
313  for (auto i = 0; i < _svm_model_linear.mu.size(); i++)
314  {
315  // isValid = (featuresMat-SVMModel.Mu)./SVMModel.Sigma*SVMModel.Beta+SVMModel.Bias > 0;
316  auto res1 = (*(_extracted_features.begin() + i) - *(_svm_model_linear.mu.begin() + i)) / (*(_svm_model_linear.sigma.begin() + i));// **(_svm_model_linear.beta.begin() + i) + _svm_model_linear.bias);
317  res += res1 * *(_svm_model_linear.beta.begin() + i);
318  }
319  res += _svm_model_linear.bias;
320  if (res < 0)
321  {
322  AC_LOG( INFO, "Calibration invalid according to SVM linear model" );
323  is_valid = false;
324  }
325  break;
326 
327  case gaussian:
329  break;
330 
331  default:
332  AC_LOG(DEBUG, "ERROR : Unknown SVM kernel " << model);
333  break;
334  }
335 
336  return is_valid;
337 }
338 
339 
341 {
343  {
347  }
348 
349 
350  // Clip any (average) movement of pixels if it's too big
352 
353  // Based on (possibly new, clipped) calibration values, see if we've strayed too
354  // far away from the camera's original factory calibration -- which we may not have
356  {
357  double xy_movement = calc_correction_in_pixels(_final_calibration);
358  AC_LOG( DEBUG, " average pixel movement from factory calibration= " << xy_movement );
359  if( xy_movement > _params.max_xy_movement_from_origin )
360  {
361  AC_LOG( ERROR, "Calibration has moved too far from the original factory calibration (" << xy_movement << " pixels)" );
362  return false;
363  }
364  }
365  else
366  {
367  AC_LOG( DEBUG, " no factory calibration available; skipping distance check" );
368  }
369 
370  /* %% Check and see that the score didn't increased by a lot in one image section and decreased in the others
371  % [c1, costVecOld] = OnlineCalibration.aux.calculateCost( frame.vertices, frame.weights, frame.rgbIDT, params );
372  % [c2, costVecNew] = OnlineCalibration.aux.calculateCost( frame.vertices, frame.weights, frame.rgbIDT, newParams );
373  % scoreDiffPerVertex = costVecNew - costVecOld;
374  % for i = 0:(params.numSectionsH*params.numSectionsV) - 1
375  % scoreDiffPersection( i + 1 ) = nanmean( scoreDiffPerVertex( frame.sectionMapDepth == i ) );
376  % end*/
379  //% validOutputStruct.minImprovementPerSection = min( scoreDiffPersection );
380  //% validOutputStruct.maxImprovementPerSection = max( scoreDiffPersection );
381  double min_cost_diff
382  = *std::min_element( _z.cost_diff_per_section.begin(), _z.cost_diff_per_section.end() );
383  double max_cost_diff
384  = *std::max_element( _z.cost_diff_per_section.begin(), _z.cost_diff_per_section.end() );
385  AC_LOG( DEBUG, " min cost diff= " << min_cost_diff << " max= " << max_cost_diff );
386 
387  bool res_svm = valid_by_svm( linear ); //(gaussian);
388  if( ! res_svm )
389  return false;
390 
391 #if 0
392  try
393  {
395  }
396  catch( invalid_value_exception const & e )
397  {
398  AC_LOG( ERROR, "Result DSM parameters are invalid: " << e.what() );
399  return false;
400  }
401 #endif
402 
403  return true;
404 }
405 
406 
408  rs2_dsm_params const & dsm_params )
409 {
410  /* Considerable values for DSM correction:
411  - h/vFactor: 0.98-1.02, representing up to 2% change in FOV.
412  - h/vOffset:
413  - Under AOT model: (-2)-2, representing up to 2deg FOV tilt
414  - Under TOA model: (-125)-125, representing up to approximately
415  2deg FOV tilt
416  These values are extreme. For more reasonable values take 0.99-1.01
417  for h/vFactor and divide the suggested h/vOffset range by 10.
418 
419  Update ww30: +/-1.5% limiter both H/V [0.985..1.015] until AC3.
420  Update ww33: vFactor for all 60 cocktail 1500h units is in the range
421  of 1.000-1.015; changing to [0.995-1.015]
422  */
424 
425  if( dsm_params.model != RS2_DSM_CORRECTION_AOT )
426  error += to_string() << " {mode}" << +dsm_params.model << " must be AOT";
427 
428  if( dsm_params.h_scale < 0.985 || dsm_params.h_scale > 1.015 )
429  error += to_string() << " {H-scale}" << dsm_params.h_scale << " exceeds 1.5% change";
430  if( dsm_params.v_scale < 0.995 || dsm_params.v_scale > 1.015 )
431  error += to_string() << " {V-scale}" << dsm_params.v_scale << " exceeds [-0.5%-1.5%]";
432 
433  if( dsm_params.h_offset < -2. || dsm_params.h_offset > 2. )
434  error += to_string() << " {H-offset}" << dsm_params.h_offset << " is limited to 2 degrees";
435  if( dsm_params.v_offset < -2. || dsm_params.v_offset > 2. )
436  error += to_string() << " {V-offset}" << dsm_params.v_offset << " is limited to 2 degrees";
437 
438  if( ! error.empty() )
439  throw invalid_value_exception( "invalid DSM:" + error + " [LIMIT]" );
440 }
441 
std::vector< double2 > uvmap_t
Definition: uvmap.h:22
float v_offset
Definition: rs_types.h:83
Video DSM (Digital Sync Module) parameters for calibration (same layout as in FW ac_depth_params) Thi...
Definition: rs_types.h:74
float v_scale
Definition: rs_types.h:81
float h_scale
Definition: rs_types.h:80
std::vector< double > calc_cost_per_vertex(std::vector< double > const &d_vals, z_frame_data const &z_data, yuy2_frame_data const &yuy_data, std::function< void(size_t i, double d_val, double weight, double vertex_cost) > fn)
Definition: cost.cpp:12
GLsizei const GLchar *const * string
unsigned char model
Definition: rs_types.h:78
GLuint GLuint GLfloat weight
Definition: glext.h:10534
GLdouble n
Definition: glext.h:1966
e
Definition: rmse.py:177
bool is_valid(const plane_3d &p)
Definition: rendering.h:243
std::vector< double > extract_features(decision_params &decision_params)
void clip_ac_scaling(rs2_dsm_params_double const &ac_data_orig, rs2_dsm_params_double &ac_data_new) const
not_this_one begin(...)
GLfloat GLfloat GLfloat alpha
GLfloat bias
Definition: glext.h:7937
GLdouble x
void collect_decision_params(z_frame_data &z_data, yuy2_frame_data &yuy_data)
bool svm_rbf_predictor(std::vector< double > &features, svm_model_gaussian &svm_model)
std::vector< double > biliniar_interp(std::vector< double > const &vals, size_t width, size_t height, uvmap_t const &uv)
Definition: uvmap.cpp:76
#define AC_LOG(TYPE, MSG)
float h_offset
Definition: rs_types.h:82
void validate_dsm_params(struct rs2_dsm_params const &dsm_params)
double calc_correction_in_pixels(std::vector< double2 > const &old_uvmap, std::vector< double2 > const &new_uvmap) const
unsigned char byte
Definition: src/types.h:52
static auto it
const char * what() const noexceptoverride
Definition: src/types.h:284
uvmap_t get_texture_map(std::vector< double3 > const &points, const calib &cal, const p_matrix &p_mat)
Definition: uvmap.cpp:52
int min(int a, int b)
Definition: lz4s.c:73
double calc_cost(const z_frame_data &z_data, const yuy2_frame_data &yuy_data, const std::vector< double2 > &uv, std::vector< double > *p_interpolated_edges)
Definition: cost.cpp:75
int i
GLuint res
Definition: glext.h:8856
#define INFO(msg)
Definition: catch.hpp:17429
std::vector< double > cost_per_section_diff(calib const &old_calib, calib const &new_calib)
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:14