24 s <<
"x[" <<
self.h_scale <<
" " <<
self.v_scale <<
"] ";
25 if(
self.h_offset ||
self.v_offset )
26 s <<
"+[" <<
self.h_offset <<
" " <<
self.v_offset;
28 s <<
" rtd " <<
self.rtd_offset;
46 const double & max_scaling_step )
48 , _dsm_regs( cal__regs )
49 , _max_scaling_step( max_scaling_step )
62 switch (ac_data.
model)
93 switch (ac_data.
model)
123 switch (ac_data.
model)
156 const std::vector<uint8_t>& relevant_pixels_image,
181 std::vector<double3> & new_vertices,
183 algo_calibration_registers& new_dsm_regs,
216 auto sc_vertices = new_vertices;
218 for (
auto i = 0;
i < sc_vertices.size();
i++)
220 sc_vertices[
i].x *= -1;
221 sc_vertices[
i].y *= -1;
239 for (
auto i = 0;
i < new_vertices.size();
i++)
241 new_vertices[
i].x = new_vertices[
i].x / new_vertices[
i].z * sc_vertices[
i].z;
242 new_vertices[
i].y = new_vertices[
i].y / new_vertices[
i].z * sc_vertices[
i].z;
243 new_vertices[
i].z = new_vertices[
i].z / new_vertices[
i].z * sc_vertices[
i].z;
245 new_vertices[
i].x *= -1;
246 new_vertices[
i].y *= -1;
250 " new DSM params: " <<
AC_D_PREC << ac_data_cand <<
"; vertices are changed" );
251 new_dsm_regs = dsm_regs_cand;
263 algo_calibration_registers
const &dsm_regs,
273 double coarse_grid[5] = { -1, -0.5, 0, 0.5, 1 };
274 double fine_grid[5] = { -1, -0.5, 0, 0.5, 1 };
276 double coarse_grid_x[5];
277 double coarse_grid_y[5];
279 for (
auto i = 0;
i < 5;
i++)
288 ndgrid_my(coarse_grid_y, coarse_grid_x, grid_y, grid_x);
302 for (
auto i = 0;
i < 5;
i++)
304 fine_grid_x[
i] = fine_grid[
i] + opt_scaling.
x;
305 fine_grid_y[
i] = fine_grid[
i] + opt_scaling.y;
308 ndgrid_my(fine_grid_y, fine_grid_x, grid_y, grid_x);
315 - max_step_with_margin ),
319 - max_step_with_margin ),
328 const algo_calibration_registers& dsm_regs,
335 switch (ac_data_out.
model)
344 ac_data_out.
h_scale = 1 / los_scaling.
x ;
345 ac_data_out.
v_scale = 1 / los_scaling.
y ;
346 ac_data_out.
h_offset = -los_shift.
x / los_scaling.
x;
347 ac_data_out.
v_offset = -los_shift.
y / los_scaling.
y;
350 ac_data_out.
h_scale = 1 / los_scaling.
x;
351 ac_data_out.
v_scale = 1 / los_scaling.
y;
368 algo_calibration_registers
const &dsm_regs,
370 double scaling_grid_y[SIZE_OF_GRID_X],
387 err_l2[
i] = std::sqrt(std::pow(fx_scaling_on_grid[
i] - focal_scaling.
x, 2) + std::pow(fy_scaling_on_grid[
i] - focal_scaling.
y, 2));
394 sg_mat[
i][0] = scaling_grid_x[
i] * scaling_grid_x[
i];
395 sg_mat[
i][1] = scaling_grid_y[
i] * scaling_grid_y[
i];
396 sg_mat[
i][2] = scaling_grid_x[
i] * scaling_grid_y[
i];
397 sg_mat[
i][3] = scaling_grid_x[
i];
398 sg_mat[
i][4] = scaling_grid_y[
i];
402 double sg_mat_tag_x_sg_mat[36] = { 0 };
403 double sg_mat_tag_x_err_l2[6] = { 0 };
405 for (
auto i = 0;
i < 6;
i++)
407 for (
auto j = 0;
j < 6;
j++)
409 for (
auto l = 0; l < 25; l++)
411 sg_mat_tag_x_sg_mat[
i * 6 +
j] += sg_mat[l][
i] * sg_mat[l][
j];
417 for (
auto j = 0;
j < 6;
j++)
419 for (
auto l = 0; l < 25; l++)
421 sg_mat_tag_x_err_l2[
j] += sg_mat[l][
j] * err_l2[l];
426 direct_inv_6x6(sg_mat_tag_x_sg_mat, sg_mat_tag_x_err_l2, quad_coef);
430 double A[4] = { quad_coef[0], quad_coef[2] / 2, quad_coef[2] / 2, quad_coef[1] };
431 double B[2] = { quad_coef[3] , quad_coef[4] };
432 double opt_scaling[2];
435 opt_scaling[0] = -opt_scaling[0] / 2;
436 opt_scaling[1] = -opt_scaling[1] / 2;
459 double min_x, min_y, max_x, max_y;
460 min_x = max_x = scaling_grid_x[0];
461 min_y = max_y = scaling_grid_y[0];
465 if (min_x > scaling_grid_x[
i])
466 min_x = scaling_grid_x[
i];
468 if (min_y > scaling_grid_y[i])
469 min_y = scaling_grid_y[
i];
471 if (max_x < scaling_grid_x[i])
472 max_x = scaling_grid_x[
i];
474 if (max_y < scaling_grid_y[i])
475 max_y = scaling_grid_y[
i];
478 auto is_pos_def = (quad_coef[0] + quad_coef[1]) > 0 && (quad_coef[0] * quad_coef[1] - quad_coef[2] * quad_coef[2] / 4) > 0;
479 auto is_with_in_lims = (opt_scaling[0] > min_x) && (opt_scaling[0] < max_x) && (opt_scaling[1] > min_y) && (opt_scaling[1] < max_y);
481 if (!is_pos_def || !is_with_in_lims)
483 double min_err = err_l2[0];
487 if (min_err > err_l2[
i])
493 opt_scaling[0] = scaling_grid_x[ind_min];
494 opt_scaling[1] = scaling_grid_y[ind_min];
496 return { opt_scaling[0], opt_scaling[1] };
502 algo_calibration_registers
const &dsm_regs,
503 double scaling_grid_x[SIZE_OF_GRID_X],
504 double scaling_grid_y[SIZE_OF_GRID_X]
509 std::vector<double3x3>
res(SIZE_OF_GRID_X, { 0 });
516 for (
auto j = 0;
j < updated_pixels.size();
j++)
523 for (
auto i = 0;
i < updated_vertices.size();
i++)
525 updated_pixels[
i].x = updated_vertices[
i].x*orig_k.fx + updated_vertices[
i].z*orig_k.ppx;
526 updated_pixels[
i].y = updated_vertices[
i].y*orig_k.fy + updated_vertices[
i].z*orig_k.ppy;
527 updated_pixels[
i].z = updated_vertices[
i].z;
530 std::vector<double2>
v1(updated_pixels.size());
531 std::vector<double2>
v2(updated_pixels.size());
532 std::vector<double>
p1(updated_pixels.size());
533 std::vector<double>
p2(updated_pixels.size());
535 for (
auto i = 0;
i <
v1.size();
i++)
546 v1.insert(
v1.end(),
v2.begin(),
v2.end());
547 p1.insert(
p1.end(),
p2.begin(),
p2.end());
549 double vtag_x_v[4] = { 0 };
550 double vtag_x_p[2] = { 0 };
552 for (
auto i = 0;
i <
v1.size();
i++)
554 vtag_x_v[0] +=
v1[
i].x*
v1[
i].x;
555 vtag_x_v[1] +=
v1[
i].x*
v1[
i].y;
556 vtag_x_v[2] +=
v1[
i].y*
v1[
i].x;
557 vtag_x_v[3] +=
v1[
i].y*
v1[
i].y;
559 vtag_x_p[0] +=
v1[
i].x*
p1[
i];
560 vtag_x_p[1] +=
v1[
i].y*
p1[
i];
567 double3x3 mat = { inv[0],0.0,orig_k.ppx ,
568 0.0,inv[1],orig_k.ppy ,
579 algo_calibration_registers
const &dsm_regs,
580 std::vector<double2> los,
584 std::vector<double3> fove_x_indicent_direction(los.size());
585 std::vector<double3> fove_y_indicent_direction(los.size());
589 std::vector<double2> dsm(los.size());
591 for (
auto i = 0;
i < los.size();
i++)
596 auto dsm_x = dsm[
i].x;
597 auto dsm_y = dsm[
i].y;
599 auto dsm_x_corr_coarse = dsm_x + (dsm_x / 2047)*(
double)regs.
FRMWpolyVars[0] +
600 std::pow(dsm_x / 2047, 2)*(double)regs.
FRMWpolyVars[1] +
605 auto dsm_x_corr = dsm_x_corr_coarse + (dsm_x_corr_coarse / 2047)*(double)regs.
FRMWundistAngHorz[0] +
610 auto dsm_y_corr = dsm_y_corr_coarse;
613 auto ang_x = dsm_x_corr * ((
double)regs.
FRMWxfov[
mode] * 0.25 / 2047);
614 auto ang_y = dsm_y_corr * ((double)regs.
FRMWyfov[
mode] * 0.25 / 2047);
618 fove_x_indicent_direction[
i] = laser_incident - mirror_normal_direction*(2 * (mirror_normal_direction*laser_incident));
624 for (
auto i = 0;
i < fove_x_indicent_direction.size();
i++)
626 fove_x_indicent_direction[
i].x /= sqrt(fove_x_indicent_direction[
i].get_norm());
627 fove_x_indicent_direction[
i].y /= sqrt(fove_x_indicent_direction[
i].get_norm());
628 fove_x_indicent_direction[
i].z /= sqrt(fove_x_indicent_direction[
i].get_norm());
631 auto outbound_direction = fove_x_indicent_direction;
634 std::fill(outbound_direction.begin(), outbound_direction.end(),
double3{ 0,0,0 });
635 for (
auto i = 0;
i < fove_x_indicent_direction.size();
i++)
637 auto ang_pre_exp =
rad_to_deg(std::acos(fove_x_indicent_direction[
i].z));
638 auto ang_post_exp = ang_pre_exp + ang_pre_exp * (double)regs.
FRMWfovexNominal[0] +
643 outbound_direction[
i].z = std::cos(
deg_to_rad(ang_post_exp));
644 auto xy_norm = fove_x_indicent_direction[
i].x*fove_x_indicent_direction[
i].x +
645 fove_x_indicent_direction[
i].y*fove_x_indicent_direction[
i].y;
647 auto xy_factor = std::sqrt((1 - outbound_direction[
i].z*outbound_direction[
i].z) / xy_norm);
648 outbound_direction[
i].x = fove_x_indicent_direction[
i].x*xy_factor;
649 outbound_direction[
i].y = fove_x_indicent_direction[
i].y*xy_factor;
653 for (
auto i = 0;
i < outbound_direction.size();
i++)
655 outbound_direction[
i].x /= outbound_direction[
i].z;
656 outbound_direction[
i].y /= outbound_direction[
i].z;
657 outbound_direction[
i].z /= outbound_direction[
i].z;
659 return outbound_direction;
664 const std::vector<uint8_t>& relevant_pixels_image,
668 std::vector<double3>
res;
670 double k_arr[9] = { k.
fx, 0, 0,
674 double k_arr_inv[9] = { 0 };
676 inv(k_arr, k_arr_inv);
678 double k_t[9] = { 0 };
686 if (relevant_pixels_image[
i*k.
width +
j])
689 double3 pix = { (double)
j, (
double)
i, (double)1 };
691 ver.
x = pix.
x*k_t[0] + pix.
y*k_t[1] + pix.
z*k_t[2];
692 ver.
y = pix.
x*k_t[3] + pix.
y*k_t[4] + pix.
z*k_t[5];
693 ver.
z = pix.
x*k_t[6] + pix.
y*k_t[7] + pix.
z*k_t[8];
705 algo_calibration_registers
const &dsm_regs,
706 std::vector< double3 >
const &
vertices,
710 const size_t angle = 45;
713 auto fovex_indicent_direction = directions;
716 std::fill(fovex_indicent_direction.begin(), fovex_indicent_direction.end(),
double3{ 0,0,0 });
717 std::vector<double> ang_post_exp(fovex_indicent_direction.size(), 0);
718 for (
auto i = 0;
i < ang_post_exp.size();
i++)
720 ang_post_exp[
i] = std::acos(directions[
i].z)* (double)180. / (
double)M_PI;
723 std::vector<double> ang_grid(angle, 0);
724 std::vector<double> ang_out_on_grid(angle, 0);
734 ang_out_on_grid[
i] = (
double)
i + fovex_nominal;
736 std::vector<double> ang_pre_exp =
interp1(ang_out_on_grid, ang_grid, ang_post_exp);
738 for (
auto i = 0;
i < fovex_indicent_direction.size();
i++)
740 fovex_indicent_direction[
i].z = std::cos(ang_pre_exp[
i] * M_PI / (
double)180.);
741 auto xy_norm = directions[
i].x*directions[
i].x + directions[
i].y*directions[
i].y;
742 auto xy_factor = sqrt(((
double)1 - (fovex_indicent_direction[
i].z* fovex_indicent_direction[
i].z)) / xy_norm);
743 fovex_indicent_direction[
i].x = directions[
i].x*xy_factor;
744 fovex_indicent_direction[
i].y = directions[
i].y*xy_factor;
750 std::vector<double3> mirror_normal_direction(fovex_indicent_direction.size());
751 std::vector<double> dsm_x_corr(fovex_indicent_direction.size());
752 std::vector<double> dsm_y_corr(fovex_indicent_direction.size());
753 std::vector<double> ang_x(fovex_indicent_direction.size());
754 std::vector<double> ang_y(fovex_indicent_direction.size());
756 for (
auto i = 0;
i < fovex_indicent_direction.size();
i++)
758 mirror_normal_direction[
i].x = fovex_indicent_direction[
i].x - laser_incident[0];
759 mirror_normal_direction[
i].y = fovex_indicent_direction[
i].y - laser_incident[1];
760 mirror_normal_direction[
i].z = fovex_indicent_direction[
i].z - laser_incident[2];
762 auto norm = sqrt(mirror_normal_direction[
i].
x*mirror_normal_direction[
i].
x +
763 mirror_normal_direction[
i].
y* mirror_normal_direction[
i].
y +
764 mirror_normal_direction[
i].z* mirror_normal_direction[
i].z);
766 mirror_normal_direction[
i].x /= norm;
767 mirror_normal_direction[
i].y /= norm;
768 mirror_normal_direction[
i].z /= norm;
770 ang_x[
i] = std::atan(mirror_normal_direction[
i].
x / mirror_normal_direction[
i].z)* (double)180. / (
double)M_PI;
771 ang_y[
i] = std::asin(mirror_normal_direction[
i].
y)* (double)180. / (
double)M_PI;
775 dsm_x_corr[
i] = ang_x[
i] / (double)(regs.
FRMWxfov[mirror_mode - 1] * (
double)0.25 / (double)2047);
776 dsm_y_corr[
i] = ang_y[
i] / (double)(regs.
FRMWyfov[mirror_mode - 1] * (
double)0.25 / (double)2047);
779 std::vector<double> dsm_grid(421);
782 for (
auto i = -2100;
i <= 2100;
i += 10)
787 std::vector<double> dsm_x_coarse_on_grid(dsm_grid.size());
788 std::vector<double> dsm_x_corr_on_grid(dsm_grid.size());
789 for (
auto i = 0;
i < dsm_grid.size();
i ++)
791 double rot[3] = { std::pow((dsm_grid[
i] / (
double)2047), 1), std::pow((dsm_grid[
i] / 2047), 2), std::pow((dsm_grid[
i] / 2047), 3) };
793 auto val = dsm_x_coarse_on_grid[
i] / (
double)2047;
794 double vals2[4] = { std::pow(
val , 1),std::pow(
val , 2), std::pow(
val , 3) , std::pow(
val , 4) };
801 auto dsm_x =
interp1(dsm_x_corr_on_grid, dsm_grid, dsm_x_corr);
802 std::vector<double> dsm_y(dsm_x.size());
804 for (
auto i = 0;
i < dsm_y.size();
i++)
809 std::vector<double2>
res(dsm_x.size());
824 for (
auto i = 0;
i <
res.size();
i++)
834 double2 angle_deg = { angle_rad.
x * (double)M_PI / (
double)180., (angle_rad.
y)* (
double)M_PI / (double)180. };
837 std::sin(angle_deg.
y),
838 std::cos(angle_deg.
y)*std::cos(angle_deg.
x) };
845 std::vector< double3 >
res( vec.size() );
847 for(
auto i = 0;
i < vec.size();
i++ )
849 auto norm = sqrt( vec[
i].
x * vec[
i].
x + vec[
i].
y * vec[
i].
y + vec[
i].z * vec[
i].z );
850 res[
i] = { vec[
i].x / norm, vec[
i].y / norm, vec[
i].z / norm };
std::vector< uint8_t > relevant_pixels_image
double2 run_scaling_optimization_step(algo::depth_to_rgb_calibration::algo_calibration_info const ®s, algo_calibration_registers const &dsm_regs, double scaling_grid_x[SIZE_OF_GRID_X], double scaling_grid_y[SIZE_OF_GRID_X], double2 focal_scaling, data_collect *data=nullptr)
pre_process_data pre_processing(const algo_calibration_info ®s, const rs2_dsm_params_double &ac_data, const algo_calibration_registers &algo_calibration_registers, const rs2_intrinsics_double &k_raw, const std::vector< uint8_t > &relevant_pixels_image, data_collect *data=nullptr)
algo::depth_to_rgb_calibration::algo_calibration_info _regs
double deg_to_rad(double deg)
std::vector< double2 > los_orig
void inv(const double x[9], double y[9])
void direct_inv_2x2(const double A[4], const double B[2], double C[2])
static const int SIZE_OF_GRID_X
los_shift_scaling last_los_error
std::vector< double > sg_mat_tag_x_err_l2
rs2_dsm_params_double convert_los_error_to_ac_data(const rs2_dsm_params_double &ac_data, const algo_calibration_registers &dsm_regs, double2 los_shift, double2 los_scaling)
std::vector< double > ang_x
algo::depth_to_rgb_calibration::algo_calibration_registers _dsm_regs
std::vector< double3x3 > optimize_k_under_los_error(algo::depth_to_rgb_calibration::algo_calibration_info const ®s, algo_calibration_registers const &dsm_regs, double scaling_grid_x[25], double scaling_grid_y[25])
std::vector< double > errL2
std::vector< double3 > fovex_indicent_direction
std::vector< double3 > vertices_orig
std::vector< double2 > los_orig
uint8_t FRMWfovexExistenceFlag
GLdouble GLdouble GLdouble w
std::vector< uint8_t > relevant_pixels_image_rot
GLfloat GLfloat GLfloat GLfloat h
std::vector< double > interp1(const std::vector< double > &ind, const std::vector< double > &vals, const std::vector< double > &intrp)
double3 laser_incident_direction(double2 angle_rad)
std::vector< uint8_t > relevant_pixels_image_rot
void transpose(const double x[9], double y[9])
float FRMWundistAngHorz[4]
rs2_intrinsics_double rotate_k_mat(const rs2_intrinsics_double &k_mat)
const pre_process_data & get_pre_process_data() const
algo_calibration_registers dsm_regs_cand
rs2_dsm_params_double convert_new_k_to_DSM(const rs2_intrinsics_double &old_k, const rs2_intrinsics_double &new_k, const z_frame_data &z, std::vector< double3 > &new_vertices, rs2_dsm_params_double const &previous_dsm_params, algo_calibration_registers &new_dsm_regs, data_collect *data=nullptr)
std::vector< double3 > mirror_normal_direction
std::vector< double2 > dsm
std::vector< std::vector< double > > sg_mat
rs2_dsm_correction_model model
std::vector< double > dsm_x_corr
void rotate_180(const uint8_t *A, uint8_t *B, uint32_t w, uint32_t h)
k2dsm_data_params k2dsm_data_p
float FRMWfovexNominal[4]
algo_calibration_registers apply_ac_res_on_dsm_model(const rs2_dsm_params_double &ac_data, const algo_calibration_registers ®s, const ac_to_dsm_dir &type)
double2 convert_k_to_los_error(algo::depth_to_rgb_calibration::algo_calibration_info const ®s, algo_calibration_registers const &dsm_regs, rs2_intrinsics_double const &k_raw, data_collect *data=nullptr)
convert_norm_vertices_to_los_data second_norm_vertices_to_los_data
#define AC_LOG(TYPE, MSG)
std::vector< double > sg_mat_tag_x_sg_mat
rs2_intrinsics_double orig_k
double rad_to_deg(double rad)
GLdouble GLdouble GLint GLint GLdouble v1
std::vector< double > dsm_y_corr
k_to_DSM(const rs2_dsm_params_double &orig_dsm_params, algo_calibration_info const &cal_info, algo_calibration_registers const &cal_regs, const double &max_scaling_step)
static const struct @18 vertices[3]
convert_norm_vertices_to_los_data first_norm_vertices_to_los_data
algo_calibration_registers dsm_regs_orig
std::vector< double > quad_coef
pre_process_data _pre_process_data
std::ostream & operator<<(std::ostream &, rs2_dsm_params_double const &)
los_shift_scaling convert_ac_data_to_los_error(const algo_calibration_registers &algo_calibration_registers, const rs2_dsm_params_double &ac_data)
static const int SIZE_OF_GRID_Y
std::vector< double > dsm_y
std::vector< double > dsm_x
std::vector< double > ang_y
std::vector< double2 > convert_norm_vertices_to_los(const algo_calibration_info ®s, const algo_calibration_registers &algo_calibration_registers, std::vector< double3 > const &vertices, convert_norm_vertices_to_los_data *data=nullptr)
std::vector< double3 > transform_to_direction(std::vector< double3 > const &)
std::vector< double3 > calc_relevant_vertices(const std::vector< uint8_t > &relevant_pixels_image, const rs2_intrinsics_double &k)
void direct_inv_6x6(const double A[36], const double B[6], double C[6])
void ndgrid_my(const double vec1[5], const double vec2[5], double yScalingGrid[25], double xScalingGrid[25])
std::vector< double3 > convert_los_to_norm_vertices(algo::depth_to_rgb_calibration::algo_calibration_info const ®s, algo_calibration_registers const &dsm_regs, std::vector< double2 > los, data_collect *data=nullptr)
std::string to_string(T value)